diff options
Diffstat (limited to '03-refactor/src/printf.c')
-rw-r--r-- | 03-refactor/src/printf.c | 152 |
1 files changed, 0 insertions, 152 deletions
diff --git a/03-refactor/src/printf.c b/03-refactor/src/printf.c deleted file mode 100644 index fa7f519..0000000 --- a/03-refactor/src/printf.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "printf.h" - -enum PRINTF_TYPE { - PRINTF_TYPE_STRING = 0, - PRINTF_TYPE_INT = 1, - PRINTF_TYPE_PERCENT = 2, - PRINTF_TYPE_UNKNOWN = 999 -}; - -static enum PRINTF_TYPE get_printf_type(const char* cur) -{ - while (*cur >= 0x30 && *cur < 0x3a) ++ cur; - - if (*cur == 's') { - return PRINTF_TYPE_STRING; - } else if (*cur == 'd' || *cur == 'x' || *cur == 'X' || *cur == 'u') { - return PRINTF_TYPE_INT; - } - - return PRINTF_TYPE_UNKNOWN; -} - -static const char* printf_handle_string( - const char* fmt, - const char* next, - printf_callback_t callback, - volatile void* closure) -{ - const char* cur = next; - for (; *cur != 0; ++ cur) { - callback(closure, *cur); - } - - return fmt; -} - -static char printf_toupper(char ch) -{ - if (ch <= 0x7a && ch > 0x60) { - return ch - 0x20; - } - return ch; -} - -static const char* parse_fmt( - const char* fmt, - int* out_padding, - char* out_pad_char) -{ - if (*fmt == '0') { - *out_pad_char = '0'; - ++ fmt; - } else { - *out_pad_char = ' '; - } - int padding = 0; - while (*fmt < 0x3a && *fmt >= 0x30) { - padding *= 10; - padding += (*fmt ++) - 0x30; - } - - *out_padding = padding; - return fmt; -} - -static const char* mapping = "0123456789abcdef"; -static const char* printf_handle_int( - const char* fmt, unsigned int next, printf_callback_t callback, volatile void* closure) -{ - int base = 10; - char chars[32]; - int pos = 31; - int upper = 0; - char pad_char; - int padding; - int is_unsigned = 0; - - fmt = parse_fmt(fmt, &padding, &pad_char); - - if (*fmt == 'x' || *fmt == 'X') { - base = 16; - is_unsigned = 1; - } else if (*fmt == 'u') { - is_unsigned = 1; - } - - upper = *fmt == 'X'; - - int next_i = (int) next; - if (next_i < 0 && !is_unsigned) { - callback(closure, '-'); - next_i *= -1; - next = (unsigned) next_i; - } - - if (next == 0) { - callback(closure, '0'); - } else { - while (next > 0) { - char next_ch = mapping[next % base]; - if (upper) next_ch = printf_toupper(next_ch); - chars[pos --] = next_ch; - padding --; - next /= base; - } - - while ((padding--) > 0) { - chars[pos --] = pad_char; - } - - for (++ pos; pos < 32; ++ pos) { - callback(closure, chars[pos]); - } - } - - return fmt; -} - -void printf_format( - const char* fmt, - printf_callback_t callback, - volatile void* closure, - va_list ap) -{ - const char* cur = fmt; - - const char* next_string; - int next_int; - - for (; *cur != 0; ++ cur) { - if (*cur == '%') { - // Handle the formatting here. - ++ cur; - enum PRINTF_TYPE printf_type = get_printf_type(cur); - - switch (printf_type) { - case PRINTF_TYPE_PERCENT: - callback(closure, '%'); - break; - case PRINTF_TYPE_STRING: - next_string = va_arg(ap, const char*); - cur = printf_handle_string(cur, next_string, callback, closure); - break; - case PRINTF_TYPE_INT: - next_int = va_arg(ap, int); - cur = printf_handle_int(cur, next_int, callback, closure); - } - } else { - callback(closure, *cur); - } - } -} |