aboutsummaryrefslogtreecommitdiff
path: root/src/common/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/libc')
-rw-r--r--src/common/libc/printf.c210
-rw-r--r--src/common/libc/string.c3
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;
}