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