diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-07-02 15:36:20 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-07-02 15:36:20 +1000 |
commit | 1d880992fd8c8457a2d990ac6622cfd58fb1b261 (patch) | |
tree | c4c843b12e96b5612c315db5a23c5da1a900618c /libc/stdio | |
download | talos-skiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.tar.gz talos-skiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.zip |
Initial commit of Open Source release
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'libc/stdio')
-rw-r--r-- | libc/stdio/Makefile.inc | 21 | ||||
-rw-r--r-- | libc/stdio/fileno.c | 19 | ||||
-rw-r--r-- | libc/stdio/fprintf.c | 26 | ||||
-rw-r--r-- | libc/stdio/fputc.c | 24 | ||||
-rw-r--r-- | libc/stdio/fputs.c | 23 | ||||
-rw-r--r-- | libc/stdio/fscanf.c | 26 | ||||
-rw-r--r-- | libc/stdio/printf.c | 27 | ||||
-rw-r--r-- | libc/stdio/putchar.c | 21 | ||||
-rw-r--r-- | libc/stdio/puts.c | 27 | ||||
-rw-r--r-- | libc/stdio/scanf.c | 26 | ||||
-rw-r--r-- | libc/stdio/setvbuf.c | 28 | ||||
-rw-r--r-- | libc/stdio/snprintf.c | 30 | ||||
-rw-r--r-- | libc/stdio/sprintf.c | 30 | ||||
-rw-r--r-- | libc/stdio/stdchnls.c | 23 | ||||
-rw-r--r-- | libc/stdio/vfprintf.c | 27 | ||||
-rw-r--r-- | libc/stdio/vfscanf.c | 269 | ||||
-rw-r--r-- | libc/stdio/vsnprintf.c | 246 | ||||
-rw-r--r-- | libc/stdio/vsprintf.c | 19 | ||||
-rw-r--r-- | libc/stdio/vsscanf.c | 131 |
19 files changed, 1043 insertions, 0 deletions
diff --git a/libc/stdio/Makefile.inc b/libc/stdio/Makefile.inc new file mode 100644 index 00000000..62276f14 --- /dev/null +++ b/libc/stdio/Makefile.inc @@ -0,0 +1,21 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2008 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# * IBM Corporation - initial implementation +# ****************************************************************************/ + + +SUBDIRS += $(LIBCDIR)/stdio + +STDIO_OBJS = fscanf.o sprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \ + printf.o setvbuf.o fputc.o puts.o fputs.o putchar.o scanf.o \ + stdchnls.o vfscanf.o vsscanf.o fileno.o snprintf.o + +STDIO = $(LIBCDIR)/stdio/built-in.o +$(STDIO): $(STDIO_OBJS:%=$(LIBCDIR)/stdio/%) diff --git a/libc/stdio/fileno.c b/libc/stdio/fileno.c new file mode 100644 index 00000000..6e239511 --- /dev/null +++ b/libc/stdio/fileno.c @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdio.h> + +int +fileno(FILE *stream) +{ + return stream->fd; +} diff --git a/libc/stdio/fprintf.c b/libc/stdio/fprintf.c new file mode 100644 index 00000000..866df393 --- /dev/null +++ b/libc/stdio/fprintf.c @@ -0,0 +1,26 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "stdio.h" + + +int fprintf(FILE *stream, const char* fmt, ...) +{ + int count; + va_list ap; + + va_start(ap, fmt); + count = vfprintf(stream, fmt, ap); + va_end(ap); + + return count; +} diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c new file mode 100644 index 00000000..6e9e7c9c --- /dev/null +++ b/libc/stdio/fputc.c @@ -0,0 +1,24 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "stdio.h" +#include "unistd.h" + +int fputc(int ch, FILE *stream) +{ + unsigned char outchar = ch; + + if (write(stream->fd, &outchar, 1) == 1) + return outchar; + else + return EOF; +} diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c new file mode 100644 index 00000000..c22329c9 --- /dev/null +++ b/libc/stdio/fputs.c @@ -0,0 +1,23 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stdio.h" +#include "string.h" +#include "unistd.h" + + +int fputs(const char *str, FILE *stream) +{ + return write(stream->fd, str, strlen(str)); +} + diff --git a/libc/stdio/fscanf.c b/libc/stdio/fscanf.c new file mode 100644 index 00000000..321b1630 --- /dev/null +++ b/libc/stdio/fscanf.c @@ -0,0 +1,26 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdio.h> + +int +fscanf(FILE *stream, const char *fmt, ...) +{ + int count; + va_list ap; + + va_start(ap, fmt); + count = vfscanf(stream, fmt, ap); + va_end(ap); + + return count; +} diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c new file mode 100644 index 00000000..01f4592d --- /dev/null +++ b/libc/stdio/printf.c @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "stdio.h" + + +int printf(const char* fmt, ...) +{ + int count; + va_list ap; + + va_start(ap, fmt); + count = vfprintf(stdout, fmt, ap); + va_end(ap); + + return count; +} + diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c new file mode 100644 index 00000000..5c750d90 --- /dev/null +++ b/libc/stdio/putchar.c @@ -0,0 +1,21 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stdio.h" + + +int +putchar(int ch) +{ + return putc(ch, stdout); +} diff --git a/libc/stdio/puts.c b/libc/stdio/puts.c new file mode 100644 index 00000000..85d9d310 --- /dev/null +++ b/libc/stdio/puts.c @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stdio.h" +#include "string.h" +#include "unistd.h" + + +int puts(const char *str) +{ + int ret; + + ret = write(stdout->fd, str, strlen(str)); + write(stdout->fd, "\n", 1); + + return ret + 1; +} diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c new file mode 100644 index 00000000..96b63998 --- /dev/null +++ b/libc/stdio/scanf.c @@ -0,0 +1,26 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdio.h> + +int +scanf(const char *fmt, ...) +{ + int count; + va_list ap; + + va_start(ap, fmt); + count = vfscanf(stdin, fmt, ap); + va_end(ap); + + return count; +} diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c new file mode 100644 index 00000000..9b62dd8f --- /dev/null +++ b/libc/stdio/setvbuf.c @@ -0,0 +1,28 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdio.h> + +int setvbuf(FILE *stream, char *buf, int mode , size_t size) +{ + if (mode != _IONBF && mode != _IOLBF && mode != _IOFBF) + return -1; + stream->buf = buf; + stream->mode = mode; + stream->bufsiz = size; + return 0; +} + +void setbuf(FILE *stream, char *buf) +{ + setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ); +} diff --git a/libc/stdio/snprintf.c b/libc/stdio/snprintf.c new file mode 100644 index 00000000..cc1cc0ff --- /dev/null +++ b/libc/stdio/snprintf.c @@ -0,0 +1,30 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdio.h> + + +int snprintf(char *buff, size_t size, const char *format, ...) +{ + va_list ar; + int count; + + if ((buff==NULL) || (format==NULL)) + return(-1); + + va_start(ar, format); + count = vsnprintf(buff, size, format, ar); + va_end(ar); + + return(count); +} + diff --git a/libc/stdio/sprintf.c b/libc/stdio/sprintf.c new file mode 100644 index 00000000..9c4540e2 --- /dev/null +++ b/libc/stdio/sprintf.c @@ -0,0 +1,30 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdio.h> + + +int sprintf(char *buff, const char *format, ...) +{ + va_list ar; + int count; + + if ((buff==NULL) || (format==NULL)) + return(-1); + + va_start(ar, format); + count = vsprintf(buff, format, ar); + va_end(ar); + + return(count); +} + diff --git a/libc/stdio/stdchnls.c b/libc/stdio/stdchnls.c new file mode 100644 index 00000000..41ed958b --- /dev/null +++ b/libc/stdio/stdchnls.c @@ -0,0 +1,23 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stdio.h" + +static char stdin_buffer[BUFSIZ], stdout_buffer[BUFSIZ]; + +FILE stdin_data = { .fd = 0, .mode = _IOLBF, .pos = 0, + .buf = stdin_buffer, .bufsiz = BUFSIZ }; +FILE stdout_data = { .fd = 1, .mode = _IOLBF, .pos = 0, + .buf = stdout_buffer, .bufsiz = BUFSIZ }; +FILE stderr_data = { .fd = 2, .mode = _IONBF, .pos = 0, + .buf = NULL, .bufsiz = 0 }; diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c new file mode 100644 index 00000000..765feeac --- /dev/null +++ b/libc/stdio/vfprintf.c @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "stdio.h" +#include "unistd.h" + + +int vfprintf(FILE *stream, const char *fmt, va_list ap) +{ + int count; + char buffer[320]; + + count = vsnprintf(buffer, sizeof(buffer), fmt, ap); + write(stream->fd, buffer, count); + + return count; +} + diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.c new file mode 100644 index 00000000..85ca8be5 --- /dev/null +++ b/libc/stdio/vfscanf.c @@ -0,0 +1,269 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "string.h" +#include "ctype.h" +#include "stdlib.h" +#include "stdio.h" +#include "unistd.h" + + +static int +_getc(FILE * stream) +{ + int count; + char c; + + if (stream->mode == _IONBF || stream->buf == NULL) { + if (read(stream->fd, &c, 1) == 1) + return (int) c; + else + return EOF; + } + + if (stream->pos == 0 || stream->pos >= BUFSIZ || + stream->buf[stream->pos] == '\0') { + count = read(stream->fd, stream->buf, BUFSIZ); + if (count < 0) + count = 0; + if (count < BUFSIZ) + stream->buf[count] = '\0'; + stream->pos = 0; + } + + return stream->buf[stream->pos++]; +} + +static void +_ungetc(int ch, FILE * stream) +{ + if (stream->mode != _IONBF && stream->pos > 0) { + if (stream->pos < BUFSIZ) + stream->buf[stream->pos] = ch; + stream->pos--; + } +} + +static int +_is_voidage(int ch) +{ + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\0') + return 1; + else + return 0; +} + + +static int +_scanf(FILE * stream, const char *fmt, va_list * ap) +{ + int i = 0; + int length = 0; + + fmt++; + + while (*fmt != '\0') { + + char tbuf[256]; + char ch; + + switch (*fmt) { + case 'd': + case 'i': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) && isdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length + && isdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } + /* We tried to understand what this is good for... + * but we did not. We know for sure that it does not + * work on SLOF if this is active. */ + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + if (strlen(tbuf) == 0) + return 0; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10); + break; + case 'X': + case 'x': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) && isxdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length + && isxdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + if (strlen(tbuf) == 0) + return 0; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16); + break; + case 'O': + case 'o': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) + && !(ch < '0' || ch > '7')) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length + && !(ch < '0' || ch > '7')) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + if (strlen(tbuf) == 0) + return 0; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8); + break; + case 'c': + ch = _getc(stream); + while (_is_voidage(ch)) + ch = _getc(stream); + + *(va_arg(*ap, char *)) = ch; + + ch = _getc(stream); + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + break; + case 's': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + strcpy(va_arg(*ap, char *), tbuf); + break; + default: + if (*fmt >= '0' && *fmt <= '9') + length += *fmt - '0'; + break; + } + fmt++; + } + + return 1; +} + + + +int +vfscanf(FILE * stream, const char *fmt, va_list ap) +{ + int args = 0; + + while (*fmt != '\0') { + + if (*fmt == '%') { + + char formstr[20]; + int i = 0; + + do { + formstr[i] = *fmt; + fmt++; + i++; + } while (! + (*fmt == 'd' || *fmt == 'i' || *fmt == 'x' + || *fmt == 'X' || *fmt == 'p' || *fmt == 'c' + || *fmt == 's' || *fmt == '%' || *fmt == 'O' + || *fmt == 'o')); + formstr[i++] = *fmt; + formstr[i] = '\0'; + if (*fmt != '%') { + if (_scanf(stream, formstr, &ap) <= 0) + return args; + else + args++; + } + + } + + fmt++; + + } + + return args; +} + +int +getc(FILE * stream) +{ + return _getc(stream); +} + +int +getchar(void) +{ + return _getc(stdin); +} diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c new file mode 100644 index 00000000..d1cd4e37 --- /dev/null +++ b/libc/stdio/vsnprintf.c @@ -0,0 +1,246 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdbool.h> +#include <compiler.h> +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "ctype.h" + +static const unsigned long long convert[] = { + 0x0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFFFFULL, 0xFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL +}; + + + +static int +print_itoa(char **buffer, unsigned long value, unsigned short base, bool upper) +{ + const char zeichen[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + char c; + + if(base <= 2 || base > 16) + return 0; + + if (value < base) { + c = zeichen[value]; + if (upper) + c = toupper(c); + **buffer = c; + *buffer += 1; + } else { + print_itoa(buffer, value / base, base, upper); + c = zeichen[value % base]; + if (upper) + c = toupper(c); + **buffer = c; + *buffer += 1; + } + + return 1; +} + + +static unsigned int __attrconst +print_intlen(unsigned long value, unsigned short int base) +{ + int i = 0; + + while(value > 0) { + value /= base; + i++; + } + if(i == 0) i = 1; + return i; +} + + +static int +print_fill(char **buffer, char *sizec, unsigned long size, unsigned short int base, char c, int optlen) +{ + int i, sizei, len; + + sizei = strtoul(sizec, NULL, 10); + len = print_intlen(size, base) + optlen; + if(sizei > len) { + for(i = 0; i < (sizei - len); i++) { + **buffer = c; + *buffer += 1; + } + } + + return 0; +} + + +static int +print_format(char **buffer, const char *format, void *var) +{ + unsigned long start; + unsigned int i = 0, sizei = 0, len = 0, length_mod = sizeof(int); + unsigned long value = 0; + unsigned long signBit; + char *form, sizec[32]; + char sign = ' '; + bool upper = false; + + form = (char *) format; + start = (unsigned long) *buffer; + + form++; + if(*form == '0' || *form == '.') { + sign = '0'; + form++; + } + + while(*form != '\0') { + switch(*form) { + case 'u': + case 'd': + case 'i': + sizec[i] = '\0'; + value = (unsigned long) var; + signBit = 0x1ULL << (length_mod * 8 - 1); + if ((*form != 'u') && (signBit & value)) { + **buffer = '-'; + *buffer += 1; + value = (-(unsigned long)value) & convert[length_mod]; + } + print_fill(buffer, sizec, value, 10, sign, 0); + print_itoa(buffer, value, 10, upper); + break; + case 'X': + upper = true; + case 'x': + sizec[i] = '\0'; + value = (unsigned long) var & convert[length_mod]; + print_fill(buffer, sizec, value, 16, sign, 0); + print_itoa(buffer, value, 16, upper); + break; + case 'O': + case 'o': + sizec[i] = '\0'; + value = (long int) var & convert[length_mod]; + print_fill(buffer, sizec, value, 8, sign, 0); + print_itoa(buffer, value, 8, upper); + break; + case 'p': + sizec[i] = '\0'; + print_fill(buffer, sizec, (unsigned long) var, 16, ' ', 2); + **buffer = '0'; + *buffer += 1; + **buffer = 'x'; + *buffer += 1; + print_itoa(buffer,(unsigned long) var, 16, upper); + break; + case 'c': + sizec[i] = '\0'; + print_fill(buffer, sizec, 1, 10, ' ', 0); + **buffer = (unsigned long) var; + *buffer += 1; + break; + case 's': + sizec[i] = '\0'; + sizei = strtoul(sizec, NULL, 10); + len = strlen((char *) var); + if(sizei > len) { + for(i = 0; i < (sizei - len); i++) { + **buffer = ' '; + *buffer += 1; + } + } + for(i = 0; i < strlen((char *) var); i++) { + **buffer = ((char *) var)[i]; + *buffer += 1; + } + break; + case 'l': + form++; + if(*form == 'l') { + length_mod = sizeof(long long int); + } else { + form--; + length_mod = sizeof(long int); + } + break; + case 'h': + form++; + if(*form == 'h') { + length_mod = sizeof(signed char); + } else { + form--; + length_mod = sizeof(short int); + } + break; + case 'z': + length_mod = sizeof(size_t); + break; + default: + if(*form >= '0' && *form <= '9') + sizec[i++] = *form; + } + form++; + } + + + return (long int) (*buffer - start); +} + + +/* + * The vsnprintf function prints a formated strings into a buffer. + * BUG: buffer size checking does not fully work yet + */ +int +vsnprintf(char *buffer, size_t bufsize, const char *format, va_list arg) +{ + char *ptr, *bstart; + + bstart = buffer; + ptr = (char *) format; + + while(*ptr != '\0' && (buffer - bstart) < bufsize) + { + if(*ptr == '%') { + char formstr[20]; + int i=0; + + do { + formstr[i] = *ptr; + ptr++; + i++; + } while(!(*ptr == 'd' || *ptr == 'i' || *ptr == 'u' || *ptr == 'x' || *ptr == 'X' + || *ptr == 'p' || *ptr == 'c' || *ptr == 's' || *ptr == '%' + || *ptr == 'O' || *ptr == 'o' )); + formstr[i++] = *ptr; + formstr[i] = '\0'; + if(*ptr == '%') { + *buffer++ = '%'; + } else { + print_format(&buffer, formstr, va_arg(arg, void *)); + } + ptr++; + } else { + + *buffer = *ptr; + + buffer++; + ptr++; + } + } + + *buffer = '\0'; + + return (buffer - bstart); +} diff --git a/libc/stdio/vsprintf.c b/libc/stdio/vsprintf.c new file mode 100644 index 00000000..0dfd737b --- /dev/null +++ b/libc/stdio/vsprintf.c @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "stdio.h" + +int +vsprintf(char *buffer, const char *format, va_list arg) +{ + return vsnprintf(buffer, 0x7fffffff, format, arg); +} diff --git a/libc/stdio/vsscanf.c b/libc/stdio/vsscanf.c new file mode 100644 index 00000000..b9603e98 --- /dev/null +++ b/libc/stdio/vsscanf.c @@ -0,0 +1,131 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + + +static void +_scanf(const char **buffer, const char *fmt, va_list *ap) +{ + int i; + int length = 0; + + fmt++; + + while(*fmt != '\0') { + + char tbuf[256]; + + switch(*fmt) { + case 'd': + case 'i': + if(length == 0) length = 256; + + for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) { + tbuf[i] = **buffer; + *buffer += 1; + } + tbuf[i] = '\0'; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10); + break; + case 'X': + case 'x': + if(length == 0) length = 256; + + for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) { + tbuf[i] = **buffer; + *buffer += 1; + } + tbuf[i] = '\0'; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16); + break; + case 'O': + case 'o': + if(length == 0) length = 256; + + for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) { + tbuf[i] = **buffer; + *buffer += 1; + } + tbuf[i] = '\0'; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8); + break; + case 'c': + *(va_arg(*ap, char *)) = **buffer; + *buffer += 1; + if(length > 1) + for(i = 1; i < length; i++) + *buffer += 1; + break; + case 's': + if(length == 0) length = 256; + + for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) { + tbuf[i] = **buffer; + *buffer += 1; + } + + tbuf[i] = '\0'; + + strcpy(va_arg(*ap, char *), tbuf); + break; + default: + if(*fmt >= '0' && *fmt <= '9') + length += *fmt - '0'; + break; + } + fmt++; + } + +} + + +int +vsscanf(const char *buffer, const char *fmt, va_list ap) +{ + + while(*fmt != '\0') { + + if(*fmt == '%') { + + char formstr[20]; + int i=0; + + do { + formstr[i] = *fmt; + fmt++; + i++; + } while(!(*fmt == 'd' || *fmt == 'i' || *fmt == 'x' || *fmt == 'X' + || *fmt == 'p' || *fmt == 'c' || *fmt == 's' || *fmt == '%' + || *fmt == 'O' || *fmt == 'o' )); + formstr[i++] = *fmt; + formstr[i] = '\0'; + if(*fmt != '%') { + while(*buffer == ' ' || *buffer == '\t' || *buffer == '\n') + buffer++; + _scanf(&buffer, formstr, &ap); + } + + } + + fmt++; + + } + + return 0; +} + |