This commit is contained in:
2025-09-27 15:16:26 +02:00
parent 5af7c5276a
commit 3b1bb9d531
63 changed files with 1087 additions and 407 deletions

161
ulib/write/write.c Normal file
View 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);
}