summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-09-07 21:14:36 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-09-07 21:14:36 -0400
commit880dc3ee72809e74a5bde2275fc8f419a762b255 (patch)
treea56ba7c771443e257a0640a826aaa376e72cbce5 /lib
parentdf0688efa326a03a22bcbc36d1900926b7b1c986 (diff)
downloadjove-kernel-880dc3ee72809e74a5bde2275fc8f419a762b255.tar.gz
jove-kernel-880dc3ee72809e74a5bde2275fc8f419a762b255.tar.bz2
jove-kernel-880dc3ee72809e74a5bde2275fc8f419a762b255.zip
small refactor to vsnprintf
Diffstat (limited to 'lib')
-rw-r--r--lib/printf.c200
1 files changed, 112 insertions, 88 deletions
diff --git a/lib/printf.c b/lib/printf.c
index 4e64d7b..b96c616 100644
--- a/lib/printf.c
+++ b/lib/printf.c
@@ -22,7 +22,6 @@ convert_as_int(
char *str,
size_t size,
int stri,
- int field_width,
uintmax_t value,
int radix,
int unsign)
@@ -37,17 +36,79 @@ convert_as_int(
for(uintmax_t i = value; i != 0; i /= radix) digits++;
if(value == 0) digits++;
- if(field_width < digits) field_width = digits;
for(uintmax_t i = value, digiti = 0; digiti < digits; i /= radix) {
char i_mod = (char)(i % radix);
- int stri_digiti = stri + (field_width - digiti) - 1;
+ int stri_digiti = stri + (digits - digiti) - 1;
SPRINTF_PUTC(str, size, stri_digiti,
(i_mod > 9 ? (i_mod + 'a' - 10) : (i_mod + '0')));
digiti++;
}
- return field_width + (stri - ostri) + 1;
+ return digits;
+}
+
+enum printf_state
+{
+ FSTATE_DIRECT = 0,
+ FSTATE_CONVERT
+};
+
+static int
+s_convert_string(char *str, size_t size, va_list ap, size_t stri)
+{
+ const char *strarg = va_arg(ap, const char*);
+ for(const char *strargc = strarg; *strargc; strargc++) {
+ SPRINTF_PUTC(str, size, stri, *strargc);
+ }
+ return stri;
+}
+
+static int
+s_convert_int(char *str, size_t size, va_list ap, size_t stri,
+ int fw, char fp, int typelen, int radix, int usign, int caps)
+{
+ char num_buf[64];
+ uintmax_t value = 0;
+ switch(typelen) {
+ case 1: value = (uintmax_t)(int8_t)va_arg(ap, int); break;
+ case 2: value = (uintmax_t)(int16_t)va_arg(ap, int); break;
+ default:
+ case 4: value = (uintmax_t)va_arg(ap, unsigned int); break;
+ case 8: value = (uintmax_t)va_arg(ap, uintmax_t); break;
+ }
+ size_t pad_stri = stri;
+
+ int advance = convert_as_int(num_buf, 64, 0, value, radix, usign);
+ if(caps) {
+ for(int i = 0; i < advance; i++) {
+ num_buf[i] = c_toupper(num_buf[i]);
+ }
+ }
+
+ int pad_diff = fw - advance;
+ for(int i = 0; i < pad_diff; i++) {
+ SPRINTF_PUTC(str, size, stri, fp);
+ }
+ for(int i = 0; i < advance; i++) {
+ SPRINTF_PUTC(str, size, stri, num_buf[i]);
+ }
+
+ return stri;
+}
+
+int
+s_convert_path(char *str, size_t size, va_list ap, size_t stri)
+{
+ uint16_t *obj_path = va_arg(ap, uint16_t*);
+ size_t obj_pathlen = va_arg(ap, size_t);
+ for(size_t i = 0; i < obj_pathlen; i++) {
+ uint16_t subdir = obj_path[i];
+ int advance = convert_as_int(str, size, stri, subdir, 10, 1);
+ stri += advance;
+ SPRINTF_PUTC(str, size, stri, '/');
+ }
+ return stri;
}
int
@@ -56,97 +117,60 @@ vsnprintf(
const char *fmt, va_list ap)
{
int stri = 0;
+ int state = FSTATE_DIRECT;
+
for(const char *fmtc = fmt; *fmtc; fmtc++) {
- if(*fmtc != '%') {
+ if(state == FSTATE_DIRECT) {
+ if(*fmtc == '%') {
+ state = FSTATE_CONVERT;
+ continue;
+ }
SPRINTF_PUTC(str, size, stri, *fmtc);
- continue;
- }
- fmtc++;
-
- //TODO: other format specifiers.
- int field_width = 0;
- char field_pad = ' ';
+ }else {
+ int field_width = 0;
+ char field_pad = ' ';
- int lenspec = 4;
+ int lenspec = 4;
- int radix = 10;
- int unsign = 0;
- int caps = 0;
- switch(*fmtc) {
- case 's':
- goto string_conversion;
- case 'b':
- radix = 2;
- goto int_conversion;
- break;
- case 'o':
- radix = 8;
- goto int_conversion;
- break;
- case 'p':
- lenspec = sizeof(uintptr_t);
- field_width = lenspec * 2;
- field_pad = '0';
- case 'X':
- caps = 1;
- case 'x':
- unsign = 1;
- radix = 16;
- goto int_conversion;
- break;
- case 'u':
- unsign = 1;
- case 'd':
- case 'i':
- goto int_conversion;
- break;
- /*custom formatters for jove.*/
- case 'P':
- goto path_conversion;
- break;
- }
-string_conversion:
- {
- const char *strarg = va_arg(ap, const char*);
- for(const char *strargc = strarg; *strargc; strargc++) {
- SPRINTF_PUTC(str, size, stri, *strargc);
- }
- } continue;
-int_conversion:
- {
- uintmax_t value = 0;
- switch(lenspec) {
- case 1: value = (uintmax_t)(int8_t)va_arg(ap, int); break;
- case 2: value = (uintmax_t)(int16_t)va_arg(ap, int); break;
- default:
- case 4: value = (uintmax_t)va_arg(ap, unsigned int); break;
- case 8: value = (uintmax_t)va_arg(ap, uintmax_t); break;
- }
- size_t pad_stri = stri;
- for(size_t i = 0; i < field_width; i++) {
- SPRINTF_PUTC(str, size, pad_stri, field_pad);
- }
+ int radix = 10;
+ int unsign = 0;
+ int caps = 0;
- int advance = convert_as_int(str, size, stri, field_width, value, radix, unsign);
- if(caps && str) {
- for(int i = 0; i < advance; i++) {
- int stra = stri + i;
- if(stra < size) str[stra] = c_toupper(str[stra]);
+ if(state == FSTATE_CONVERT) {
+ switch(*fmtc) {
+ case 's':
+ stri = s_convert_string(str, size, ap, stri);
+ break;
+ case 'b':
+ stri = s_convert_int(str, size, ap, stri, field_width, field_pad, lenspec, 2, 1, 0);
+ break;
+ case 'o':
+ stri = s_convert_int(str, size, ap, stri, field_width, field_pad, lenspec, 8, 0, 0);
+ break;
+ case 'p':
+ lenspec = sizeof(uintptr_t);
+ field_width = lenspec * 2;
+ field_pad = '0';
+ case 'X':
+ caps = 1;
+ case 'x':
+ unsign = 1;
+ stri = s_convert_int(str, size, ap, stri, field_width, field_pad, lenspec, 16, unsign, caps);
+ break;
+ case 'u':
+ unsign = 1;
+ case 'd':
+ case 'i':
+ stri = s_convert_int(str, size, ap, stri, field_width, field_pad, lenspec, 10, unsign, caps);
+ break;
+ /*custom formatters for jove.*/
+ case 'P':
+ stri = s_convert_path(str, size, ap, stri);
+ break;
}
}
- stri += advance;
- } continue;
-path_conversion:
- {
- uint16_t *obj_path = va_arg(ap, uint16_t*);
- size_t obj_pathlen = va_arg(ap, size_t);
- for(size_t i = 0; i < obj_pathlen; i++) {
- uint16_t subdir = obj_path[i];
- int advance = convert_as_int(str, size, stri, 3, subdir, 10, 1);
- stri += advance;
- SPRINTF_PUTC(str, size, stri, '/');
- }
- } continue;
+ state = FSTATE_DIRECT;
+ }
}
if(str && stri < size) str[stri] = 0;
return stri;