aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--libsimple/strn.h65
l---------man/strncasechr.3libsimple1
l---------man/strncasechrnul.3libsimple1
l---------man/strncasecmpnul.3libsimple1
l---------man/strncaseends.3libsimple1
l---------man/strncaseeq.3libsimple1
l---------man/strncaseeqlen.3libsimple1
l---------man/strncaseeqnul.3libsimple1
l---------man/strncasestarts.3libsimple1
l---------man/strncasestr.3libsimple1
l---------man/strnchr.3libsimple1
l---------man/strnchrnul.3libsimple1
l---------man/strncmpnul.3libsimple1
l---------man/strnend.3libsimple1
l---------man/strnends.3libsimple1
l---------man/strneq.3libsimple1
l---------man/strneqlen.3libsimple1
l---------man/strneqnul.3libsimple1
l---------man/strnstarts.3libsimple1
l---------man/strnstr.3libsimple1
l---------man/strrncasechr.3libsimple1
l---------man/strrncaseeqlen.3libsimple1
l---------man/strrncasestr.3libsimple1
l---------man/strrnchr.3libsimple1
l---------man/strrneqlen.3libsimple1
l---------man/strrnstr.3libsimple1
-rw-r--r--strncasechr.c43
-rw-r--r--strncasechrnul.c43
-rw-r--r--strnchr.c42
-rw-r--r--strnchrnul.c42
-rw-r--r--strnend.c38
-rw-r--r--strrncasechr.c48
-rw-r--r--strrnchr.c47
34 files changed, 395 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 4749ada..dbf37b1 100644
--- a/Makefile
+++ b/Makefile
@@ -94,12 +94,19 @@ OBJ =\
strchrnul.o\
strends.o\
streqlen.o\
+ strncasechr.o\
+ strncasechrnul.o\
strncasestr.o\
+ strnchr.o\
+ strnchrnul.o\
strndup.o\
+ strnend.o\
strnstr.o\
strrcasechr.o\
strrcasestr.o\
+ strrncasechr.o\
strrncasestr.o\
+ strrnchr.o\
strrnstr.o\
strrstr.o\
strstarts.o\
diff --git a/libsimple/strn.h b/libsimple/strn.h
index 90b2118..66b1e10 100644
--- a/libsimple/strn.h
+++ b/libsimple/strn.h
@@ -1,10 +1,6 @@
/* See LICENSE file for copyright and license details. */
-/* TODO strncasechr */
-/* TODO strncasechrnul */
-/* TODO strrncasechr */
-/* TODO strnchrnul */
-/* TODO strnend */
+
/* TODO strnstarts */
/* TODO strncasestarts */
/* TODO strnends */
@@ -14,30 +10,84 @@
/* TODO strrneqlen */
/* TODO strrncaseeqlen */
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+char *libsimple_strnchr(const char *, int, size_t);
+#ifndef strnchr
+# define strnchr libsimple_strnchr
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+char *libsimple_strncasechr(const char *, int, size_t);
+#ifndef strncasechr
+# define strncasechr libsimple_strncasechr
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __returns_nonnull__, __warn_unused_result__)))
+char *libsimple_strnchrnul(const char *, int, size_t);
+#ifndef strnchrnul
+# define strnchrnul libsimple_strnchrnul
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __returns_nonnull__, __warn_unused_result__)))
+char *libsimple_strncasechrnul(const char *, int, size_t);
+#ifndef strncasechrnul
+# define strncasechrnul libsimple_strncasechrnul
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+char *libsimple_strrnchr(const char *, int, size_t);
+#ifndef strrnchr
+# define strrnchr libsimple_strrnchr
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+char *libsimple_strrncasechr(const char *, int, size_t);
+#ifndef strrncasechr
+# define strrncasechr libsimple_strrncasechr
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __returns_nonnull__, __warn_unused_result__)))
+char *libsimple_strnend(const char *, size_t);
+#ifndef strnend
+# define strnend libsimple_strnend
+#endif
+
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strnstr(const char *, const char *, size_t);
#ifndef strnstr
# define strnstr libsimple_strnstr
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strrnstr(const char *, const char *, size_t);
#ifndef strrnstr
# define strrnstr libsimple_strrnstr
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strncasestr(const char *, const char *, size_t);
#ifndef strncasestr
# define strncasestr libsimple_strncasestr
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strrncasestr(const char *, const char *, size_t);
#ifndef strrncasestr
# define strrncasestr libsimple_strrncasestr
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strncmpnul(const char *__a, const char *__b, size_t __n)
{ return (!__a || !__b) ? !__b - !__a : strncmp(__a, __b, __n); }
@@ -45,6 +95,7 @@ static inline int libsimple_strncmpnul(const char *__a, const char *__b, size_t
# define strncmpnul libsimple_strncmpnul
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strncasecmpnul(const char *__a, const char *__b, size_t __n)
{ return (!__a || !__b) ? !__b - !__a : strncasecmp(__a, __b, __n); }
@@ -52,6 +103,7 @@ static inline int libsimple_strncasecmpnul(const char *__a, const char *__b, siz
# define strncasecmpnul libsimple_strncasecmpnul
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
static inline int libsimple_strneq(const char *__a, const char *__b, size_t __n)
{ return !strncmp(__a, __b, __n); }
@@ -59,6 +111,7 @@ static inline int libsimple_strneq(const char *__a, const char *__b, size_t __n)
# define strneq libsimple_strneq
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strneqnul(const char *__a, const char *__b, size_t __n)
{ return !strncmpnul(__a, __b, __n); }
@@ -66,6 +119,7 @@ static inline int libsimple_strneqnul(const char *__a, const char *__b, size_t _
# define strneqnul libsimple_strneqnul
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
static inline int libsimple_strncaseeq(const char *__a, const char *__b, size_t __n)
{ return !strncasecmp(__a, __b, __n); }
@@ -73,6 +127,7 @@ static inline int libsimple_strncaseeq(const char *__a, const char *__b, size_t
# define strncaseeq libsimple_strncaseeq
#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strncaseeqnul(const char *__a, const char *__b, size_t __n)
{ return !strncasecmpnul(__a, __b, __n); }
diff --git a/man/strncasechr.3libsimple b/man/strncasechr.3libsimple
new file mode 120000
index 0000000..2d09610
--- /dev/null
+++ b/man/strncasechr.3libsimple
@@ -0,0 +1 @@
+libsimple_strncasechr.3 \ No newline at end of file
diff --git a/man/strncasechrnul.3libsimple b/man/strncasechrnul.3libsimple
new file mode 120000
index 0000000..60448c9
--- /dev/null
+++ b/man/strncasechrnul.3libsimple
@@ -0,0 +1 @@
+libsimple_strncasechrnul.3 \ No newline at end of file
diff --git a/man/strncasecmpnul.3libsimple b/man/strncasecmpnul.3libsimple
new file mode 120000
index 0000000..a2ed681
--- /dev/null
+++ b/man/strncasecmpnul.3libsimple
@@ -0,0 +1 @@
+libsimple_strncasecmpnul.3 \ No newline at end of file
diff --git a/man/strncaseends.3libsimple b/man/strncaseends.3libsimple
new file mode 120000
index 0000000..8e45624
--- /dev/null
+++ b/man/strncaseends.3libsimple
@@ -0,0 +1 @@
+libsimple_strncaseends.3 \ No newline at end of file
diff --git a/man/strncaseeq.3libsimple b/man/strncaseeq.3libsimple
new file mode 120000
index 0000000..f0ea42f
--- /dev/null
+++ b/man/strncaseeq.3libsimple
@@ -0,0 +1 @@
+libsimple_strncaseeq.3 \ No newline at end of file
diff --git a/man/strncaseeqlen.3libsimple b/man/strncaseeqlen.3libsimple
new file mode 120000
index 0000000..18e46e0
--- /dev/null
+++ b/man/strncaseeqlen.3libsimple
@@ -0,0 +1 @@
+libsimple_strncaseeqlen.3 \ No newline at end of file
diff --git a/man/strncaseeqnul.3libsimple b/man/strncaseeqnul.3libsimple
new file mode 120000
index 0000000..3d50ddc
--- /dev/null
+++ b/man/strncaseeqnul.3libsimple
@@ -0,0 +1 @@
+libsimple_strncaseeqnul.3 \ No newline at end of file
diff --git a/man/strncasestarts.3libsimple b/man/strncasestarts.3libsimple
new file mode 120000
index 0000000..50f228e
--- /dev/null
+++ b/man/strncasestarts.3libsimple
@@ -0,0 +1 @@
+libsimple_strncasestarts.3 \ No newline at end of file
diff --git a/man/strncasestr.3libsimple b/man/strncasestr.3libsimple
new file mode 120000
index 0000000..035c71a
--- /dev/null
+++ b/man/strncasestr.3libsimple
@@ -0,0 +1 @@
+libsimple_strncasestr.3 \ No newline at end of file
diff --git a/man/strnchr.3libsimple b/man/strnchr.3libsimple
new file mode 120000
index 0000000..43c29bf
--- /dev/null
+++ b/man/strnchr.3libsimple
@@ -0,0 +1 @@
+libsimple_strnchr.3 \ No newline at end of file
diff --git a/man/strnchrnul.3libsimple b/man/strnchrnul.3libsimple
new file mode 120000
index 0000000..60b8881
--- /dev/null
+++ b/man/strnchrnul.3libsimple
@@ -0,0 +1 @@
+libsimple_strnchrnul.3 \ No newline at end of file
diff --git a/man/strncmpnul.3libsimple b/man/strncmpnul.3libsimple
new file mode 120000
index 0000000..fa439bb
--- /dev/null
+++ b/man/strncmpnul.3libsimple
@@ -0,0 +1 @@
+libsimple_strncmpnul.3 \ No newline at end of file
diff --git a/man/strnend.3libsimple b/man/strnend.3libsimple
new file mode 120000
index 0000000..9f728bf
--- /dev/null
+++ b/man/strnend.3libsimple
@@ -0,0 +1 @@
+libsimple_strnend.3 \ No newline at end of file
diff --git a/man/strnends.3libsimple b/man/strnends.3libsimple
new file mode 120000
index 0000000..a8a14ee
--- /dev/null
+++ b/man/strnends.3libsimple
@@ -0,0 +1 @@
+libsimple_strnends.3 \ No newline at end of file
diff --git a/man/strneq.3libsimple b/man/strneq.3libsimple
new file mode 120000
index 0000000..5c125b0
--- /dev/null
+++ b/man/strneq.3libsimple
@@ -0,0 +1 @@
+libsimple_strneq.3 \ No newline at end of file
diff --git a/man/strneqlen.3libsimple b/man/strneqlen.3libsimple
new file mode 120000
index 0000000..82589f6
--- /dev/null
+++ b/man/strneqlen.3libsimple
@@ -0,0 +1 @@
+libsimple_strneqlen.3 \ No newline at end of file
diff --git a/man/strneqnul.3libsimple b/man/strneqnul.3libsimple
new file mode 120000
index 0000000..d0141dc
--- /dev/null
+++ b/man/strneqnul.3libsimple
@@ -0,0 +1 @@
+libsimple_strneqnul.3 \ No newline at end of file
diff --git a/man/strnstarts.3libsimple b/man/strnstarts.3libsimple
new file mode 120000
index 0000000..1e8f08a
--- /dev/null
+++ b/man/strnstarts.3libsimple
@@ -0,0 +1 @@
+libsimple_strnstarts.3 \ No newline at end of file
diff --git a/man/strnstr.3libsimple b/man/strnstr.3libsimple
new file mode 120000
index 0000000..03b83b7
--- /dev/null
+++ b/man/strnstr.3libsimple
@@ -0,0 +1 @@
+libsimple_strnstr.3 \ No newline at end of file
diff --git a/man/strrncasechr.3libsimple b/man/strrncasechr.3libsimple
new file mode 120000
index 0000000..6316f08
--- /dev/null
+++ b/man/strrncasechr.3libsimple
@@ -0,0 +1 @@
+libsimple_strrncasechr.3 \ No newline at end of file
diff --git a/man/strrncaseeqlen.3libsimple b/man/strrncaseeqlen.3libsimple
new file mode 120000
index 0000000..28bc354
--- /dev/null
+++ b/man/strrncaseeqlen.3libsimple
@@ -0,0 +1 @@
+libsimple_strrncaseeqlen.3 \ No newline at end of file
diff --git a/man/strrncasestr.3libsimple b/man/strrncasestr.3libsimple
new file mode 120000
index 0000000..86107aa
--- /dev/null
+++ b/man/strrncasestr.3libsimple
@@ -0,0 +1 @@
+libsimple_strrncasestr.3 \ No newline at end of file
diff --git a/man/strrnchr.3libsimple b/man/strrnchr.3libsimple
new file mode 120000
index 0000000..de1494a
--- /dev/null
+++ b/man/strrnchr.3libsimple
@@ -0,0 +1 @@
+libsimple_strrnchr.3 \ No newline at end of file
diff --git a/man/strrneqlen.3libsimple b/man/strrneqlen.3libsimple
new file mode 120000
index 0000000..b255358
--- /dev/null
+++ b/man/strrneqlen.3libsimple
@@ -0,0 +1 @@
+libsimple_strrneqlen.3 \ No newline at end of file
diff --git a/man/strrnstr.3libsimple b/man/strrnstr.3libsimple
new file mode 120000
index 0000000..d493079
--- /dev/null
+++ b/man/strrnstr.3libsimple
@@ -0,0 +1 @@
+libsimple_strrnstr.3 \ No newline at end of file
diff --git a/strncasechr.c b/strncasechr.c
new file mode 100644
index 0000000..9ba2b93
--- /dev/null
+++ b/strncasechr.c
@@ -0,0 +1,43 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strncasechr(const char *s_, int c, size_t n)
+{
+ char *s = *(char **)(void *)&s_;
+ char *end = &s[n];
+ c = tolower(c);
+ for (; s != end && *s && tolower(*s) != c; s++);
+ return s == end ? NULL : tolower(*s) == c ? s : NULL;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strncasechr("abcABCabcABC", 'a', 13), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechr("abcABCabcABC", 'c', 13), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechr("abcABCabcABC", 'A', 13), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechr("abcABCabcABC", 'C', 13), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechr("ABCabcABCabc", 'a', 13), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_strncasechr("ABCabcABCabc", 'c', 13), "CabcABCabc"));
+ assert(!strcmpnul(libsimple_strncasechr("ABCabcABCabc", 'A', 13), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_strncasechr("ABCabcABCabc", 'C', 13), "CabcABCabc"));
+ assert(!libsimple_strncasechr("abcABCabcABC", 'x', 13));
+ assert(!libsimple_strncasechr("abcABCabcABC", 'x', 20));
+ assert(!strcmpnul(libsimple_strncasechr("abcABCabcABC", '\0', 13), ""));
+ assert(!strcmpnul(libsimple_strncasechr("abcABCabcABC", '\0', 20), ""));
+ assert(!libsimple_strncasechr("abcABCabcABC", '\0', 3));
+ assert(!libsimple_strncasechr("abcdef", 'd', 3));
+ assert(!libsimple_strncasechr("abcdef", 'e', 3));
+ assert(!strcmpnul(libsimple_strncasechr("123123", '1', 7), "123123"));
+ assert(!strcmpnul(libsimple_strncasechr("123123", '3', 7), "3123"));
+ return 0;
+}
+
+#endif
diff --git a/strncasechrnul.c b/strncasechrnul.c
new file mode 100644
index 0000000..608f097
--- /dev/null
+++ b/strncasechrnul.c
@@ -0,0 +1,43 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strncasechrnul(const char *s_, int c, size_t n)
+{
+ char *s = *(char **)(void *)&s_;
+ char *end = &s[n];
+ c = tolower(c);
+ for (; s != end && *s && tolower(*s) != c; s++);
+ return s;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", 'a', 13), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", 'c', 13), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", 'A', 13), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", 'C', 13), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechrnul("ABCabcABCabc", 'a', 13), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_strncasechrnul("ABCabcABCabc", 'c', 13), "CabcABCabc"));
+ assert(!strcmpnul(libsimple_strncasechrnul("ABCabcABCabc", 'A', 13), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_strncasechrnul("ABCabcABCabc", 'C', 13), "CabcABCabc"));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", 'x', 13), ""));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", 'x', 20), ""));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", '\0', 13), ""));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", '\0', 20), ""));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcABCabcABC", '\0', 3), "ABCabcABC"));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcdef", 'd', 3), "def"));
+ assert(!strcmpnul(libsimple_strncasechrnul("abcdef", 'e', 3), "def"));
+ assert(!strcmpnul(libsimple_strncasechrnul("123123", '1', 7), "123123"));
+ assert(!strcmpnul(libsimple_strncasechrnul("123123", '3', 7), "3123"));
+ return 0;
+}
+
+#endif
diff --git a/strnchr.c b/strnchr.c
new file mode 100644
index 0000000..e03df86
--- /dev/null
+++ b/strnchr.c
@@ -0,0 +1,42 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strnchr(const char *s_, int c_, size_t n)
+{
+ char *s = *(char **)(void *)&s_, c = (char)c_;
+ char *end = &s[n];
+ for (; s != end && *s && *s != c; s++);
+ return s == end ? NULL : *s == c ? s : NULL;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strnchr("abcABCabcABC", 'a', 13), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_strnchr("abcABCabcABC", 'c', 13), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_strnchr("abcABCabcABC", 'A', 13), "ABCabcABC"));
+ assert(!strcmpnul(libsimple_strnchr("abcABCabcABC", 'C', 13), "CabcABC"));
+ assert(!strcmpnul(libsimple_strnchr("ABCabcABCabc", 'a', 13), "abcABCabc"));
+ assert(!strcmpnul(libsimple_strnchr("ABCabcABCabc", 'c', 13), "cABCabc"));
+ assert(!strcmpnul(libsimple_strnchr("ABCabcABCabc", 'A', 13), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_strnchr("ABCabcABCabc", 'C', 13), "CabcABCabc"));
+ assert(!libsimple_strnchr("abcABCabcABC", 'x', 13));
+ assert(!libsimple_strnchr("abcABCabcABC", 'x', 20));
+ assert(!strcmpnul(libsimple_strnchr("abcABCabcABC", '\0', 13), ""));
+ assert(!strcmpnul(libsimple_strnchr("abcABCabcABC", '\0', 20), ""));
+ assert(!libsimple_strnchr("abcABCabcABC", '\0', 3));
+ assert(!libsimple_strnchr("abcdef", 'd', 3));
+ assert(!libsimple_strnchr("abcdef", 'e', 3));
+ assert(!strcmpnul(libsimple_strnchr("123123", '1', 7), "123123"));
+ assert(!strcmpnul(libsimple_strnchr("123123", '3', 7), "3123"));
+ return 0;
+}
+
+#endif
diff --git a/strnchrnul.c b/strnchrnul.c
new file mode 100644
index 0000000..4e7e1b8
--- /dev/null
+++ b/strnchrnul.c
@@ -0,0 +1,42 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strnchrnul(const char *s_, int c_, size_t n)
+{
+ char *s = *(char **)(void *)&s_, c = (char)c_;
+ char *end = &s[n];
+ for (; s != end && *s && *s != c; s++);
+ return s;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", 'a', 13), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", 'c', 13), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", 'A', 13), "ABCabcABC"));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", 'C', 13), "CabcABC"));
+ assert(!strcmpnul(libsimple_strnchrnul("ABCabcABCabc", 'a', 13), "abcABCabc"));
+ assert(!strcmpnul(libsimple_strnchrnul("ABCabcABCabc", 'c', 13), "cABCabc"));
+ assert(!strcmpnul(libsimple_strnchrnul("ABCabcABCabc", 'A', 13), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_strnchrnul("ABCabcABCabc", 'C', 13), "CabcABCabc"));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", 'x', 13), ""));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", 'x', 20), ""));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", '\0', 13), ""));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", '\0', 20), ""));
+ assert(!strcmpnul(libsimple_strnchrnul("abcABCabcABC", '\0', 3), "ABCabcABC"));
+ assert(!strcmpnul(libsimple_strnchrnul("abcdef", 'd', 3), "def"));
+ assert(!strcmpnul(libsimple_strnchrnul("abcdef", 'e', 3), "def"));
+ assert(!strcmpnul(libsimple_strnchrnul("123123", '1', 7), "123123"));
+ assert(!strcmpnul(libsimple_strnchrnul("123123", '3', 7), "3123"));
+ return 0;
+}
+
+#endif
diff --git a/strnend.c b/strnend.c
new file mode 100644
index 0000000..df950cf
--- /dev/null
+++ b/strnend.c
@@ -0,0 +1,38 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strnend(const char *s_, size_t n)
+{
+ char *s = *(char **)(void *)&s_;
+ char *end = &s[n];
+ for (; s != end && *s; s++);
+ return s;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strnend("123456789", 0), "123456789"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 1), "23456789"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 2), "3456789"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 3), "456789"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 4), "56789"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 5), "6789"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 6), "789"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 7), "89"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 8), "9"));
+ assert(!strcmpnul(libsimple_strnend("123456789", 9), ""));
+ assert(!strcmpnul(libsimple_strnend("123456789", 10), ""));
+ assert(!strcmpnul(libsimple_strnend("123456789", 11), ""));
+ assert(!strcmpnul(libsimple_strnend("123456789", 12), ""));
+ return 0;
+}
+
+#endif
diff --git a/strrncasechr.c b/strrncasechr.c
new file mode 100644
index 0000000..f4046d1
--- /dev/null
+++ b/strrncasechr.c
@@ -0,0 +1,48 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strrncasechr(const char *s_, int c, size_t n)
+{
+ char *s = *(char **)(void *)&s_;
+ char *end = &s[n], *r = NULL;
+ c = tolower(c);
+ for (; s != end; s++) {
+ if (tolower(*s) == c)
+ r = s;
+ if (!*s)
+ break;
+ }
+ return r;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strrncasechr("abcABCabcABC", 'a', 13), "ABC"));
+ assert(!strcmpnul(libsimple_strrncasechr("abcABCabcABC", 'c', 13), "C"));
+ assert(!strcmpnul(libsimple_strrncasechr("abcABCabcABC", 'A', 13), "ABC"));
+ assert(!strcmpnul(libsimple_strrncasechr("abcABCabcABC", 'C', 13), "C"));
+ assert(!strcmpnul(libsimple_strrncasechr("ABCabcABCabc", 'a', 13), "abc"));
+ assert(!strcmpnul(libsimple_strrncasechr("ABCabcABCabc", 'c', 13), "c"));
+ assert(!strcmpnul(libsimple_strrncasechr("ABCabcABCabc", 'A', 13), "abc"));
+ assert(!strcmpnul(libsimple_strrncasechr("ABCabcABCabc", 'C', 13), "c"));
+ assert(!libsimple_strrncasechr("abcABCabcABC", 'x', 13));
+ assert(!libsimple_strrncasechr("abcABCabcABC", 'x', 20));
+ assert(!strcmpnul(libsimple_strrncasechr("abcABCabcABC", '\0', 13), ""));
+ assert(!strcmpnul(libsimple_strrncasechr("abcABCabcABC", '\0', 20), ""));
+ assert(!libsimple_strrncasechr("abcABCabcABC", '\0', 3));
+ assert(!libsimple_strrncasechr("abcdef", 'd', 3));
+ assert(!libsimple_strrncasechr("abcdef", 'e', 3));
+ assert(!strcmpnul(libsimple_strrncasechr("123123", '1', 7), "123"));
+ assert(!strcmpnul(libsimple_strrncasechr("123123", '3', 7), "3"));
+ return 0;
+}
+
+#endif
diff --git a/strrnchr.c b/strrnchr.c
new file mode 100644
index 0000000..d67775e
--- /dev/null
+++ b/strrnchr.c
@@ -0,0 +1,47 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strrnchr(const char *s_, int c_, size_t n)
+{
+ char *s = *(char **)(void *)&s_, c = (char)c_;
+ char *end = &s[n], *r = NULL;
+ for (; s != end; s++) {
+ if (*s == c)
+ r = s;
+ if (!*s)
+ break;
+ }
+ return r;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strrnchr("abcABCabcABC", 'a', 13), "abcABC"));
+ assert(!strcmpnul(libsimple_strrnchr("abcABCabcABC", 'c', 13), "cABC"));
+ assert(!strcmpnul(libsimple_strrnchr("abcABCabcABC", 'A', 13), "ABC"));
+ assert(!strcmpnul(libsimple_strrnchr("abcABCabcABC", 'C', 13), "C"));
+ assert(!strcmpnul(libsimple_strrnchr("ABCabcABCabc", 'a', 13), "abc"));
+ assert(!strcmpnul(libsimple_strrnchr("ABCabcABCabc", 'c', 13), "c"));
+ assert(!strcmpnul(libsimple_strrnchr("ABCabcABCabc", 'A', 13), "ABCabc"));
+ assert(!strcmpnul(libsimple_strrnchr("ABCabcABCabc", 'C', 13), "Cabc"));
+ assert(!libsimple_strrnchr("abcABCabcABC", 'x', 13));
+ assert(!libsimple_strrnchr("abcABCabcABC", 'x', 20));
+ assert(!strcmpnul(libsimple_strrnchr("abcABCabcABC", '\0', 13), ""));
+ assert(!strcmpnul(libsimple_strrnchr("abcABCabcABC", '\0', 20), ""));
+ assert(!libsimple_strrnchr("abcABCabcABC", '\0', 3));
+ assert(!libsimple_strrnchr("abcdef", 'd', 3));
+ assert(!libsimple_strrnchr("abcdef", 'e', 3));
+ assert(!strcmpnul(libsimple_strrnchr("123123", '1', 7), "123"));
+ assert(!strcmpnul(libsimple_strrnchr("123123", '3', 7), "3"));
+ return 0;
+}
+
+#endif