diff --git a/include/c/_fileio.h b/include/c/_fileio.h new file mode 100644 index 0000000..1a46528 --- /dev/null +++ b/include/c/_fileio.h @@ -0,0 +1,82 @@ +#ifndef _FILEIO_H +#define _FILEIO_H + +#include +#include + +// Nobody should have to interface with the internals of this structure +typedef struct _iobuf { // 24B + unsigned char* _ptr; // File buffer base + unsigned int _size; // Size of buffer + int _offset; // Offset into file + unsigned short _flag; // Open flags + int _file; // File descriptor + + char __reserved[6]; +} FILE; + +FILE* stdin; +FILE* stdout; +FILE* stderr; + +FILE* fopen(const char* filename, const char* mode) { + int oflag = O_RDWR | O_CREAT | O_BIN; // TODO! + + int fd = open(filename, oflag); + if (fd < 0) { + printf(""); // TODO: i'd prefer if i didn't need this + return NULL; + } + + // TODO: Somehow get the open file table + FILE* fp = malloc(sizeof(FILE)); + fp->_file = fd; + + return fp; +} + +int fclose(FILE* stream) { + int res = close(stream->_file); + return res; +} + +size_t fread(void* ptr, size_t size, size_t count, FILE* stream) { + unsigned int offset = 0; + size_t readEl = 0; + int fd = stream->_file; + + while (readEl != count) { + if (read(fd, (void*)(ptr + offset), size) != size) break; + offset += size; + readEl++; + } + + return readEl; +} + +size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { + unsigned int offset = 0; + size_t writtenEl = 0; + int fd = stream->_file; + + while (writtenEl != count) { + if (write(fd, (void*)(ptr + offset), size) != size) break; + offset += size; + writtenEl++; + } + + return writtenEl; +} + +int fseek(FILE* stream, long int origin, int offset) { + // TODO + return -1; +} + +long int ftell(FILE* stream) { + // TODO + return -1; +} + +#endif + diff --git a/include/c/_printf.h b/include/c/_printf.h new file mode 100644 index 0000000..e2d838b --- /dev/null +++ b/include/c/_printf.h @@ -0,0 +1,74 @@ +#ifndef _PRINTF_H +#define _PRINTF_H + +#include +#include + +// TODO: Support negative numbers +int printf(const char* fmt, ...) { + unsigned int* argPtr = (unsigned int*)&fmt + 1; // First arg after fmt + + // Printing buffer + static char* buffer; + static unsigned int len; + int max = 256; + + buffer = malloc(max); + len = 0; + + int state = 0; + for (int i = 0; fmt[i] != '\0'; i++) { + if (len > max) { + max *= 2; + // Reallocate larger buffer TODO: Use realloc(); + char* temp = malloc(max); + strcpy(temp, buffer); + free(buffer); + buffer = temp; + } + buffer[len] = '\0'; + + char c = fmt[i]; + if (state == 0) { + if (c == '%') state = '%'; + else buffer[len++] = c; + } else if (state == '%') { + switch (c) { + case 'd': // Decimal number + strcat(buffer, itoa(*argPtr++, 10)); + len += strlen(&buffer[len]); // Add the remaining length + break; + case 'x': // Hex number + strcat(buffer, itoa(*argPtr++, 16)); + len += strlen(&buffer[len]); + break; + case 's': // String + char* s = *(char**)argPtr++; + + while (*s != '\0') { + buffer[len++] = *s++; + } + break; + case 'c': // Char + buffer[len++] = *(char*)argPtr; + argPtr++; + break; + default: // This looks insane + buffer[len++] = '%'; + case '%': // Just print '%' + buffer[len++] = c; + break; + } + state = 0; + } + } + + buffer[len] = '\0'; + write(1, buffer, len); + free(buffer); + + return 0; +} + +#endif + diff --git a/include/c/stdio.h b/include/c/stdio.h index 1a864aa..fab3b37 100644 --- a/include/c/stdio.h +++ b/include/c/stdio.h @@ -4,87 +4,17 @@ #include #include #include -#include - -// Nobody should have to interface with the internals of this structure -typedef struct _iobuf { // 24B - unsigned char* _ptr; // File buffer base - unsigned int _size; // Size of buffer - int _offset; // Offset into file - unsigned short _flag; // Open flags - int _file; // File descriptor - - char __reserved[6]; -} FILE; - -FILE* stdin; -FILE* stdout; -FILE* stderr; /* Declarations */ +void putc(char); +char getc(); + int printf(const char*, ...); -/* --- file I/O --- */ -FILE* fopen(const char* filename, const char* mode) { - int oflag = O_RDWR | O_CREAT | O_BIN; // TODO! +/* STDIO Include */ +#include <_fileio.h> +#include <_printf.h> - int fd = open(filename, oflag); - if (fd < 0) { - printf(""); // TODO: i'd prefer if i didn't need this - return NULL; - } - - // TODO: Somehow get the open file table - FILE* fp = malloc(sizeof(FILE)); - fp->_file = fd; - - return fp; -} - -int fclose(FILE* stream) { - int res = close(stream->_file); - return res; -} - -size_t fread(void* ptr, size_t size, size_t count, FILE* stream) { - unsigned int offset = 0; - size_t readEl = 0; - int fd = stream->_file; - - while (readEl != count) { - if (read(fd, (void*)(ptr + offset), size) != size) break; - offset += size; - readEl++; - } - - return readEl; -} - -size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { - unsigned int offset = 0; - size_t writtenEl = 0; - int fd = stream->_file; - - while (writtenEl != count) { - if (write(fd, (void*)(ptr + offset), size) != size) break; - offset += size; - writtenEl++; - } - - return writtenEl; -} - -int fseek(FILE* stream, long int origin, int offset) { - // TODO - return -1; -} - -long int ftell(FILE* stream) { - // TODO - return -1; -} - -/* --- stdout --- */ void putc(char c) { // write(stdout, &c, 1); TODO: This doesn't work and we need to use a static variable static char _c; @@ -92,6 +22,13 @@ void putc(char c) { write(1, &_c, 1); } +char getc() { + char* c = (char*)0x2100; + *c= '\0'; + while (*c == '\0') { __asm__ volatile ("hlt"); } + return *c; +} + void print(const char* s) { write(1, s, strlen(s)); } @@ -100,80 +37,6 @@ void clear() { print("\x1b[J"); } -// TODO: Support negative numbers -int printf(const char* fmt, ...) { - unsigned int* argPtr = (unsigned int*)&fmt + 1; // First arg after fmt - - // Printing buffer - static char* buffer; - static unsigned int len; - int max = 256; - - buffer = malloc(max); - len = 0; - - int state = 0; - for (int i = 0; fmt[i] != '\0'; i++) { - if (len > max) { - max *= 2; - // Reallocate larger buffer TODO: Use realloc(); - char* temp = malloc(max); - strcpy(temp, buffer); - free(buffer); - buffer = temp; - } - buffer[len] = '\0'; - - char c = fmt[i]; - if (state == 0) { - if (c == '%') state = '%'; - else buffer[len++] = c; - } else if (state == '%') { - switch (c) { - case 'd': // Decimal number - strcat(buffer, itoa(*(unsigned int*)argPtr++, 10)); - len += strlen(&buffer[len]); // Add the remaining length - break; - case 'x': // Hex number - strcat(buffer, itoa(*(unsigned int*)argPtr++, 16)); - len += strlen(&buffer[len]); - break; - case 's': // String - char* s = *(char**)argPtr++; - - while (*s != '\0') { - buffer[len++] = *s++; - } - break; - case 'c': // Char - buffer[len++] = *(char*)argPtr; - argPtr++; - break; - default: // This looks insane - buffer[len++] = '%'; - case '%': // Just print '%' - buffer[len++] = c; - break; - } - state = 0; - } - } - - buffer[len] = '\0'; - write(1, buffer, len); - free(buffer); - - return 0; -} - -/* --- stdin --- */ -char getc() { - char* character = (char*)0x2100; - *character = '\0'; - while (*character == '\0') { __asm__ volatile ("hlt"); } - return *character; -} - // Reads until a newline // TODO: Use Read() Syscall void reads(char* buffer) {