WIP 2
This commit is contained in:
161
ulib/write/write.c
Normal file
161
ulib/write/write.c
Normal file
@ -0,0 +1,161 @@
|
||||
#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);
|
||||
}
|
Reference in New Issue
Block a user