diff options
Diffstat (limited to 'src/common/libc')
-rw-r--r-- | src/common/libc/printf.c | 210 | ||||
-rw-r--r-- | src/common/libc/string.c | 3 |
2 files changed, 115 insertions, 98 deletions
diff --git a/src/common/libc/printf.c b/src/common/libc/printf.c index 0498b2d..fbebafe 100644 --- a/src/common/libc/printf.c +++ b/src/common/libc/printf.c @@ -1,6 +1,7 @@ #include <stdarg.h> #include <stdbool.h> +#include <kogata/debug.h> #include <kogata/printf.h> int snprintf(char * buff, size_t len, const char *format, ...) { @@ -13,20 +14,48 @@ int snprintf(char * buff, size_t len, const char *format, ...) { return len; } -int vsnprintf(char *buff, size_t len, const char* format, va_list ap){ - size_t i, result; +struct vsnprintf_s { + char* buff; + size_t len; + size_t i; +}; +int vsnprintf_putc_fun(int c, void* p) { + struct vsnprintf_s *s = (struct vsnprintf_s*)p; + if (s->i < s->len - 1) { + s->buff[s->i] = c; + s->i++; + return 1; + } else { + return 0; + } +} +int vsnprintf(char *buff, size_t len, const char* format, va_list arg){ if (!buff || !format) return -1; -#define PUTCHAR(thechar) \ - do { \ - if (result < len-1) \ - *buff++ = (thechar); \ - result++; \ - } while (0) + struct vsnprintf_s s; + s.buff = buff; + s.len = len; + s.i = 0; + + size_t ret = vcprintf(vsnprintf_putc_fun, &s, format, arg); + ASSERT(ret == s.i); + + buff[s.i] = 0; + return s.i; +} + +int vcprintf(int (*putc_fun)(int c, void* p), void* p, const char* format, va_list ap) { + if (!format) return -1; + + int ret = 0; +#define PUTCHAR(thechar) { int _tmp = putc_fun(thechar, p);\ + if (_tmp == 1) ret++; \ + else if (_tmp == 0) return ret; \ + else if (_tmp < 0) return _tmp; } - result = 0; + size_t i; for(i = 0; format[i] != '\0' ; i++) { if (format[i] == '%') { i++; @@ -34,111 +63,98 @@ int vsnprintf(char *buff, size_t len, const char* format, va_list ap){ int l = 0; bool spec = true; while (spec) { - switch(format[i]) { - case 'l': { - l++; - i++; - break; - } - case 'u': { - u = 1; - i++; - break; - } - default: - spec = false; + if (format[i] == 'l') { + l++; + i++; + } else if (format[i] == 'u') { + u = 1; + i++; + } else { + spec = false; } } - switch(format[i]) { - case '%': + if (format[i] == '%') { PUTCHAR('%'); - break; - case 'i':; - case 'd': { - if (u) { - // TODO - } else { - long long int integer; - if (l == 0) integer = va_arg(ap, int); - if (l == 1) integer = va_arg(ap, long int); - if (l == 2) integer = va_arg(ap, long long int); - - int cpt2 = 0; - char buff_int[32]; - - 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]); + } else if (format[i] == 'i' || format[i] == 'd') { + if (u) { + // TODO + } else { + long long int integer; + if (l == 0) integer = va_arg(ap, int); + if (l == 1) integer = va_arg(ap, long int); + if (l == 2) integer = va_arg(ap, long long int); + + int cpt2 = 0; + char buff_int[32]; + + if (integer<0) { + PUTCHAR('-'); } - break; + + 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]); } - case 'c': { + } else if (format[i] == 'c') { int value = va_arg(ap,int); PUTCHAR((char)value); break; + } else if (format[i] == 's') { + char *string = va_arg(ap,char *); + if (!string) + string = "(null)"; + for(; *string != '\0' ; string++) + PUTCHAR(*string); + } else if (format[i] == 'x') { + unsigned int hexa = va_arg(ap,int); + int had_nonzero = 0; + for(int j = 0; j < 8; j++) { + unsigned int 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)); + } + } } - 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); - int had_nonzero = 0; - for(int j = 0; j < 8; j++) { - unsigned int 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; + if (!had_nonzero) { + PUTCHAR('0'); } - case 'p': { - unsigned int hexa = va_arg(ap,int); - for (int j = 0; j < 8; j++) { - unsigned int nb = (unsigned int)(hexa << (j*4)); - nb = (nb >> 28) & 0xf; - if (nb < 10) - PUTCHAR('0'+nb); - else - PUTCHAR('a'+(nb-10)); - } - break; + } else if (format[i] == 'p') { + unsigned int hexa = va_arg(ap,int); + for (int j = 0; j < 8; j++) { + unsigned int nb = (unsigned int)(hexa << (j*4)); + nb = (nb >> 28) & 0xf; + if (nb < 10) { + PUTCHAR('0'+nb); + } else { + PUTCHAR('a'+(nb-10)); + } } - default: - PUTCHAR('%'); - PUTCHAR(format[i]); + } else { + PUTCHAR('%'); + PUTCHAR(format[i]); } } else { PUTCHAR(format[i]); } } - *buff = '\0'; - return result; + return ret; } /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libc/string.c b/src/common/libc/string.c index 4b99dda..b2c6bb8 100644 --- a/src/common/libc/string.c +++ b/src/common/libc/string.c @@ -176,8 +176,9 @@ size_t strspn(const char *s, const char *accept) { } const char *strstr(const char *haystack, const char *needle) { + int n = strlen(needle); for (const char* p = haystack; *p != 0; p++) { - if (!strcmp(p, needle)) return p; + if (!strncmp(p, needle, n)) return p; } return NULL; } |