mirror of https://github.com/flysand7/ciabatta.git
Quick and dirty file api
This commit is contained in:
parent
dbd10db051
commit
5e177fae50
14
build.py
14
build.py
|
@ -123,10 +123,8 @@ try:
|
||||||
ciabatta_header.write('\n')
|
ciabatta_header.write('\n')
|
||||||
ciabatta_header.write('// This file is AUTO-GENERATED by library.json\n')
|
ciabatta_header.write('// This file is AUTO-GENERATED by library.json\n')
|
||||||
ciabatta_header.write('\n')
|
ciabatta_header.write('\n')
|
||||||
# Write includes
|
# Write main include
|
||||||
for include in library_config['includes']:
|
ciabatta_header.write('#include <cia-def.h>\n')
|
||||||
ciabatta_header.write(f'#include <{include}>\n')
|
|
||||||
ciabatta_header.write('\n')
|
|
||||||
# Write platform includes
|
# Write platform includes
|
||||||
platform_config = None
|
platform_config = None
|
||||||
for platform in library_config['platforms']:
|
for platform in library_config['platforms']:
|
||||||
|
@ -138,10 +136,14 @@ try:
|
||||||
include_path = os.path.join(platform_config['path'], include)
|
include_path = os.path.join(platform_config['path'], include)
|
||||||
ciabatta_header.write(f'#include "{include_path}"\n')
|
ciabatta_header.write(f'#include "{include_path}"\n')
|
||||||
ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n')
|
ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n')
|
||||||
ciabatta_header.write(f'#include "tinyrt.h"\n')
|
ciabatta_header.write(f'#include <tinyrt.h>\n')
|
||||||
for tinyrt_source in platform_config['tinyrt']:
|
for tinyrt_source in platform_config['tinyrt']:
|
||||||
ciabatta_header.write(f'#include "{target}/{tinyrt_source}"\n')
|
ciabatta_header.write(f'#include "{target}/{tinyrt_source}"\n')
|
||||||
# Write API includes
|
# Write module includes
|
||||||
|
for include in library_config['includes']:
|
||||||
|
ciabatta_header.write(f'#include <{include}>\n')
|
||||||
|
ciabatta_header.write('\n')
|
||||||
|
# Write module sources
|
||||||
ciabatta_header.write('\n')
|
ciabatta_header.write('\n')
|
||||||
for api in library_config['apis']:
|
for api in library_config['apis']:
|
||||||
api_name = api['name']
|
api_name = api['name']
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cia-def.h>
|
||||||
|
#include <tinyrt.h>
|
||||||
|
|
||||||
|
typedef u64 size_t;
|
||||||
|
|
||||||
|
typedef struct FILE FILE;
|
||||||
|
struct FILE {
|
||||||
|
_RT_File rt_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EOF (-1)
|
||||||
|
|
||||||
|
extern FILE *stdin;
|
||||||
|
extern FILE *stdout;
|
||||||
|
extern FILE *stderr;
|
||||||
|
|
||||||
|
FILE *fopen(const char *restrict filename, const char *restrict mode);
|
||||||
|
int fgetc(FILE *file);
|
||||||
|
int fputc(int c, FILE *file);
|
||||||
|
size_t fread(void *restrict buf, size_t size, size_t count, FILE *restrict file);
|
||||||
|
size_t fwrite(void const *restrict buf, size_t size, size_t count, FILE *restrict file);
|
||||||
|
int fclose(FILE *file);
|
|
@ -50,16 +50,20 @@ static _RT_Status _rt_deinit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// File API
|
// File API
|
||||||
#if _RT_API_FILE == 1
|
struct _RT_File typedef _RT_File;
|
||||||
struct _RT_File typedef _RT_File;
|
struct _RT_File {
|
||||||
struct _RT_File {
|
union {
|
||||||
union {
|
void *handle;
|
||||||
void *handle;
|
u64 fd;
|
||||||
u64 fd;
|
|
||||||
};
|
|
||||||
i32 flags;
|
|
||||||
};
|
};
|
||||||
static _RT_Status _rt_file_open(_RT_File *file, char *name, int flags);
|
i32 flags;
|
||||||
|
};
|
||||||
|
#if _RT_API_FILE == 1
|
||||||
|
static _RT_File _rt_file_stdin;
|
||||||
|
static _RT_File _rt_file_stdout;
|
||||||
|
static _RT_File _rt_file_stderr;
|
||||||
|
static _RT_Status _rt_file_std_handles_init();
|
||||||
|
static _RT_Status _rt_file_open(_RT_File *file, char const *name, int flags);
|
||||||
static _RT_Status _rt_file_read(u64 size, void *buffer, _RT_File *from, u64 *out_bytes_read);
|
static _RT_Status _rt_file_read(u64 size, void *buffer, _RT_File *from, u64 *out_bytes_read);
|
||||||
static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written);
|
static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written);
|
||||||
static _RT_Status _rt_file_close(_RT_File *file);
|
static _RT_Status _rt_file_close(_RT_File *file);
|
|
@ -0,0 +1,85 @@
|
||||||
|
|
||||||
|
FILE *stdin;
|
||||||
|
FILE *stdout;
|
||||||
|
FILE *stderr;
|
||||||
|
|
||||||
|
// TODO: memory allocation
|
||||||
|
static FILE _files[64];
|
||||||
|
static int _files_cnt = 0;
|
||||||
|
|
||||||
|
static void _fileapi_init() {
|
||||||
|
_rt_file_std_handles_init();
|
||||||
|
stdin = &_files[_files_cnt++];
|
||||||
|
stdin->rt_file = _rt_file_stdin;
|
||||||
|
stdout = &_files[_files_cnt++];
|
||||||
|
stdout->rt_file = _rt_file_stdout;
|
||||||
|
stderr = &_files[_files_cnt++];
|
||||||
|
stderr->rt_file = _rt_file_stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fopen(char const *restrict filename, char const *restrict mode) {
|
||||||
|
_RT_File rt_file;
|
||||||
|
int flags = 0;
|
||||||
|
while(*mode) {
|
||||||
|
if(*mode == 'r') flags |= _RT_FILE_READ;
|
||||||
|
if(*mode == 'w') flags |= _RT_FILE_WRITE;
|
||||||
|
// TODO: other flags
|
||||||
|
mode += 1;
|
||||||
|
}
|
||||||
|
_RT_Status status = _rt_file_open(&rt_file, filename, flags);
|
||||||
|
if(status != _RT_STATUS_OK) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
FILE *file = &_files[_files_cnt];
|
||||||
|
_files_cnt += 1;
|
||||||
|
file->rt_file = rt_file;
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fgetc(FILE *file) {
|
||||||
|
int c = 0;
|
||||||
|
u64 bytes_read;
|
||||||
|
_RT_Status status = _rt_file_read(1, &c, &file->rt_file, &bytes_read);
|
||||||
|
if(status == _RT_STATUS_FILE_EOF) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
else if(status != _RT_STATUS_OK) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fputc(int c, FILE *file) {
|
||||||
|
u64 bytes_written;
|
||||||
|
_RT_Status status = _rt_file_write(&file->rt_file, 1, &c, &bytes_written);
|
||||||
|
if(status != _RT_STATUS_OK) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fread(void *restrict buf, size_t size, size_t count, FILE *restrict file) {
|
||||||
|
u64 bytes_read;
|
||||||
|
_RT_Status status = _rt_file_read(size*count, buf, &file->rt_file, &bytes_read);
|
||||||
|
if(status != _RT_STATUS_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return bytes_read / size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fwrite(void const *restrict buf, size_t size, size_t count, FILE *restrict file) {
|
||||||
|
u64 bytes_written;
|
||||||
|
_RT_Status status = _rt_file_write(&file->rt_file, size*count, (void *)buf, &bytes_written);
|
||||||
|
if(status != _RT_STATUS_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return bytes_written / size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fclose(FILE *file) {
|
||||||
|
_RT_Status status = _rt_file_close(&file->rt_file);
|
||||||
|
if(status != _RT_STATUS_OK) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -24,8 +24,8 @@
|
||||||
// this module will not be included in the final build
|
// this module will not be included in the final build
|
||||||
|
|
||||||
includes: [
|
includes: [
|
||||||
"cia-def.h",
|
"stdlib.h",
|
||||||
"stdlib.h"
|
"stdio.h",
|
||||||
],
|
],
|
||||||
|
|
||||||
platforms: [
|
platforms: [
|
||||||
|
@ -60,6 +60,16 @@ apis: [
|
||||||
"rt_api_program",
|
"rt_api_program",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "stdlib_file",
|
||||||
|
path: "impl/stdlib-file",
|
||||||
|
includes: [
|
||||||
|
"file.c"
|
||||||
|
],
|
||||||
|
reqs: [
|
||||||
|
"rt_api_file"
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
// END
|
// END
|
||||||
|
|
|
@ -10,6 +10,8 @@ void __stack_chk_fail(void) {
|
||||||
syscall_exit(1);
|
syscall_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _fileapi_init();
|
||||||
|
|
||||||
void __libc_start_main(
|
void __libc_start_main(
|
||||||
int (*main)(int, char**, char**),
|
int (*main)(int, char**, char**),
|
||||||
int argc, char **argv,
|
int argc, char **argv,
|
||||||
|
@ -21,6 +23,7 @@ void __libc_start_main(
|
||||||
// Get the envp
|
// Get the envp
|
||||||
char **envp = argv + (argc + 1);
|
char **envp = argv + (argc + 1);
|
||||||
init(argc, argv, envp);
|
init(argc, argv, envp);
|
||||||
|
_fileapi_init();
|
||||||
main(argc, argv, envp);
|
main(argc, argv, envp);
|
||||||
fini();
|
fini();
|
||||||
// glibc bug
|
// glibc bug
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
|
|
||||||
// See src/tinyrt.h file for the interface this file implements
|
// See src/tinyrt.h file for the interface this file implements
|
||||||
|
|
||||||
static _RT_Status _rt_file_open(_RT_File *file, char *name, int _rt_flags) {
|
static _RT_File _rt_file_stdin;
|
||||||
|
static _RT_File _rt_file_stderr;
|
||||||
|
|
||||||
|
static _RT_Status _rt_file_std_handles_init() {
|
||||||
|
_rt_file_stdin.fd = 0;
|
||||||
|
_rt_file_stdin.flags = _RT_FILE_READ;
|
||||||
|
_rt_file_stdout.fd = 1;
|
||||||
|
_rt_file_stdout.flags = _RT_FILE_WRITE;
|
||||||
|
_rt_file_stderr.fd = 2;
|
||||||
|
_rt_file_stdout.flags = _RT_FILE_WRITE;
|
||||||
|
return _RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _RT_Status _rt_file_open(_RT_File *file, char const *name, int _rt_flags) {
|
||||||
if((_rt_flags & 0x3) == 0) {
|
if((_rt_flags & 0x3) == 0) {
|
||||||
return _RT_ERROR_BAD_PARAM;
|
return _RT_ERROR_BAD_PARAM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,9 @@
|
||||||
|
|
||||||
#include <cia-def.h>
|
#include <cia-def.h>
|
||||||
|
#include <stdio.h>
|
||||||
#define STDOUT_FILENO 1
|
|
||||||
#define SYS_write 1
|
|
||||||
|
|
||||||
static __inline i64 __syscall3(i64 n, i64 a1, i64 a2, i64 a3) {
|
|
||||||
i64 ret;
|
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
|
||||||
"d"(a3) : "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline i64 syscall_write(u32 fd, char const *buf, u64 count) {
|
|
||||||
return __syscall3(SYS_write, (i64)fd, (i64)buf, (u64)count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv, char **envp) {
|
int main(int argc, char **argv, char **envp) {
|
||||||
char string[] = "Hello, world!\n";
|
char string[] = "Hello, world!\n";
|
||||||
syscall_write(STDOUT_FILENO, string, sizeof string);
|
fwrite(string, 1, sizeof string-1, stdout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue