_Litob.c (1500B)
1 #include "libultra_internal.h" 2 #include <stdlib.h> 3 #include <string.h> 4 #include "printf.h" 5 6 #define BUFF_LEN 0x18 7 8 static u8 ldigs[] = "0123456789abcdef"; 9 static u8 udigs[] = "0123456789ABCDEF"; 10 11 void _Litob(printf_struct *args, fmt_type type) { 12 u8 buff[BUFF_LEN]; 13 const u8 *num_map; 14 s32 base; 15 s32 buff_ind; 16 u64 num; 17 lldiv_t quotrem; 18 19 if (type == 'X') { 20 num_map = udigs; 21 } else { 22 num_map = ldigs; 23 } 24 25 base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); 26 buff_ind = BUFF_LEN; 27 num = args->value.s64; 28 29 if ((type == 'd' || type == 'i') && args->value.s64 < 0) { 30 num = -num; 31 } 32 33 if (num != 0 || args->precision != 0) { 34 buff[--buff_ind] = num_map[num % base]; 35 } 36 37 args->value.s64 = num / base; 38 39 while (args->value.s64 > 0 && buff_ind > 0) { 40 quotrem = lldiv(args->value.s64, base); 41 args->value.s64 = quotrem.quot; 42 buff[--buff_ind] = num_map[quotrem.rem]; 43 } 44 45 args->part2_len = BUFF_LEN - buff_ind; 46 47 memcpy(args->buff, buff + buff_ind, args->part2_len); 48 49 if (args->part2_len < args->precision) { 50 args->num_leading_zeros = args->precision - args->part2_len; 51 } 52 53 if (args->precision < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { 54 buff_ind = args->width - args->part1_len - args->num_leading_zeros - args->part2_len; 55 if (buff_ind > 0) { 56 args->num_leading_zeros += buff_ind; 57 } 58 } 59 }