82 lines
1.7 KiB
C
82 lines
1.7 KiB
C
|
|
// 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;
|
|
}
|
|
|