Browse Source

Added stpcpy and strcasestr along with some code to test them.

David McCullough 24 years ago
parent
commit
f5fc8d4321
5 changed files with 114 additions and 11 deletions
  1. 3 0
      include/string.h
  2. 10 3
      libc/string/Makefile
  3. 15 0
      libc/string/string.c
  4. 26 8
      libc/string/strstr.c
  5. 60 0
      test/string/string.c

+ 3 - 0
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));

+ 10 - 3
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

+ 15 - 0
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

+ 26 - 8
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 */
 

+ 60 - 0
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 ();