Add fprintf and vfprintf (and implemented printf/vprintf using it)
This commit is contained in:
parent
7697e5d947
commit
fba2d299c4
|
@ -7,11 +7,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
int putchar(int c);
|
||||
int puts(const char *s);
|
||||
int vprintf(const char *restrict format, va_list ap);
|
||||
int printf(const char *restrict format, ...);
|
||||
|
||||
FILE* fopen(const char *restrict pathname, const char *restrict mode);
|
||||
int fclose(FILE *stream);
|
||||
int fgetc(FILE *stream);
|
||||
|
@ -25,4 +20,11 @@ int fputs(const char *restrict s, FILE *restrict stream);
|
|||
|
||||
int rename(const char *old, const char *new);
|
||||
|
||||
int putchar(int c);
|
||||
int puts(const char *s);
|
||||
int vfprintf(FILE *restrict stream, const char *restrict format, va_list ap);
|
||||
int fprintf(FILE *restrict stream, const char *restrict format, ...);
|
||||
int vprintf(const char *restrict format, va_list ap);
|
||||
int printf(const char *restrict format, ...);
|
||||
|
||||
#endif
|
||||
|
|
176
src/stdio.c
176
src/stdio.c
|
@ -1,87 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int putchar(int c) {
|
||||
sys_write(stdout, &c, 1);
|
||||
return (unsigned char)c;
|
||||
}
|
||||
|
||||
int puts(const char *s) {
|
||||
int i = 0;
|
||||
while(s[i] != '\0') {
|
||||
putchar(s[i]);
|
||||
i++;
|
||||
}
|
||||
putchar('\n');
|
||||
return 1; // FIXME
|
||||
}
|
||||
|
||||
int vprintf(const char *restrict format, va_list ap) {
|
||||
char *s;
|
||||
int value;
|
||||
int size = 0;
|
||||
for (size_t i = 0; i < strlen(format); i++) {
|
||||
if (format[i] == '%') {
|
||||
i++;
|
||||
switch(format[i]) {
|
||||
case 'c':
|
||||
putchar((char) va_arg(ap, int));
|
||||
size++;
|
||||
break;
|
||||
case 's':
|
||||
s = va_arg(ap, char *);
|
||||
for (size_t j = 0; j < strlen(s); j++) {
|
||||
putchar(s[j]);
|
||||
size++;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
value = va_arg(ap, int);
|
||||
if (value == 0) {
|
||||
putchar('0');
|
||||
size++;
|
||||
} if (value < 0) {
|
||||
putchar('-');
|
||||
value *= (-1);
|
||||
size++;
|
||||
}
|
||||
|
||||
long long power = 1;
|
||||
|
||||
while (value > power)
|
||||
power *= 10;
|
||||
|
||||
if (power >= 10)
|
||||
power /= 10;
|
||||
|
||||
while (value != 0) {
|
||||
int digit = (int)(value / power);
|
||||
putchar('0' + digit);
|
||||
size++;
|
||||
if (digit != 0)
|
||||
value = value - digit * power;
|
||||
if (power != 1)
|
||||
power /= 10;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
putchar(format[i]);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int printf(const char *restrict format, ...) {
|
||||
int size;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
size = vprintf(format, ap);
|
||||
va_end(ap);
|
||||
return size;
|
||||
}
|
||||
|
||||
#define O_RDWR 2 // FIXME
|
||||
#define O_RDONLY 0
|
||||
#define O_CREAT 64
|
||||
|
@ -164,3 +83,98 @@ int fputs(const char *restrict s, FILE *restrict stream) {
|
|||
int rename(const char *old, const char *new) {
|
||||
return sys_rename(old, new);
|
||||
}
|
||||
|
||||
int putchar(int c) {
|
||||
sys_write(stdout->fd, &c, 1);
|
||||
return (unsigned char)c;
|
||||
}
|
||||
|
||||
int puts(const char *s) {
|
||||
int i = 0;
|
||||
while(s[i] != '\0') {
|
||||
putchar(s[i]);
|
||||
i++;
|
||||
}
|
||||
putchar('\n');
|
||||
return 1; // FIXME
|
||||
}
|
||||
|
||||
int vfprintf(FILE *restrict stream, const char *restrict format, va_list ap) {
|
||||
char *s;
|
||||
int value;
|
||||
int size = 0;
|
||||
for (size_t i = 0; i < strlen(format); i++) {
|
||||
if (format[i] == '%') {
|
||||
i++;
|
||||
switch(format[i]) {
|
||||
case 'c':
|
||||
fputc((char) va_arg(ap, int), stream);
|
||||
size++;
|
||||
break;
|
||||
case 's':
|
||||
s = va_arg(ap, char *);
|
||||
for (size_t j = 0; j < strlen(s); j++) {
|
||||
fputc(s[j], stream);
|
||||
size++;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
value = va_arg(ap, int);
|
||||
if (value == 0) {
|
||||
fputc('0', stream);
|
||||
size++;
|
||||
} if (value < 0) {
|
||||
fputc('-', stream);
|
||||
value *= (-1);
|
||||
size++;
|
||||
}
|
||||
|
||||
long long power = 1;
|
||||
|
||||
while (value > power)
|
||||
power *= 10;
|
||||
|
||||
if (power >= 10)
|
||||
power /= 10;
|
||||
|
||||
while (value != 0) {
|
||||
int digit = (int)(value / power);
|
||||
fputc('0' + digit, stream);
|
||||
size++;
|
||||
if (digit != 0)
|
||||
value = value - digit * power;
|
||||
if (power != 1)
|
||||
power /= 10;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fputc(format[i], stream);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int fprintf(FILE *restrict stream, const char *restrict format, ...) {
|
||||
int size;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
size = vfprintf(stream, format, ap);
|
||||
va_end(ap);
|
||||
return size;
|
||||
}
|
||||
|
||||
int vprintf(const char *restrict format, va_list ap) {
|
||||
return vfprintf(stdout, format, ap);
|
||||
}
|
||||
|
||||
int printf(const char *restrict format, ...) {
|
||||
int size;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
size = vprintf(format, ap);
|
||||
va_end(ap);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue