diff options
| -rw-r--r-- | api/syscall.h | 16 | ||||
| -rw-r--r-- | lib/printf.c | 200 | ||||
| -rw-r--r-- | sys/syscall_objdir.c | 4 | ||||
| -rw-r--r-- | sys/syscall_untyped.c | 4 |
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); |
