162 lines
3.6 KiB
C
162 lines
3.6 KiB
C
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include <limits.h>
|
|
#include <system/system.h>
|
|
#include <sysdefs/devctl.h>
|
|
#include <write/write.h>
|
|
|
|
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);
|
|
}
|