X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=bootcensus;a=blobdiff_plain;f=src%2Flibc%2Fstring.c;fp=src%2Flibc%2Fstring.c;h=4246aade0d0e43a10e1665441ceab16458bfcd5c;hp=ce3c2e7b7436010fd8025b7a1f20555a1a5cffd4;hb=81c11bdd80190ec319a82b0402173cfb65fcbf72;hpb=7dcd5071e600f8cf48174d1fddb3dba57ec9476d diff --git a/src/libc/string.c b/src/libc/string.c index ce3c2e7..4246aad 100644 --- a/src/libc/string.c +++ b/src/libc/string.c @@ -1,6 +1,6 @@ /* pcboot - bootable PC demo/game kernel -Copyright (C) 2018 John Tsiombikas +Copyright (C) 2018-2019 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,41 +16,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include - -/* -void memset(void *s, int c, size_t n) -{ - char *ptr = s; - while(n--) { - *ptr++ = c; - } -} -*/ - -/* Does the same thing as memset only with 16bit values. - * n in this case is the number of values, not the number of bytes. - */ -/* -void memset16(void *s, int c, size_t n) -{ - int16_t *ptr = s; - while(n--) { - *ptr++ = c; - } -} -*/ -/* -void *memcpy(void *dest, const void *src, size_t n) -{ - char *dptr = dest; - const char *sptr = src; - - while(n--) { - *dptr++ = *sptr++; - } - return dest; -} -*/ +#include +#include void *memmove(void *dest, const void *src, size_t n) { @@ -77,6 +44,49 @@ void *memmove(void *dest, const void *src, size_t n) return dest; } +int memcmp(void *aptr, void *bptr, size_t n) +{ + int i, startoffs, diff; + uint32_t *a32, *b32; + unsigned char *a = aptr; + unsigned char *b = bptr; + + a32 = (uint32_t*)((intptr_t)(a + 3) & 0xfffffffc); + b32 = (uint32_t*)((intptr_t)(b + 3) & 0xfffffffc); + + /* if both are aligned the same way... */ + if((startoffs = (unsigned char*)a32 - a) == (unsigned char*)b32 - b) { + /* catch-up to the 32bit alignment */ + for(i=0; i= 4) { + if(*a32 != *b32) break; + a32++; + b32++; + n -= 4; + } + + /* update byte pointers to contine with the tail */ + a = (unsigned char*)a32; + b = (unsigned char*)b32; + } + + /* we're here both for the tail-end of same-alignment buffers, or for the + * whole length of mis-aligned buffers. + */ + while(n-- > 0) { + if((diff = *a++ - *b++) != 0) { + return diff; + } + } + return 0; +} + size_t strlen(const char *s) { size_t len = 0; @@ -129,6 +139,24 @@ char *strstr(const char *str, const char *substr) return 0; } +char *strcasestr(const char *str, const char *substr) +{ + while(*str) { + const char *s1 = str; + const char *s2 = substr; + + while(*s1 && tolower(*s1) == tolower(*s2)) { + s1++; + s2++; + } + if(!*s2) { + return (char*)str; + } + str++; + } + return 0; +} + int strcmp(const char *s1, const char *s2) { while(*s1 && *s1 == *s2) { @@ -137,3 +165,93 @@ int strcmp(const char *s1, const char *s2) } return *s1 - *s2; } + +int strcasecmp(const char *s1, const char *s2) +{ + while(*s1 && tolower(*s1) == tolower(*s2)) { + s1++; + s2++; + } + return tolower(*s1) - tolower(*s2); +} + +int strncmp(const char *s1, const char *s2, int n) +{ + if(n <= 0) return 0; + + while(n-- > 0 && *s1 && *s2 && *s1 == *s2) { + s1++; + s2++; + } + + if(n <= 0) return 0; + return *s1 - *s2; +} + +int strncasecmp(const char *s1, const char *s2, int n) +{ + if(n <= 0) return 0; + + while(n-- > 0 && *s1 && *s2 && tolower(*s1) == tolower(*s2)) { + s1++; + s2++; + } + + if(n <= 0) return 0; + return tolower(*s1) - tolower(*s2); +} + +char *strcpy(char *dest, const char *src) +{ + char *dptr = dest; + while((*dptr++ = *src++)); + return dest; +} + +char *strcat(char *dest, const char *src) +{ + strcpy(dest + strlen(dest), src); + return dest; +} + +char *strncpy(char *dest, const char *src, int n) +{ + char *dptr = dest; + while(n-- > 0 && (*dptr++ = *src++)); + return dest; +} + + +static const char *errstr[] = { + "Success", + "Foo", + "Interrupted", + "Invalid", + "Child", + "Timeout", + "Out of memory", + "I/O error", + "Not found", + "Name too long", + "No space left on device", + "Permission denied", + "Not a directory", + "Is a directory", + "Does not exist", + 0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0, + "Bug" +}; + +char *strerror(int err) +{ + if(err < 0 || err > sizeof errstr / sizeof *errstr || !errstr[err]) { + return "Unknown"; + } + return (char*)errstr[err]; +}