// 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 #include #include #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; }