basic printf

This commit is contained in:
flysand7 2023-09-12 04:33:42 +11:00
parent 4c0041414d
commit 4917b05771
4 changed files with 151 additions and 2 deletions

1
cia.c
View File

@ -31,6 +31,7 @@
// Module stdlib_file
#include "src/stdlib-file/file.c"
#include "src/stdlib-file/fmt.c"
// Module stdlib_string
#include "src/stdlib-string/mem.c"

View File

@ -4,6 +4,7 @@
#include <cia/def.h>
#include <cia/sync.h>
#include <tinyrt.h>
#include <stdarg.h>
typedef struct FILE FILE;
struct FILE {
@ -23,3 +24,5 @@ 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);
int printf(char const *restrict fmt, ...);

144
src/stdlib-file/fmt.c Normal file
View File

@ -0,0 +1,144 @@
static int print_string(char *str) {
int str_len = 0;
while(str[str_len] != 0) {
str_len += 1;
}
u64 unused;
_RT_Status status = _rt_file_write(&stdout->rt_file, str_len, str, &unused);
if(status != _RT_STATUS_OK) {
return -1;
};
return str_len;
}
static int print_int(i64 number) {
bool negative = (number < 0);
if(negative) {
number = -number;
}
char buf[20];
buf[sizeof buf - 1] = 0;
char *p = buf + sizeof buf - 1;
do {
*--p = (number%10) + '0';
number /= 10;
} while(number > 0);
if(negative) {
*--p = '-';
}
u64 unused;
int buf_len = (int)(&buf[0] + sizeof buf - p);
_RT_Status status = _rt_file_write(&stdout->rt_file, buf_len, p, &unused);
if(status != _RT_STATUS_OK) {
return -1;
}
return buf_len;
}
static int print_uint(u64 number) {
char buf[20];
buf[sizeof buf - 1] = 0;
char *p = buf + sizeof buf - 1;
do {
*--p = (number%10) + '0';
number /= 10;
} while(number > 0);
u64 unused;
int buf_len = (int)(&buf[0] + sizeof buf - p);
_RT_Status status = _rt_file_write(&stdout->rt_file, buf_len, p, &unused);
if(status != _RT_STATUS_OK) {
return -1;
}
return buf_len;
}
static int print_hex(u64 number) {
char digits[] = "0123456789abcdef";
char buf[20];
buf[sizeof buf - 1] = 0;
char *p = buf + sizeof buf - 1;
for(int i = 0; i < 64; i += 4) {
// if(i != 0 && i % 16 == 0) {
// *--p = '_';
// }
u8 bits = (number >> i) & 0x0f;
char digit = digits[bits];
*--p = digit;
}
*--p = 'x';
*--p = '0';
u64 unused;
int buf_len = (int)(&buf[0] + sizeof buf - p);
_RT_Status status = _rt_file_write(&stdout->rt_file, buf_len, p, &unused);
if(status != _RT_STATUS_OK) {
return -1;
}
return buf_len;
}
int printf(const char *restrict fmt, ...) {
i64 ret_printed = 0;
va_list args;
va_start(args, fmt);
i64 buf_start_idx = 0;
i64 buf_end_idx = 0;
u64 unused;
for(i64 i = 0; fmt[i] != 0;) {
buf_start_idx = i;
buf_end_idx = i;
while(fmt[i] != '%' && fmt[i] != 0) {
buf_end_idx += 1;
i += 1;
}
i64 buf_size = buf_end_idx - buf_start_idx;
if(buf_size != 0) {
_RT_Status status = _rt_file_write(
&stdout->rt_file
, buf_size
, (void *)&fmt[buf_start_idx]
, &unused
);
if(status != _RT_STATUS_OK) {
return -1;
}
ret_printed += buf_size;
}
if(fmt[i] == 0) {
break;
}
// fmt[i] == '%'
i += 1;
int arg_chars;
if(fmt[i] == 'd') {
int arg = va_arg(args, int);
arg_chars = print_int((i64)arg);
}
else if(fmt[i] == 'u') {
unsigned int arg = va_arg(args, unsigned int);
arg_chars = print_uint((u64)arg);
}
else if(fmt[i] == 'p') {
void *arg = va_arg(args, void *);
arg_chars = print_hex((u64)arg);
}
else if(fmt[i] == 's') {
char *str = va_arg(args, char *);
arg_chars = print_string(str);
}
else if(fmt[i] == 'c') {
int ch = va_arg(args, int);
_RT_Status status = _rt_file_write(&stdout->rt_file, 1, &ch, &unused);
if(status != _RT_STATUS_OK) {
return -1;
}
arg_chars = 1;
}
i += 1;
if(arg_chars < 0) {
return -1;
}
ret_printed += arg_chars;
}
va_end(args);
return ret_printed;
}

View File

@ -3,7 +3,8 @@
#include <stdio.h>
int main(int argc, char **argv, char **envp) {
char string[] = "Hello, world!\n";
fwrite(string, 1, sizeof string-1, stdout);
// char string[] = "Hello, world!\n";
// fwrite(string, 1, sizeof string-1, stdout);
printf("Hello, world! %d\n", 4);
return 0;
}