From 7d1c355c2843a140d5c474567c690402793aaa36 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 12 Jan 2015 19:22:35 +0800 Subject: [PATCH] Usermode/libc #6 Fix string.h functions, add some more unit tests --- Usermode/Libraries/Makefile.tpl | 7 +- Usermode/Libraries/libc.so_src/Makefile | 4 +- Usermode/Libraries/libc.so_src/TEST_string.c | 35 ++++++++ Usermode/Libraries/libc.so_src/stdio.c | 6 +- Usermode/Libraries/libc.so_src/string.c | 94 +++++++++++--------- 5 files changed, 95 insertions(+), 51 deletions(-) create mode 100644 Usermode/Libraries/libc.so_src/TEST_string.c diff --git a/Usermode/Libraries/Makefile.tpl b/Usermode/Libraries/Makefile.tpl index 5e241f23..8f548bfa 100644 --- a/Usermode/Libraries/Makefile.tpl +++ b/Usermode/Libraries/Makefile.tpl @@ -43,7 +43,7 @@ else V := @ endif -.PHONY: all clean install postbuild +.PHONY: all clean install postbuild utest-build utest-run generate_exp all: _libs $(_BIN) $(_XBIN) @@ -60,16 +60,13 @@ _libs: $(HEADERS) .PHONY: utest utest-build utest-run $(UTESTS:%=runtest-%) -utest: utest-build utest-run +utest: utest-build generate_exp utest-run generate_exp: $(UTESTS:%=EXP_%.txt) - @echo > /dev/null utest-build: $(UTESTS:%=TEST_%) - @echo > /dev/null utest-run: $(UTESTS:%=runtest-%) - @echo > /dev/null $(UTESTS:%=runtest-%): runtest-%: TEST_% EXP_%.txt @echo --- [TEST] $* diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile index 40977e9c..64749b3b 100644 --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@ -29,8 +29,8 @@ endif include ../Makefile.tpl EXP_%.txt: TEST_%.native - ./$< > $@ - rm $< + @./$< > $@ + @rm $< EXP_strtoi.txt: echo -n "" > $@ diff --git a/Usermode/Libraries/libc.so_src/TEST_string.c b/Usermode/Libraries/libc.so_src/TEST_string.c new file mode 100644 index 00000000..46fcee5f --- /dev/null +++ b/Usermode/Libraries/libc.so_src/TEST_string.c @@ -0,0 +1,35 @@ +/* + */ +#include +#include + +#define ASSERT(cnd) printf("ASSERT: "#cnd" == %s\n", ((cnd) ? "pass" : "FAIL")) + +int main() +{ + ASSERT(strcmp("hello", "world") < 0); + ASSERT(strcmp("hello", "hello") == 0); + ASSERT(strcmp("wello", "hello") > 0); + ASSERT(strcmp("\xff", "\1") > 0); + ASSERT(strcmp("\1", "\xff") < 0); + ASSERT(strcmp("Hello", "hello") < 0); + + ASSERT(strncmp("hello world", "hello", 5) == 0); + + ASSERT(strcasecmp("hello", "world") < 0); + ASSERT(strcasecmp("hello", "hello") == 0); + ASSERT(strcasecmp("wello", "hello") > 0); + ASSERT(strcasecmp("\xff", "\1") > 0); + ASSERT(strcasecmp("\1", "\xff") < 0); + ASSERT(strcasecmp("Hello", "hello") == 0); + ASSERT(strcasecmp("Hello", "Hello") == 0); + ASSERT(strcasecmp("hellO", "Hello") == 0); + + + char buf[13]; + memset(buf, 0, 13); + ASSERT(buf[0] == 0); ASSERT(buf[12] == 0); + + ASSERT(memchr("\xffhello", 'x', 6) == NULL); +} + diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c index cf2e7336..55fd5213 100644 --- a/Usermode/Libraries/libc.so_src/stdio.c +++ b/Usermode/Libraries/libc.so_src/stdio.c @@ -795,13 +795,12 @@ EXPORT char *fgets(char *s, int size, FILE *fp) */ EXPORT int fputc(int c, FILE *fp) { - char ch = c; + unsigned char ch = c; return fwrite(&ch, 1, 1, fp); } EXPORT int putchar(int c) { - c &= 0xFF; return fputc(c, stdout); } @@ -811,7 +810,7 @@ EXPORT int putchar(int c) */ EXPORT int fgetc(FILE *fp) { - char ret = 0; + unsigned char ret = 0; if( fread(&ret, 1, 1, fp) != 1 ) return -1; return ret; @@ -825,7 +824,6 @@ EXPORT int getchar(void) EXPORT int puts(const char *str) { - if(!str) return 0; int len = strlen(str); diff --git a/Usermode/Libraries/libc.so_src/string.c b/Usermode/Libraries/libc.so_src/string.c index 0757c24a..ae91b13f 100644 --- a/Usermode/Libraries/libc.so_src/string.c +++ b/Usermode/Libraries/libc.so_src/string.c @@ -2,7 +2,7 @@ * AcessOS Basic C Library * string.c */ -#include +//#include #include #include #include @@ -13,20 +13,19 @@ * \fn EXPORT int strcmp(const char *s1, const char *s2) * \brief Compare two strings */ -EXPORT int strcmp(const char *s1, const char *s2) +EXPORT int strcmp(const char *_s1, const char *_s2) { - while(*s1 && *s1 == *s2) { - s1++; s2++; - } - return (int)*s1 - (int)*s2; + return strncmp(_s1, _s2, SIZE_MAX); } /** - * \fn EXPORT int strncmp(const char *s1, const char *s2) - * \brief Compare two strings + * \fn EXPORT int strncmp(const char *s1, const char *s2, size_t n) + * \brief Compare two strings, stopping after n characters */ -EXPORT int strncmp(const char *s1, const char *s2, size_t n) +EXPORT int strncmp(const char *_s1, const char *_s2, size_t n) { + const unsigned char* s1 = (const unsigned char*)_s1; + const unsigned char* s2 = (const unsigned char*)_s2; while(n && *s1 && *s1 == *s2) { s1++; s2++; @@ -38,23 +37,31 @@ EXPORT int strncmp(const char *s1, const char *s2, size_t n) return (int)*s1 - (int)*s2; } -EXPORT int strcasecmp(const char *s1, const char *s2) +EXPORT int strcasecmp(const char *_s1, const char *_s2) { - int rv; - while( (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0' ) { - s1++; s2++; - } - return rv; + return strncasecmp(_s1, _s2, SIZE_MAX); } -EXPORT int strncasecmp(const char *s1, const char *s2, size_t n) +EXPORT int strncasecmp(const char *_s1, const char *_s2, size_t n) { - int rv = 0; - if( n == 0 ) return 0; - while(n -- && (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0') { - s1++; s2++; + const unsigned char* s1 = (const unsigned char*)_s1; + const unsigned char* s2 = (const unsigned char*)_s2; + while( n-- && *s1 && *s2 ) + { + if( *s1 != *s2 ) + { + int rv; + rv = toupper(*s1) - toupper(*s2); + if(rv != 0) + return rv; + rv = tolower(*s1) - tolower(*s2); + if(rv != 0) + return rv; + } + s1 ++; + s2 ++; } - return rv; + return 0; } /** @@ -131,7 +138,8 @@ EXPORT size_t strlen(const char *str) EXPORT size_t strnlen(const char *str, size_t maxlen) { size_t len; - for( len = 0; maxlen -- && *str; str ++, len ++ ); + for( len = 0; maxlen -- && *str; str ++, len ++ ) + ; return len; } @@ -171,11 +179,12 @@ EXPORT char *strndup(const char *str, size_t maxlen) * \fn EXPORT char *strchr(char *str, int character) * \brief Locate a character in a string */ -EXPORT char *strchr(const char *str, int character) +EXPORT char *strchr(const char *_str, int character) { + const unsigned char* str = (const unsigned char*)_str; for(;*str;str++) { - if(*str == character) + if( *str == character ) return (char*)str; } return NULL; @@ -185,11 +194,10 @@ EXPORT char *strchr(const char *str, int character) * \fn EXPORT char *strrchr(char *str, int character) * \brief Locate the last occurance of a character in a string */ -EXPORT char *strrchr(const char *str, int character) +EXPORT char *strrchr(const char *_str, int character) { - int i; - i = strlen(str)-1; - while(i--) + const unsigned char* str = (const unsigned char*)_str; + for( int i = strlen(_str); i--; ) { if(str[i] == character) return (void*)&str[i]; @@ -277,6 +285,8 @@ EXPORT void *memcpy(void *__dest, const void *__src, size_t count) return __dest; } +// TODO: memccpy (POSIX defined) + /** * \fn EXPORT void *memmove(void *dest, const void *src, size_t count) * \brief Copy data in memory, avoiding overlap problems @@ -316,7 +326,7 @@ EXPORT int memcmp(const void *mem1, const void *mem2, size_t count) while(count--) { if( *p1 != *p2 ) - return *p1 - *p2; + return (int)*p1 - (int)*p2; p1 ++; p2 ++; } @@ -332,11 +342,12 @@ EXPORT int memcmp(const void *mem1, const void *mem2, size_t count) */ EXPORT void *memchr(const void *ptr, int value, size_t num) { + const unsigned char* buf = ptr; while(num--) { - if( *(const unsigned char*)ptr == (unsigned char)value ) - return (void*)ptr; - ptr ++; + if( *buf == (unsigned char)value ) + return (void*)buf; + buf ++; } return NULL; } @@ -344,12 +355,13 @@ EXPORT void *memchr(const void *ptr, int value, size_t num) EXPORT size_t strcspn(const char *haystack, const char *reject) { size_t ret = 0; - int i; while( *haystack ) { - for( i = 0; reject[i] && reject[i] == *haystack; i ++ ); - - if( reject[i] ) return ret; + for( int i = 0; reject[i]; i ++ ) + { + if( reject[i] == *haystack ) + return ret; + } ret ++; } return ret; @@ -358,12 +370,13 @@ EXPORT size_t strcspn(const char *haystack, const char *reject) EXPORT size_t strspn(const char *haystack, const char *accept) { size_t ret = 0; - int i; while( *haystack ) { - for( i = 0; accept[i] && accept[i] == *haystack; i ++ ); - - if( !accept[i] ) return ret; + for( int i = 0; accept[i]; i ++ ) + { + if( accept[i] != *haystack ) + return ret; + } ret ++; } return ret; @@ -378,6 +391,7 @@ EXPORT char *strpbrk(const char *haystack, const char *accept) if( accept[i] == *haystack ) return (char*)haystack; } + haystack ++; } return NULL; } -- 2.20.1