From 167ddc64a60bf8360ef67c675b97a517dc0e85d1 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 21 Oct 2018 11:59:01 +0200 Subject: Add strrcasechr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 1 + libsimple/str.h | 16 +++++++++- man/libsimple_strcasechr.3 | 1 + man/libsimple_strrcasechr.3 | 78 +++++++++++++++++++++++++++++++++++++++++++++ man/strrcasechr.3libsimple | 1 + strrcasechr.c | 46 ++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 man/libsimple_strrcasechr.3 create mode 120000 man/strrcasechr.3libsimple create mode 100644 strrcasechr.c 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 */ @@ -53,6 +52,21 @@ char *libsimple_strcasechrnul(const char *, int); #endif +/** + * 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 * 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 + +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 -- cgit v1.2.3-70-g09d2