#pragma once #include #include /* The interpreter only uses %s, %c, %d and %zu. No device stdio required. */ typedef void FILE; #define stdin ((FILE *)0) #define stderr ((FILE *)0) #define EOF (-1) static int vsnprintf(char *dst, size_t cap, const char *fmt, va_list ap) { size_t n = 0; #define EMIT(c) do { char emitted = (c); if (n + 1 < cap) dst[n] = emitted; ++n; } while (0) while (*fmt) { if (*fmt != '%') { EMIT(*fmt++); continue; } ++fmt; if (*fmt == 's') { const char *s = va_arg(ap, const char *); while (*s) { EMIT(*s++); } } else if (*fmt == 'c') { char c = (char)va_arg(ap, int); EMIT(c); } else { unsigned v; if (*fmt == 'z') { ++fmt; v = (unsigned)va_arg(ap, size_t); } else { int value = va_arg(ap, int); v = (unsigned)value; if (value < 0) { EMIT('-'); v = 0u - v; } } char digits[10]; unsigned count = 0; do { digits[count++] = '0' + v % 10; v /= 10; } while (v); while (count) { char c = digits[--count]; EMIT(c); } } ++fmt; } if (cap) dst[n < cap ? n : cap - 1] = 0; #undef EMIT return (int)n; } static int snprintf(char *dst, size_t cap, const char *fmt, ...) { va_list ap; va_start(ap, fmt); int n = vsnprintf(dst, cap, fmt, ap); va_end(ap); return n; } static int isdigit(int c) { return c >= '0' && c <= '9'; } static int isalpha(int c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } static int isalnum(int c) { return isalpha(c) || isdigit(c); }