aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--libsimple/str.h16
-rw-r--r--man/libsimple_strcasechr.31
-rw-r--r--man/libsimple_strrcasechr.378
l---------man/strrcasechr.3libsimple1
-rw-r--r--strrcasechr.c46
6 files changed, 142 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 21bd244..09d3d15 100644
--- a/Makefile
+++ b/Makefile
@@ -83,6 +83,7 @@ OBJ =\
strncasestr.o\
strndup.o\
strnstr.o\
+ strrcasechr.o\
strrcasestr.o\
strrncasestr.o\
strrnstr.o\
diff --git a/libsimple/str.h b/libsimple/str.h
index d4930b4..c046fbc 100644
--- a/libsimple/str.h
+++ b/libsimple/str.h
@@ -1,7 +1,6 @@
/* See LICENSE file for copyright and license details. */
-/* TODO strrcasechr */
/* TODO streqlen */
/* TODO strcaseeqlen */
/* TODO strreqlen */
@@ -54,6 +53,21 @@ char *libsimple_strcasechrnul(const char *, int);
/**
+ * Scans for a character in a string, the scan is case-insensitive
+ *
+ * @param s The string to scan
+ * @param c The character for scan for
+ * @return `s` with a maximal offset such that `tolower(*r) == tolower(c)`,
+ * where `r` is the returned pointer, `NULL` if no such offset exists
+ */
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+char *libsimple_strrcasechr(const char *, int);
+#ifndef strrcasechr
+# define strrcasechr libsimple_strrcasechr
+#endif
+
+
+/**
* Scans for the end of a string
*
* @param s The string
diff --git a/man/libsimple_strcasechr.3 b/man/libsimple_strcasechr.3
index 97fabc0..f100ac8 100644
--- a/man/libsimple_strcasechr.3
+++ b/man/libsimple_strcasechr.3
@@ -75,4 +75,5 @@ None.
None.
.SH SEE ALSO
.BR libsimple_strcasechrnul (3),
+.BR libsimple_strrcasechr (3),
.BR strchr (3)
diff --git a/man/libsimple_strrcasechr.3 b/man/libsimple_strrcasechr.3
new file mode 100644
index 0000000..188bcd7
--- /dev/null
+++ b/man/libsimple_strrcasechr.3
@@ -0,0 +1,78 @@
+.TH LIBSIMPLE_STRRCASECHR 3 2018-10-21 libsimple
+.SH NAME
+libsimple_strrcasechr \- find a character in a string
+.SH SYNOPSIS
+.nf
+#include <libsimple.h>
+
+char *libsimple_strrcasechr(const char *\fIs\fP, int \fIc\fP);
+
+#ifndef strrcasechr
+# define strrcasechr libsimple_strrcasechr
+#endif
+.fi
+
+Link with
+.IR \-lsimple .
+.SH DESCRIPTION
+The
+.BR libsimple_strrcasechr ()
+function scans the string
+.I s
+for the last occurence of the character
+.I c
+(it is converted to a
+.BR char ).
+If no such character exist in the string,
+the string's end is returned.
+.PP
+The comparison is case-insensitive.
+.SH RETURN VALUE
+The
+.BR libsimple_strrcasechr ()
+function returns the pointer
+.I s
+with a maximal offset such that
+.IR tolower(*r)==tolower(c) ,
+where
+.I r
+is the returned pointer, if no such
+offset exists, it returns
+.IR NULL .
+.SH ERRORS
+The
+.BR libsimple_strrcasechr ()
+function cannot fail.
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lb lb lb
+l l l.
+Interface Attribute Value
+T{
+.BR libsimple_strrcasechr ()
+T} Thread safety MT-Safe
+T{
+.BR libsimple_strrcasechr ()
+T} Async-signal safety AS-Safe
+T{
+.BR libsimple_strrcasechr ()
+T} Async-cancel safety AC-Safe
+.TE
+.SH EXAMPLES
+None.
+.SH APPLICATION USAGE
+None.
+.SH RATIONALE
+None.
+.SH FUTURE DIRECTIONS
+None.
+.SH NOTES
+None.
+.SH BUGS
+None.
+.SH SEE ALSO
+.BR libsimple_strcasechr (3),
+.BR strrchr (3)
diff --git a/man/strrcasechr.3libsimple b/man/strrcasechr.3libsimple
new file mode 120000
index 0000000..c49c441
--- /dev/null
+++ b/man/strrcasechr.3libsimple
@@ -0,0 +1 @@
+libsimple_strrcasechr.3 \ No newline at end of file
diff --git a/strrcasechr.c b/strrcasechr.c
new file mode 100644
index 0000000..979e61b
--- /dev/null
+++ b/strrcasechr.c
@@ -0,0 +1,46 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strrcasechr(const char *s_, int c)
+{
+ char *s = *(char **)(void *)&s_, lc = (char)tolower(c), uc = (char)toupper(c), *r = NULL;
+ if (lc != uc) {
+ for (; *s; s++)
+ if (*s == lc || *s == uc)
+ r = s;
+ } else {
+ for (; *s; s++)
+ if (*s == lc)
+ r = s;
+ }
+ return r;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strrcasechr("abcABCabcABCx123123", 'c'), "Cx123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("abcABCabcABCx123123", 'a'), "ABCx123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("abcABCabcABCx123123", 'x'), "x123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("abcABCabcABCx123123", 'C'), "Cx123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("abcABCabcABCx123123", 'A'), "ABCx123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("abcABCabcABCx123123", 'X'), "x123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("ABCabcABCabcX123123", 'c'), "cX123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("ABCabcABCabcX123123", 'a'), "abcX123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("ABCabcABCabcX123123", 'x'), "X123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("ABCabcABCabcX123123", 'C'), "cX123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("ABCabcABCabcX123123", 'A'), "abcX123123"));
+ assert(!strcmpnul(libsimple_strrcasechr("ABCabcABCabcX123123", 'X'), "X123123"));
+ assert(!libsimple_strrcasechr("ABCabcABCabcX123123", '0'));
+ assert(!strcmpnul(libsimple_strrcasechr("ABCabcABCabcX123123", '1'), "123"));
+ return 0;
+}
+
+#endif