jacking/zynq/zynq_printf.h

82 lines
1.7 KiB
C
Raw Normal View History

2022-01-29 01:26:40 +00:00
// because xil_printf's behavior isn't very portable, and the xilinx bare-metal
// libraries don't provide a printf() implementation, we will make one here
// using xil_printf under the hood
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define XIL_NEWLINE "\n\r" /* yeah... wat */
static char* pbuf = NULL;
static int psize = 0;
int vdprintf(int fd, const char* fmt, va_list args) {
(void)fd;
if (pbuf == NULL) {
psize = 80; // initial value: "default" terminal width
pbuf = malloc(psize);
}
int r;
do {
r = vsnprintf(pbuf, psize, fmt, args);
if (r < 0) return r;
if (r < psize - 1) // it fits into the buffer, so we can stop
break;
// make buffer larger, and try again
psize <<= 1;
pbuf = realloc(pbuf, psize);
} while (1);
// print line by line
char* start = pbuf;
for (char* c = pbuf; *c && (ptrdiff_t)c < (ptrdiff_t)pbuf + r; ++c) {
if (*c == '\n') {
*c = '\0';
xil_printf("%s" XIL_NEWLINE, start);
start = c + 1;
}
}
if (*start && (ptrdiff_t)start < (ptrdiff_t)pbuf + r) {
xil_printf("%s", start);
}
return r;
}
int dprintf(int fd, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int r = vdprintf(fd, fmt, args);
va_end(args);
return r;
}
int vprintf(const char* fmt, va_list args) {
return vdprintf(1 /*STDOUT_FILENO*/, fmt, args);
}
int printf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int r = vprintf(fmt, args);
va_end(args);
return r;
}
int vfprintf(FILE* f, const char* fmt, va_list args) {
(void)f;
return vdprintf(/*fileno(f)*/ 1, fmt, args);
}
int fprintf(FILE* f, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int r = vfprintf(f, fmt, args);
va_end(args);
return r;
}