diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2014-11-30 19:58:32 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2014-11-30 19:58:32 +0100 |
commit | 54e7efbbd0e0c88d99bb6bddb82e9fc8d90eae50 (patch) | |
tree | 178f0d423d1708cbddf89c0e4c510a2022fa7eda /kernel/lib/printf.c | |
parent | bee97e0b630976b96798246a3ef4eea8964099cf (diff) | |
download | kogata-54e7efbbd0e0c88d99bb6bddb82e9fc8d90eae50.tar.gz kogata-54e7efbbd0e0c88d99bb6bddb82e9fc8d90eae50.zip |
Add debug output and a few elementary stdlib functions.
Diffstat (limited to 'kernel/lib/printf.c')
-rw-r--r-- | kernel/lib/printf.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/kernel/lib/printf.c b/kernel/lib/printf.c new file mode 100644 index 0000000..fdf474d --- /dev/null +++ b/kernel/lib/printf.c @@ -0,0 +1,105 @@ +#include <printf.h> +#include <stdarg.h> + +int snprintf(char * buff, size_t len, const char *format, ...) { + va_list ap; + + va_start(ap, format); + len = vsnprintf(buff, len, format, ap); + va_end(ap); + + return len; +} + +int vsnprintf(char *buff, size_t len, const char* format, va_list ap){ + size_t i, result; + + if (!buff || !format) + return -1; + +#define PUTCHAR(thechar) \ + do { \ + if (result < len-1) \ + *buff++ = (thechar); \ + result++; \ + } while (0) + + result = 0; + for(i = 0; format[i] != '\0' ; i++) { + if (format[i] == '%') { + i++; + switch(format[i]) { + case '%': + PUTCHAR('%'); + break; + + case 'i':; + case 'd': { + int integer = va_arg(ap,int); + int cpt2 = 0; + char buff_int[16]; + + if (integer<0) + PUTCHAR('-'); + + do { + int m10 = integer%10; + m10 = (m10 < 0)? -m10:m10; + buff_int[cpt2++] = (char)('0'+ m10); + integer = integer/10; + } while(integer != 0); + + for(cpt2 = cpt2 - 1; cpt2 >= 0; cpt2--) + PUTCHAR(buff_int[cpt2]); + + break; + } + case 'c': { + int value = va_arg(ap,int); + PUTCHAR((char)value); + break; + } + case 's': { + char *string = va_arg(ap,char *); + if (!string) + string = "(null)"; + for(; *string != '\0' ; string++) + PUTCHAR(*string); + break; + } + case 'x': { + unsigned int hexa = va_arg(ap,int); + unsigned int nb; + int j, had_nonzero = 0; + for(j = 0; j < 8; j++) + { + nb = (unsigned int)(hexa << (j*4)); + nb = (nb >> 28) & 0xf; + // Skip the leading zeros + if (nb == 0) { + if (had_nonzero) + PUTCHAR('0'); + } else { + had_nonzero = 1; + if (nb < 10) + PUTCHAR('0'+nb); + else + PUTCHAR('a'+(nb-10)); + } + } + if (!had_nonzero) + PUTCHAR('0'); + break; + } + default: + PUTCHAR('%'); + PUTCHAR(format[i]); + } + } else { + PUTCHAR(format[i]); + } + } + + *buff = '\0'; + return result; +} |