olibc/src/stdio.c

151 lines
2.8 KiB
C
Raw Normal View History

2021-12-19 08:35:56 +00:00
#include <stdio.h>
#include <string.h>
2021-12-19 08:35:56 +00:00
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++;
}
2021-12-19 08:35:56 +00:00
}
return size;
}
2021-12-19 08:35:56 +00:00
int printf(const char *restrict format, ...) {
int size;
va_list ap;
va_start(ap, format);
size = vprintf(format, ap);
va_end(ap);
return size;
2021-12-19 08:35:56 +00:00
}
2021-12-28 10:03:23 +00:00
#define O_RDWR 2 // FIXME
#define O_RDONLY 0
#define O_CREAT 64
#define O_TRUNC 512
#define O_WRONLY 1
#define O_APPEND 1024
#define EINVAL 22 // FIXME
FILE* fopen(const char *restrict pathname, const char *restrict mode) { // FIXME
if (pathname == NULL)
return (FILE*)NULL;
int oflag;
switch(mode[0]) { // TODO: add b and x mode (check C11 specifications)
case 'r':
if (strlen(mode) > 1 && mode[1] == '+')
oflag = O_RDWR;
else
oflag = O_RDONLY;
break;
case 'w':
if (strlen(mode) > 1 && mode[1] == '+')
oflag = O_RDWR | O_CREAT | O_TRUNC;
else
oflag = O_WRONLY | O_CREAT | O_TRUNC;
break;
case 'a':
if (strlen(mode) > 1 && mode[1] == '+')
oflag = O_RDWR | O_CREAT | O_APPEND;
else
oflag = O_WRONLY | O_CREAT | O_APPEND;
break;
default:
return (FILE*)EINVAL;
}
int fd = sys_open(pathname, oflag);
if (fd == -1)
return NULL;
FILE *temp = malloc(sizeof(pathname) + sizeof(fd));
temp->filename = (char*)pathname;
temp->fd = fd;
return temp;
}
int fclose(FILE *stream) {
return sys_close(stream->fd);
}
2021-12-28 13:48:06 +00:00
int fgetc(FILE *stream) {
char buf = '\0';
sys_read(stream->fd, (void*)&buf, 1);
return (buf == '\0') ? (unsigned int)-1 : (unsigned int)buf;
}
int getchar(void) {
return fgetc(stdin);
}
2021-12-28 16:21:43 +00:00
char *fgets(char *restrict s, int n, FILE *restrict stream) {
s = malloc(n);
int i = 0;
char c = '\0';
while (i < n-1 && (c = fgetc(stream)) != -1 && (s[i++] = c) && c != '\n');
return (strlen(s) == 0) ? NULL : s;
}
2021-12-28 13:48:06 +00:00