Mon 16 Mar 11:09:06 CET 2026
This commit is contained in:
parent
389ba56aa3
commit
57ef333953
151
src/printf.c
Normal file
151
src/printf.c
Normal 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; }
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user