Mon 16 Mar 11:09:06 CET 2026

This commit is contained in:
sbosse 2026-03-16 11:10:39 +01:00
parent 389ba56aa3
commit 57ef333953

151
src/printf.c Normal file
View File

@ -0,0 +1,151 @@
#include "config.h"
#include "printf.h"
// output stream
static index_t _stdout=1;
/*
Important: Output channel can be busy/full!
AVAILBYTE(od)==0
*/
INLINE void print_char(char c) {
OUTBYTE(_stdout,c);
}
void print_int(int i) {
if (i < 0) {
OUTBYTE(_stdout,'-');
i = -i;
}
if (i / 10) print_int(i / 10);
OUTBYTE(_stdout,i % 10 + '0');
}
char* sprint_int(char *buf, int i) {
if (i < 0) {
*buf='-';
i = -i;
buf++;
}
if (i / 10) buf=sprint_int(buf,i / 10);
*buf=i % 10 + '0';
buf++;
return buf;
}
void print_uint_hex(int i) {
if (i / 16) print_uint_hex(i / 16);
OUTBYTE(_stdout,i % 16 > 9? 'A'+(i%16)-10: (i%16) + '0');
}
void print_uint(unsigned int i) {
if (i / 10) print_uint(i / 10);
OUTBYTE(_stdout,i % 10 + '0');
}
#if HAS_FLOAT==0
void print_number(number_t x) {
print_int((int)x);
}
#else
// TODO
#endif
/*
returns number of written array elements
returns zero or negative number if out channel is blocked
*/
int print_array(number_t *x,index_t len) {
int n=0;
while (len) {
print_number(*x);
x++;len--;
n++;
}
return n;
}
/*
returns number of written array elements
returns zero or negative number if out channel is blocked
*/
int print_string(char *s) {
int n=0;
while (*s) {
OUTBYTE(_stdout,*s++);
n++;
}
return n;
}
void print_format(char *format, ...) {
void **arg = (void **) &format + 1;
for (char *p = format; *p; p++) {
if (*p != '%') {
OUTBYTE(_stdout,*p);
continue;
}
switch (*++p) {
case 'd':
print_int(*(int *) arg++);
break;
case 'x':
print_uint_hex(*(int *) arg++);
break;
case 'u':
print_uint(*(unsigned int *) arg++);
break;
case 'c':
OUTBYTE(_stdout,*(char *) arg++);
break;
case 's':
print_string(*(char **) arg++);
break;
case '%':
OUTBYTE(_stdout,'%');
break;
default:
OUTBYTE(_stdout,*p);
break;
}
}
}
/*
buffer versions supporting up and down growing cyclic buffers
dir=1: [0,1,..,size-1]
dir=-1 : [size-1,size-2,..,0]
dir=-2 : [size-1,size-2,..,size/2]
*/
int bprint_char(char *buf, int off, int size, int dir, char c) {
buf[off]=c;
if (dir==1) off=(off+1)%size;
else if (dir==-1) off=off==0?size-1:off-1;
else /*-2*/ off=off==size/2?size-1:off-1;
return off;
}
int bprint_int(char *buf, int off, int size, int dir, int i) {
if (i < 0) {
buf[off]='-';
i = -i;
if (dir==1) off=(off+1)%size;
else if (dir==-1) off=off==0?size-1:off-1;
else /*-2*/ off=off==size/2?size-1:off-1;
}
if (i / 10) off=bprint_int(buf,off,size,dir, i / 10);
buf[off]=i % 10 + '0';
if (dir==1) off=(off+1)%size;
else if (dir==-1) off=off==0?size-1:off-1;
else /*-2*/ off=off==size/2?size-1:off-1;
return off;
}
/*
Set standard output channel (default 1)
*/
index_t print_stdout(index_t handle) { index_t old=_stdout; _stdout=handle; return old; }