Almost finished stdio.h

This commit is contained in:
2024-10-25 18:11:10 +02:00
parent 57bfddc65e
commit ad5bf2baab
6 changed files with 259 additions and 8 deletions
+7 -8
View File
@@ -17,12 +17,7 @@
#define SEEK_END 1
#define SEEK_SET 2
// Standard file pointers
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
/* The ultimate FILE struct */
/* The FILE struct */
typedef struct _iobuf { // 24B
unsigned char* _ptr; // File buffer base
unsigned int _size; // Size of buffer
@@ -33,6 +28,7 @@ typedef struct _iobuf { // 24B
char __reserved[6];
} FILE;
// Standard file pointers
extern FILE* stdin;
extern FILE* stdout;
extern FILE* stderr;
@@ -59,20 +55,23 @@ char* fgets(char* str, int n, FILE* stream);
int fputs(const char* str, FILE* stream);
int puts(const char* str);
/* Error handling */
/* TODO: Error handling
void perror(const char* s);
int feof(FILE* stream);
int ferror(FILE* stream);
void clearerr(FILE* stream);
*/
/* Formatted I/O */
int printf(const char* fmt, ...);
int vprintf(const char* fmt, va_list va);
int fprintf(FILE* stream, const char* fmt, ...);
int vfprintf(FILE* stream, const char* fmt, va_list va);
// INFO: (v)sprinf() Has been depricated and removed as it is unsafe (potencial buffer overflow). Please use (v)snprintf()
// NOTE: (v)sprinf() Has been depricated and removed as it is unsafe (potencial buffer overflow). Please use (v)snprintf()
int snprintf(char* str, size_t size, const char* fmt, ...);
int vsnprintf(char* str, size_t size, const char* fmt, va_list va);
int vpprintf(void (*outfn)(char c, void* arg), void* arg, const char* fmt, ...)
int vpprintf(void (*outfn)(char c, void* arg), void* arg, const char* fmt, va_list va)
int scanf(const char* fmt, ...);
int vscanf(const char* fmt, va_list va);
+29
View File
@@ -0,0 +1,29 @@
#include <stdio.h>
#include <syscall.h>
int getchar(void) { return getc(stdin); }
int putchar(int c) { return putc(stdout); }
int getc(FILE* stream) {
if (!stream) { return EOF; }
unsigned char ch;
ssize_t res = read(stream->_file, &ch, 1);
if (res <= 0) { return EOF; }
return (int)ch;
}
int putc(int c, FILE* stream) {
if (!stream) { return EOF; }
unsigned char ch = (unsigned char)c;
ssize_t res = write(stream->_file, &c, 1);
if (res <= 0) { return EOF; }
return (int)ch;
}
// TODO:
int ungetc(int c, FILE* stream) { return EOF; }
+73
View File
@@ -0,0 +1,73 @@
#include <stdio.h>
#include <syscall.h>
#include <stdlib.h>
#include <string.h>
FILE* fopen(const char* path, const char* mode) {
FILE* fp = (FILE*)malloc(sizeof(FILE));
if (!fp) { return NULL; }
int flags = 0;
if (strcmp(mode, "r") == 0) { flags = O_RDONLY; }
else if (strcmp(mode, "w") == 0) { flags = O_WRONLY | O_CREAT | O_TRUNC; }
else if (strcmp(mode, "a") == 0) { flags = O_WRONLY | O_CREAT | O_APPEND; }
else if (strcmp(mode, "r+") == 0) { flags = O_RDWR; }
else if (strcmp(mode, "w+") == 0) { flags = O_RDWR | O_CREAT | O_TRUNC; }
else if (strcmp(mode, "a+") == 0) { flags = O_RDWR | O_CREAT | O_APPEND; }
else { // Unsuppored mode
free(file);
return NULL;
}
int fd = open(path, flags);
if (fd == -1) {
free(FILE);
return NULL;
}
fp->_file = fd;
fp->_ptr = NULL;
fp->_size = 0;
fp->_offset = 0;
fp->_flag = flags;
return fp;
}
int fclose(FILE* stream) {
if (!stream) { return -1; }
int ret = close(stream->_file);
free(stream);
return ret;
}
size_t fread(void* ptr, size_t size, size_t count, FILE* stream) {
if (!stream || !ptr || size == 0 || count == 0) { return 0; }
size_t total = size * count;
ssize_t read = read(stream->_file, ptr, total);
if (read < 0) return 0;
stream->offset += read;
return read / size;
}
size_t fwrite(void* ptr, size_t size, size_t count, FILE* stream) {
if (!stream || !ptr || size == 0 || count == 0) { return 0; }
size_t total = size * count;
ssize_t written = write(stream->_file, ptr, total);
if (read < 0) return 0;
stream->offset += written;
return written / size;
}
// TODO
int fseek(FILE* stream, long offset, int whence);
long ftell(FILE* stream);
void rewind(FILE* stream);
int fflush(FILE* stream);
+32
View File
@@ -0,0 +1,32 @@
#include <stdio.h>
#include <stddef.h>
char* fgets(char* str, int n, FILE* stream) {
if (!str || !stream || n <= 1) { return NULL; }
char* dest = str;
int ch;
while (--n > 0 && (ch = getc(stream)) != EOF) {
*dest++ = ch;
if (ch == '\n') break; // Stop at newline
}
*dest = '\0'; // Null terminate
return (dest == str) ? NULL : str;
}
int fputs(const char* str, FILE* stream) {
if (!str || !stream) { return EOF; }
while (*str) {
if (putc(*str++, stream) == EOF) { return EOF; }
}
return 0;
}
inline char* gets(char* str, int n) { return fgets(str, n, stdin); }
inline int puts(const char* str) { return fputs(str, stdout); }
+108
View File
@@ -0,0 +1,108 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
/* Internal definitions */
typedef struct {
int buflen;
int offset;
char* buf;
} printfEnv_t;
/* Helpers */
static void _dynamicPutc(char c, printfEnv_t* env) {
if (!env->buf) { return; }
if (env->offset < env->buflen) {
env->buf[env->offset++] = c;
} else {
env->buflen *= 2;
env->buf = realloc(env->buf, env->buflen);
// If there's not enough memory, we chatch the NULL pointer in the fwrite() call
if (!env->buf) { return; }
env->buf[env->offset++] = c;
}
}
static void _staticPutc(char c, printfEnv_t* env) {
if (!env->buf) { return; }
if (env->offset < env->buflen) {
env->buf[env->offset] = c;
env->offset++;
}
}
/* Impementation */
int vpprintf(void (*outfn)(char c, void* arg), void* arg, const char* fmt, va_list va) { /* TODO */ }
int vsnprintf(char* str, size_t size, const char* fmt, va_list va) {
printfEnv_t env;
env.buflen = size;
env.offset = 0;
env.buf = str;
// Format the string
int ret = vpprintf(_staticPutc, &env, fmt, va);
return ret;
}
int vfprintf(FILE* stream, const char* fmt, va_list va) {
printfEnv_t env;
env.buflen = 128;
env.offset = 0;
env.buf = malloc(env.buflen);
if (!env.buf) { return -1; }
// Format the string
int ret = vpprintf(_dynamicPutc, &env, fmt, va);
// Write to stream
if (fwrite(env.buf, 1, ret, stream) != 1) { return -1; }
free(env.buf);
return ret;
}
int vprintf(const char* fmt, va_list va) { return vfprintf(stdout, fmt, va); }
// Print using an custom putc function
int pprintf(void (*outfn)(char c), const char* fmt, ...) {
va_list va;
va_start(va, fmt);
int ret = vpprintf(outfn, fmt, va);
va_end(va);
return ret;
}
// Print to a buffer
int snprintf(char* str, size_t size, const char* fmt, ...) {
va_list va;
va_start(va, fmt);
int ret = vsnprintf(str, size, fmt, va);
va_end(va);
return ret;
}
// Print to a stream
int fprintf(FILE* stream, const char* fmt, ...) {
va_list va;
va_start(va, fmt);
int ret = vfprintf(stream, fmt, va);
va_end(va);
return ret;
}
// Print to stdout
int printf(const char* fmt, ...) {
va_list va;
va_start(va, fmt);
int ret = vfprintf(stdout, fmt, va);
va_end(va);
return ret;
}
+10
View File
@@ -0,0 +1,10 @@
#include <stdio.h>
// TODO
int scanf(const char* fmt, ...);
int vscanf(const char* fmt, va_list va);
int fscanf(FILE* stream, const char* fmt, ...);
int vfscanf(FILE* stream, const char* fmt, va_list va);
int sscanf(const char* str, const char* fmt, ...);
int vsscanf(const char* str, const char* fmt, va_list va);