From f5fc8d4321de6a8cd913bafde705993d96a5e820 Mon Sep 17 00:00:00 2001 From: David McCullough Date: Wed, 4 Jul 2001 11:29:02 +0000 Subject: Added stpcpy and strcasestr along with some code to test them. --- include/string.h | 3 +++ libc/string/Makefile | 13 +++++++++--- libc/string/string.c | 15 +++++++++++++ libc/string/strstr.c | 34 ++++++++++++++++++++++------- test/string/string.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 11 deletions(-) diff --git a/include/string.h b/include/string.h index d449f0bda..939b1a4b5 100644 --- a/include/string.h +++ b/include/string.h @@ -19,6 +19,8 @@ extern char *strncat __P ((char *__restrict __dest, /* Copy SRC to DEST. */ extern char *strcpy __P ((char *__restrict __dest, __const char *__restrict __src)); +extern char *stpcpy __P ((char *__restrict __dest, + __const char *__restrict __src)); /* Copy no more than N characters of SRC to DEST. */ extern char *strncpy __P ((char *__restrict __dest, __const char *__restrict __src, size_t __n)); @@ -90,6 +92,7 @@ extern char *strsep __P ((char **__restrict __stringp, __const char *__restrict __delim)); /* Find the first occurrence of NEEDLE in HAYSTACK. */ extern char *strstr __P ((__const char *__haystack, __const char *__needle)); +extern char *strcasestr __P((__const char *__haystack, __const char *__needle)); /* Divide S into tokens separated by characters in DELIM. */ extern char *strtok __P ((char *__restrict __s, __const char *__restrict __delim)); diff --git a/libc/string/Makefile b/libc/string/Makefile index 488c69549..c9b70829e 100644 --- a/libc/string/Makefile +++ b/libc/string/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)Rules.mak MSRC=string.c MOBJ=strlen.o strcat.o strcpy.o strchr.o strcmp.o strncat.o strncpy.o \ strncmp.o strrchr.o strdup.o memcpy.o memccpy.o memset.o \ - memmove.o memcmp.o memchr.o ffs.o strnlen.o strxfrm.o + memmove.o memcmp.o memchr.o ffs.o strnlen.o strxfrm.o stpcpy.o ifeq ($(HAS_LOCALE),true) MOBJ += strcoll.o @@ -35,11 +35,14 @@ endif MSRC1=strsignal.c MOBJ1=strsignal.o psignal.o -CSRC=strpbrk.c strsep.c strstr.c strtok.c strtok_r.c strcspn.c \ +MSRC2=strstr.c +MOBJ2=strstr.o strcasestr.o + +CSRC=strpbrk.c strsep.c strtok.c strtok_r.c strcspn.c \ strspn.c strcasecmp.c strncasecmp.c strerror.c bcopy.c bzero.c \ bcmp.c sys_errlist.c COBJS=$(patsubst %.c,%.o, $(CSRC)) -OBJS=$(MOBJ) $(MOBJ1) $(COBJS) +OBJS=$(MOBJ) $(MOBJ1) $(MOBJ2) $(COBJS) all: $(OBJS) $(LIBC) @@ -52,6 +55,10 @@ $(MOBJ): $(MSRC) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o +$(MOBJ2): $(MSRC2) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(STRIPTOOL) -x -R .note -R .comment $*.o + $(MOBJ1): $(MSRC1) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o diff --git a/libc/string/string.c b/libc/string/string.c index 27649b43b..0a1ced8b3 100644 --- a/libc/string/string.c +++ b/libc/string/string.c @@ -58,6 +58,21 @@ char *strcpy(char *dst, const char *src) } #endif +/********************** Function stpcpy ************************************/ + +#ifdef L_stpcpy +char *stpcpy(char *dst, const char *src) +{ + register char *ptr = dst; + + while (*src) + *dst++ = *src++; + *dst = '\0'; + + return dst; +} +#endif + /********************** Function strcmp ************************************/ #ifdef L_strcmp diff --git a/libc/string/strstr.c b/libc/string/strstr.c index b1890559b..6742e69cb 100644 --- a/libc/string/strstr.c +++ b/libc/string/strstr.c @@ -25,6 +25,7 @@ * as much fun trying to understand it, as I had to write it :-). * * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ +/* added strcasestr support, davidm@lineo.com */ #if HAVE_CONFIG_H # include @@ -36,9 +37,26 @@ typedef unsigned chartype; +#if defined(L_strstr) + +#define VAL(x) (x) +#define FUNC strstr #undef strstr -char *strstr( const char *phaystack, const char *pneedle) +#elif defined(L_strcasestr) + +#include +#define VAL(x) tolower(x) +#define FUNC strcasestr +#undef strcasestr + +#else + +#error "No target function defined." + +#endif + +char * FUNC ( const char *phaystack, const char *pneedle) { register const unsigned char *haystack, *needle; register chartype b, c; @@ -54,7 +72,7 @@ char *strstr( const char *phaystack, const char *pneedle) if (c == '\0') goto ret0; } - while (c != b); + while (VAL(c) != VAL(b)); c = *++needle; if (c == '\0') @@ -70,39 +88,39 @@ char *strstr( const char *phaystack, const char *pneedle) a = *++haystack; if (a == '\0') goto ret0; - if (a == b) + if (VAL(a) == VAL(b)) break; a = *++haystack; if (a == '\0') goto ret0; shloop:} - while (a != b); + while (VAL(a) != VAL(b)); jin:a = *++haystack; if (a == '\0') goto ret0; - if (a != c) + if (VAL(a) != VAL(c)) goto shloop; rhaystack = haystack-- + 1; rneedle = needle; a = *rneedle; - if (*rhaystack == a) + if (VAL(*rhaystack) == VAL(a)) do { if (a == '\0') goto foundneedle; ++rhaystack; a = *++needle; - if (*rhaystack != a) + if (VAL(*rhaystack) != VAL(a)) break; if (a == '\0') goto foundneedle; ++rhaystack; a = *++needle; } - while (*rhaystack == a); + while (VAL(*rhaystack) == VAL(a)); needle = rneedle; /* took the register-poor approach */ diff --git a/test/string/string.c b/test/string/string.c index 43a1108b3..2f281e18c 100644 --- a/test/string/string.c +++ b/test/string/string.c @@ -139,6 +139,35 @@ test_strcpy (void) } } +void +test_stpcpy (void) +{ + int i; + it = "stpcpy"; + check (stpcpy (one, "abcd") == one+4, 1); /* Returned value. */ + equal (one, "abcd", 2); /* Basic test. */ + + (void) stpcpy (one, "x"); + equal (one, "x", 3); /* Writeover. */ + equal (one+2, "cd", 4); /* Wrote too much? */ + + (void) stpcpy (two, "hi there"); + (void) stpcpy (one, two); + equal (one, "hi there", 5); /* Basic test encore. */ + equal (two, "hi there", 6); /* Stomped on source? */ + + (void) stpcpy (one, ""); + equal (one, "", 7); /* Boundary condition. */ + + for (i = 0; i < 16; i++) + { + (void) stpcpy (one + i, "hi there"); /* Unaligned destination. */ + equal (one + i, "hi there", 8 + (i * 2)); + (void) stpcpy (two, one + i); /* Unaligned source. */ + equal (two, "hi there", 9 + (i * 2)); + } +} + void test_strcat (void) { @@ -442,6 +471,33 @@ test_strstr (void) check(strstr(one, "bbca") == one+1, 16); /* With overlap. */ } +void +test_strcasestr (void) +{ + it = "strcasestr"; + check(strcasestr("abcd", "z") == NULL, 1); /* Not found. */ + check(strcasestr("abcd", "abx") == NULL, 2); /* Dead end. */ + (void) strcpy(one, "aBcD"); + check(strcasestr(one, "c") == one+2, 3); /* Basic test. */ + check(strcasestr(one, "bc") == one+1, 4); /* Multichar. */ + check(strcasestr(one, "d") == one+3, 5); /* End of string. */ + check(strcasestr(one, "cd") == one+2, 6); /* Tail of string. */ + check(strcasestr(one, "abc") == one, 7); /* Beginning. */ + check(strcasestr(one, "abcd") == one, 8); /* Exact match. */ + check(strcasestr(one, "abcde") == NULL, 9); /* Too long. */ + check(strcasestr(one, "de") == NULL, 10); /* Past end. */ + check(strcasestr(one, "") == one, 11); /* Finding empty. */ + (void) strcpy(one, "aBaBa"); + check(strcasestr(one, "ba") == one+1, 12); /* Finding first. */ + (void) strcpy(one, ""); + check(strcasestr(one, "b") == NULL, 13); /* Empty string. */ + check(strcasestr(one, "") == one, 14); /* Empty in empty string. */ + (void) strcpy(one, "BcBcA"); + check(strcasestr(one, "bca") == one+2, 15); /* False start. */ + (void) strcpy(one, "BbBcABBcA"); + check(strcasestr(one, "bbca") == one+1, 16); /* With overlap. */ +} + void test_strspn (void) { @@ -913,6 +969,9 @@ main (void) /* Test strcpy next because we need it to set up other tests. */ test_strcpy (); + /* stpcpy */ + test_stpcpy (); + /* strcat. */ test_strcat (); @@ -945,6 +1004,7 @@ main (void) /* strstr - somewhat like strchr. */ test_strstr (); + test_strcasestr (); /* strspn. */ test_strspn (); -- cgit v1.2.3