#include "amistdio.h" #include #include #include #include #include #include #include #include static char __printf_default_buffer[80]; static int bsz = sizeof(__printf_default_buffer); static char *buffer = __printf_default_buffer; void __freeBuff() { if (buffer && buffer != __printf_default_buffer) { FreeVec(buffer); buffer = 0; } } void setPrintfBufferSize(int sz) { char * p = (char*) AllocVec(sz, MEMF_PUBLIC); if (p) { __freeBuff(); buffer = p; bsz = sz; } } ADD2EXIT(__freeBuff, -42); // the callback per character, checks for end of buffer! void __amiputs_putchar_callback(register char *ptr asm("a3")) { asm volatile("cmp.b #-1,(a3)"); asm volatile("bne.s __Skip"); asm volatile("move.b d0,(a3)+"); asm volatile("__Skip:"); } int amivsnprintf(char * buff, int sz, const char *fmt, va_list args) { memset(buff, 0xff, sz - 1); buff[sz - 1] = 0; RawDoFmt(fmt, args, (void(*)())__amiputs_putchar_callback, buff); return strlen(buff); } int amivfprintf(BPTR f, const char *fmt, va_list args) { int r; for(;;) { r = amivsnprintf(buffer, bsz, fmt, args); if (r + 1 < bsz) // reached end of buffer? break; int obsz = bsz; // try to resize setPrintfBufferSize(bsz * 3); if (obsz == bsz) break; // resize failed // print again with longer buffer } FPuts(f, buffer); if (strchr(buffer, '\n')) Flush(f); return r; } int amisnprintf(char * to, int sz, char const *fmt, ...) { va_list args; va_start(args, fmt); int retval = amivsnprintf(to, sz, fmt, args); va_end(args); return retval; } int amiprintf(char const *fmt, ...) { va_list args; va_start(args, fmt); int retval = amivfprintf(Output(), fmt, args); va_end(args); return retval; } int amifprintf(BPTR f, char const *fmt, ...) { va_list args; va_start(args, fmt); int retval = amivfprintf(f, fmt, args); va_end(args); return retval; }