diff --git a/library/string.c b/library/string.c new file mode 100644 index 0000000..4f32f5b --- /dev/null +++ b/library/string.c @@ -0,0 +1,307 @@ +/* +Copyright (C) 2015-2019 The University of Notre Dame +This software is distributed under the GNU General Public License. +See the file LICENSE for details. +*/ + +#include "kernel/types.h" +#include "kernel/ascii.h" +#include "library/malloc.h" +#include "library/string.h" +#include "library/malloc.h" +#include "stdarg.h" + +void strcpy(char *d, const char *s) +{ + while(*s) { + *d++ = *s++; + } + *d = 0; +} + +void strncpy(char *d, const char *s, unsigned length) +{ + while(*s && length--) { + *d++ = *s++; + } + *d = 0; +} + +char * strdup(const char *s) +{ + char * d = (char *)malloc((strlen(s)+1) * sizeof(char)); + char * tmp = d; + while(*s) { + *tmp++ = *s++; + } + *tmp = 0; + return d; +} + +int strcmp(const char *a, const char *b) +{ + while(1) { + if(*a < *b) { + return -1; + } else if(*a > *b) { + return 1; + } else if(*a == 0) { + return 0; + } else { + a++; + b++; + } + } +} + +int strncmp(const char *a, const char *b, unsigned length) +{ + while(length > 0) { + if(*a < *b) { + return -1; + } else if(*a > *b) { + return 1; + } else if(*a == 0) { + return 0; + } else { + a++; + b++; + length--; + } + } + return 0; +} + +unsigned strlen(const char *s) +{ + unsigned len = 0; + while(*s) { + len++; + s++; + } + return len; +} + +char *strrev(char *s) +{ + unsigned start = 0; + unsigned end = strlen(s) - 1; + char swap; + + while(start < end) { + swap = s[start]; + s[start] = s[end]; + s[end] = swap; + + start++; + end--; + } + + return s; +} + +char *strcat(char *d, const char *s) +{ + strcpy(d + strlen(d), s); + return d; +} + +const char *strchr(const char *s, char ch) +{ + while(*s) { + if(*s == ch) + return s; + s++; + } + return 0; +} + +char *strtok(char *s, const char *delim) +{ + static char *oldword = 0; + char *word; + + if(!s) + s = oldword; + + while(*s && strchr(delim, *s)) + s++; + + if(!*s) { + oldword = s; + return 0; + } + + word = s; + while(*s && !strchr(delim, *s)) + s++; + + if(*s) { + *s = 0; + oldword = s + 1; + } else { + oldword = s; + } + + return word; +} + +int str2int(const char *s, int *d) +{ + int val = 0; + for(; *s; ++s) { + val *= 10; + if(*s > ASCII_9 || *s < ASCII_0) { + return 0; + } + val += (*s - '0'); + } + *d = val; + return 1; +} + +void memset(void *vd, char value, unsigned length) +{ + char *d = vd; + while(length) { + *d = value; + length--; + d++; + } +} + +void memcpy(void *vd, const void *vs, unsigned length) +{ + char *d = vd; + const char *s = vs; + while(length) { + *d = *s; + d++; + s++; + length--; + } +} + +extern void printf_putstring(const char *str); +extern void printf_putchar(char c); + +static void printf_puthexdigit(uint8_t i) +{ + if(i < 10) { + printf_putchar('0' + i); + } else { + printf_putchar('a' + i - 10); + } +} + +static void printf_puthex(uint32_t i) +{ + int j; + for(j = 28; j >= 0; j = j - 4) { + printf_puthexdigit((i >> j) & 0x0f); + } +} + +static void printf_putint(int32_t i) +{ + int f, d; + if(i < 0 && i != 0) { + printf_putchar('-'); + i = -i; + } + + f = 1; + while((i / f) >= 10) { + f *= 10; + } + while(f > 0) { + d = i / f; + printf_putchar('0' + d); + i = i - d * f; + f = f / 10; + } +} + +static void printf_putuint(uint32_t u) +{ + int f, d; + f = 1; + while((u / f) >= 10) { + f *= 10; + } + while(f > 0) { + d = u / f; + printf_putchar('0' + d); + u = u - d * f; + f = f / 10; + } +} + +void printf(const char *s, ...) +{ + va_list args; + + uint32_t u; + int32_t i; + char *str; + + va_start(args, s); + + while(*s) { + if(*s != '%') { + printf_putchar(*s); + } else { + s++; + switch (*s) { + case 'd': + i = va_arg(args, int32_t); + printf_putint(i); + break; + case 'u': + u = va_arg(args, uint32_t); + printf_putuint(u); + break; + case 'x': + u = va_arg(args, uint32_t); + printf_puthex(u); + break; + case 's': + str = va_arg(args, char *); + printf_putstring(str); + break; + case 'c': + u = va_arg(args, int32_t); + printf_putchar(u); + break; + case 0: + return; + break; + default: + printf_putchar(*s); + break; + } + } + s++; + } + va_end(args); +} + +char *uint_to_string(uint32_t u, char *s) +{ + uint32_t f, d, i; + + f = 1; + i = 0; + while((u / (f * 10)) > 0) { + f *= 10; + } + while(f > 0) { + d = u / f; + s[i] = '0' + d; + u = u % f; + f = f / 10; + i++; + } + s[i] = 0; + return s; +}