Skip to content

Commit

Permalink
add stdlib vsnprintf, fprintf, vfprintf
Browse files Browse the repository at this point in the history
  • Loading branch information
twiddlingbits committed Apr 28, 2024
1 parent 422890c commit f69ad4f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 24 deletions.
13 changes: 12 additions & 1 deletion include/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,28 @@
#define __TINY_STDIO_H__

#include "stddef.h"
#include "assert.h"

#ifdef __cplusplus
extern "C" {
#endif

#define snprintf(x,y, ...) twr_snprintf(x,y, __VA_ARGS__)
static inline int vsnprintf(char *buffer, size_t bufsz, const char *format, va_list vlist) {return twr_vsnprintf(buffer, (twr_size_t)bufsz, format, vlist); }
#define printf(...) twr_printf(__VA_ARGS__)
#define fprintf(x, ...) twr_fprintf(x, __VA_ARGS__)
#define vfprintf( x, y, z ) twr_vfprintf( x, y, z )


//void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va_list* args);

static inline int remove( const char* pathname ) {assert(0);return -1;} // not implemented; here to get libc++ to compile

// EOF not implemented; here to get libc++ to compile
#define EOF (-1)

#ifdef __cplusplus
}
#endif

#endif
#endif
64 changes: 41 additions & 23 deletions source/twr-crt/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void static do_width(const char* in, char* assembly, int size_assembly, bool pad
twr_strcat_s(assembly, size_assembly, in);
}

void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va_list* args) {
void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va_list vlist) {
struct pformat pf;

while (*format) {
Expand All @@ -91,7 +91,7 @@ void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va
char buffer[20];
char assembly[20];
int assemoff;
int val=va_arg(*args, int);
int val=va_arg(vlist, int);
twr_itoa_s(val, buffer, sizeof(buffer), 10);

if (val>=0 && pf.flag_space) {
Expand All @@ -111,7 +111,7 @@ void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va
{
char buffer[16];
char assembly[16];
twr_itoa_s(va_arg(*args, int), buffer, sizeof(buffer), 16);
twr_itoa_s(va_arg(vlist, int), buffer, sizeof(buffer), 16);
do_width(buffer, assembly, sizeof(assembly), pf.flag_zero, pf.width);
outstr(out, cbdata, assembly, sizeof(assembly));

Expand All @@ -123,7 +123,7 @@ void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va
char buffer[30];
char assembly[30];
int assemoff;
double val=va_arg(*args, double);
double val=va_arg(vlist, double);
twr_wasm_tofixed(buffer, sizeof(buffer), val, pf.precision);

if (val>=0 && pf.flag_space) {
Expand All @@ -144,7 +144,7 @@ void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va
char buffer[30];
char assembly[30];
int assemoff;
double val=va_arg(*args, double);
double val=va_arg(vlist, double);
twr_wasm_toexponential(buffer, sizeof(buffer), val, pf.precision);

if (val>=0 && pf.flag_space) {
Expand All @@ -164,7 +164,7 @@ void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va
{
char buffer[30];
char assembly[30];
double val=va_arg(*args, double);
double val=va_arg(vlist, double);
int assemoff;
twr_dtoa(buffer, sizeof(buffer), val, pf.precision);
if (val>=0 && pf.flag_space) {
Expand All @@ -180,12 +180,12 @@ void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va
break;

case 's':
outstr(out, cbdata, va_arg(*args, char *), 100000); // arbitrary max of 100K string length
outstr(out, cbdata, va_arg(vlist, char *), 100000); // arbitrary max of 100K string length
break;

case 'c':
{
const int c=va_arg(*args, int);
const int c=va_arg(vlist, int);
out(cbdata, c);
}
break;
Expand All @@ -203,9 +203,9 @@ void twr_vprintf(twr_cbprintf_callback out, void* cbdata, const char *format, va
}

struct snprintf_callback_data {
int size;
char* buffer;
int pos;
char *const buffer;
const twr_size_t size;
twr_size_t pos;
};

static void snprintf_callback(void* datain, char ch) {
Expand All @@ -215,29 +215,33 @@ static void snprintf_callback(void* datain, char ch) {
}
}

int twr_snprintf(char* buffer, int size, const char* format, ...) {
va_list args;
va_start(args, format);
int twr_snprintf(char *buffer, twr_size_t bufsz, const char *format, ... ) {
va_list vlist;
va_start(vlist, format);

struct snprintf_callback_data data;
data.buffer=buffer;
data.size=size;
data.pos=0;
const int rv=twr_vsnprintf(buffer, bufsz, format, vlist);

twr_vprintf(snprintf_callback, &data, format, &args);
va_end(vlist);

if (data.pos<data.size) buffer[data.pos++]=0;
return rv;
}

va_end(args);
int twr_vsnprintf(char *buffer, twr_size_t bufsz, const char *format, va_list vlist) {
struct snprintf_callback_data data = {.buffer=buffer, .size=bufsz, .pos=0};

twr_vprintf(snprintf_callback, &data, format, vlist);

if (data.pos<data.size) buffer[data.pos++]=0;

return data.pos;
}


void twr_printf(const char* format, ...) {
va_list args;
va_start(args, format);

twr_vprintf((twr_cbprintf_callback)io_putc, twr_get_stdio_con(), format, &args);
twr_vprintf((twr_cbprintf_callback)io_putc, twr_get_stdio_con(), format, args);

va_end(args);
}
Expand All @@ -247,12 +251,26 @@ void twr_conlog(const char* format, ...) {
va_list args;
va_start(args, format);

twr_vprintf((twr_cbprintf_callback)io_putc, twr_get_dbgout_con(), format, &args);
twr_vprintf((twr_cbprintf_callback)io_putc, twr_get_dbgout_con(), format, args);
io_putc(twr_get_dbgout_con(), 0x3); // ASCII EOT is used to flush the buffer and make sure the line prints to the console.

va_end(args);
}

void twr_fprintf(FILE *stream, const char* format, ...) {
va_list vlist;
va_start(vlist, format);

twr_vprintf((twr_cbprintf_callback)io_putc, stream, format, vlist);

va_end(vlist);
}

// should reurns The number of characters written if successful or negative value if an error occurred.
void twr_vfprintf( FILE *stream, const char *format, va_list vlist ) {
twr_vprintf((twr_cbprintf_callback)io_putc, stream, format, vlist);
}


int twr_printf_unit_test() {
char b[100];
Expand Down

0 comments on commit f69ad4f

Please sign in to comment.