summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/syscall.h16
-rw-r--r--lib/printf.c200
-rw-r--r--sys/syscall_objdir.c4
-rw-r--r--sys/syscall_untyped.c4
4 files changed, 125 insertions, 99 deletions
diff --git a/api/syscall.h b/api/syscall.h
index cf8b1c1..bdd9972 100644
--- a/api/syscall.h
+++ b/api/syscall.h
@@ -10,16 +10,21 @@ struct syscall_header
{
uint16_t callid;
uint16_t pathlen;
- uint16_t path[];
+ objpath_part_t path[];
};
-#define SYSCALL_VTT_WRITE 0
struct syscall_generic_write
{
size_t len;
char data[];
};
+struct syscall_generic_objpath
+{
+ uint16_t pathlen;
+ objpath_part_t path[];
+};
+
#define SYSCALL_UNTYPED_SIZE 0
#define SYSCALL_UNTYPED_ALIGN 1
@@ -37,12 +42,9 @@ struct syscall_untyped_split
uint16_t dest_pathlen;
objpath_part_t dest_path[];
};
-struct syscall_generic_objpath
-{
- uint16_t second_pathlen;
- objpath_part_t second_path[];
-};
#define SYSCALL_OBJDIR_OBJTYPE 0
+#define SYSCALL_VTT_WRITE 0
+
#endif
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;
diff --git a/sys/syscall_objdir.c b/sys/syscall_objdir.c
index cf1e5b7..5e49fd4 100644
--- a/sys/syscall_objdir.c
+++ b/sys/syscall_objdir.c
@@ -14,11 +14,11 @@ s_syscall_objdir_objtype(
CHECK_TOOSMALL(bytes_needed, payload_size, "Message is too small for this payload!");
struct syscall_generic_objpath *payload = payload_data;
- bytes_needed += payload->second_pathlen * 2;
+ bytes_needed += payload->pathlen * 2;
CHECK_TOOSMALL(bytes_needed, payload_size, "Message is too small for second target path!");
int retval = 0;
- jove_owned_obj_t *second_obj = objdir_getobj(objdir, payload->second_path, payload->second_pathlen);
+ jove_owned_obj_t *second_obj = objdir_getobj(objdir, payload->path, payload->pathlen);
CHECK_OBJEXISTS(second_obj, "Second target does not exist!");
retval = obj_gettype(second_obj);
diff --git a/sys/syscall_untyped.c b/sys/syscall_untyped.c
index 52a0715..3467830 100644
--- a/sys/syscall_untyped.c
+++ b/sys/syscall_untyped.c
@@ -35,10 +35,10 @@ s_syscall_untyped_merge(
CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for payload!");
struct syscall_generic_objpath *payload = payload_data;
- bytes_needed += payload->second_pathlen * 2;
+ bytes_needed += payload->pathlen * 2;
CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for second path!");
- jove_owned_obj_t *snd_obj = objdir_getobj(objdir, payload->second_path, payload->second_pathlen);
+ jove_owned_obj_t *snd_obj = objdir_getobj(objdir, payload->path, payload->pathlen);
CHECK_OBJTYPE(snd_obj, JOVE_OBJ_UNTYPED, "Second object is not an untyped!");
return untyped_merge(target_obj, snd_obj);