summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid McCullough <davidm@snapgear.com>2001-07-04 11:29:02 +0000
committerDavid McCullough <davidm@snapgear.com>2001-07-04 11:29:02 +0000
commitf5fc8d4321de6a8cd913bafde705993d96a5e820 (patch)
tree089bb21da63f63a76a4534cbc040aea854d10cb1
parent0d85794e9b8a873a44a373d4936c5c26e1a574c9 (diff)
Added stpcpy and strcasestr along with some code to test them.
-rw-r--r--include/string.h3
-rw-r--r--libc/string/Makefile13
-rw-r--r--libc/string/string.c15
-rw-r--r--libc/string/strstr.c34
-rw-r--r--test/string/string.c60
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 <config.h>
@@ -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 <ctype.h>
+#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
@@ -140,6 +140,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)
{
it = "strcat";
@@ -443,6 +472,33 @@ test_strstr (void)
}
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)
{
it = "strspn";
@@ -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 ();