#include #include #include #include #include #include #include #include char *utoa(uintmax_t v, int base, bool uppercase) { if (base < 2 || base > 36) { return NULL; } static char buf[sizeof(uintmax_t) * CHAR_BIT + 3]; const char *digits = uppercase ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "0123456789abcdefghijklmnopqrstuvwxyz"; size_t i = sizeof(buf) - 1; buf[i] = '\0'; if (v == 0) { buf[--i] = '0'; return &buf[i]; } while (v != 0) { if (i == 0) { return NULL; } buf[--i] = digits[v % base]; v /= base; } return &buf[i]; } char *itoa(intmax_t v, int base, bool uppercase) { if (base < 2 || base > 36) { return NULL; } static char buf[sizeof(uintmax_t) * CHAR_BIT + 3]; const char *digits = uppercase ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "0123456789abcdefghijklmnopqrstuvwxyz"; size_t i = sizeof(buf) - 1; buf[i] = '\0'; if (v == 0) { buf[--i] = '0'; return &buf[i]; } bool neg = (v < 0); uintmax_t u; if (neg) { u = (uintmax_t)(-(v + 1)) + 1; } else { u = (uintmax_t)v; } while (u != 0) { if (i == 0) { return NULL; } buf[--i] = digits[u % base]; u /= base; } if (neg) { if (i == 0) { return NULL; } buf[--i] = '-'; } return &buf[i]; } #define FMTBUF_MAX 2048 extern Dev_t termdev; enum { WRITE_FORMATMODE, WRITE_NORMALMODE, }; const char *convstr1 = "0123456789abcdef"; const char *convstr2 = "0123456789ABCDEF"; void writefmt(char *fmt, ...) { va_list list; va_start(list, fmt); writevfmt(fmt, list); va_end(list); } #define ITOA_BUF_SIZE 32 void writevsfmt(char *buf, char *fmt, va_list list) { size_t c = 0; int WRITE_STATE = WRITE_NORMALMODE; for (size_t i = 0; fmt[i] != '\0'; i++) { if (WRITE_STATE == WRITE_NORMALMODE) { switch (fmt[i]) { case '{': WRITE_STATE = WRITE_FORMATMODE; break; default: buf[c++] = fmt[i]; break; } } else if (WRITE_STATE == WRITE_FORMATMODE) { switch (fmt[i]) { case '}': WRITE_STATE = WRITE_NORMALMODE; break; case 's': { char *string = va_arg(list, char *); while (*string) { buf[c++] = *string; string++; } } break; case 'd': { int int1 = va_arg(list, int); char *string = itoa(int1, 10, false); while (*string) { buf[c++] = *string; string++; } } break; case 'x': { unsigned int int1 = va_arg(list, unsigned int); char *string = utoa(int1, 16, false); while (*string) { buf[c++] = *string; string++; } } break; case 'X': { unsigned int int1 = va_arg(list, unsigned int); char *string = utoa(int1, 16, true); while (*string) { buf[c++] = *string; string++; } } break; case 'p': { uintptr_t ptr = (uintptr_t)va_arg(list, void *); char *string = utoa(ptr, 16, false); while (*string) { buf[c++] = *string; string++; } } break; case 'P': { uintptr_t ptr = (uintptr_t)va_arg(list, void *); char *string = utoa(ptr, 16, true); while (*string) { buf[c++] = *string; string++; } } break; case 'c': { char c1 = (char)va_arg(list, char); buf[c++] = c1; } break; } } } } void writevfmt(char *fmt, va_list list) { char buf[FMTBUF_MAX]; writevsfmt(buf, fmt, list); devctl(&termdev, 0x00, buf, sizeof(buf), 0); }