aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--libsimple/str.h34
-rw-r--r--man/libsimple_strcasechr.378
-rw-r--r--man/libsimple_strcasechrnul.376
-rw-r--r--man/libsimple_strchrnul.31
l---------man/strcasechr.3libsimple1
l---------man/strcasechrnul.3libsimple1
-rw-r--r--strcasechr.c41
-rw-r--r--strcasechrnul.c41
-rw-r--r--strchrnul.c19
10 files changed, 289 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 7af3845..21bd244 100644
--- a/Makefile
+++ b/Makefile
@@ -74,17 +74,19 @@ OBJ =\
rawmemchr.o\
rawmemrchr.o\
rawmemrchr.o\
+ strcasechr.o\
+ strcasechrnul.o\
strcaseends.o\
strcasestr.o\
strchrnul.o\
strends.o\
+ strncasestr.o\
strndup.o\
strnstr.o\
- strncasestr.o\
strrcasestr.o\
- strrstr.o\
strrncasestr.o\
strrnstr.o\
+ strrstr.o\
strstarts.o\
strtotimespec.o\
strtotimeval.o\
diff --git a/libsimple/str.h b/libsimple/str.h
index 8fdaf19..d4930b4 100644
--- a/libsimple/str.h
+++ b/libsimple/str.h
@@ -1,8 +1,6 @@
/* See LICENSE file for copyright and license details. */
-/* TODO strcasechr */
-/* TODO strcasechrnul */
/* TODO strrcasechr */
/* TODO streqlen */
/* TODO strcaseeqlen */
@@ -18,7 +16,7 @@
* @return `s` with a minimal offset such that `*r == c || !*r`,
* where `r` is the returned pointer
*/
-_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __returns_nonnull__, __warn_unused_result__)))
char *libsimple_strchrnul(const char *, int);
#ifndef strchrnul
# define strchrnul libsimple_strchrnul
@@ -26,6 +24,36 @@ char *libsimple_strchrnul(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 minimal 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_strcasechr(const char *, int);
+#ifndef strcasechr
+# define strcasechr libsimple_strcasechr
+#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 minimal offset such that `tolower(*r) == tolower(c) || !*r`,
+ * where `r` is the returned pointer
+ */
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __returns_nonnull__, __warn_unused_result__)))
+char *libsimple_strcasechrnul(const char *, int);
+#ifndef strcasechrnul
+# define strcasechrnul libsimple_strcasechrnul
+#endif
+
+
+/**
* Scans for the end of a string
*
* @param s The string
diff --git a/man/libsimple_strcasechr.3 b/man/libsimple_strcasechr.3
new file mode 100644
index 0000000..97fabc0
--- /dev/null
+++ b/man/libsimple_strcasechr.3
@@ -0,0 +1,78 @@
+.TH LIBSIMPLE_STRCASECHR 3 2018-10-21 libsimple
+.SH NAME
+libsimple_strcasechr \- find a character in a string
+.SH SYNOPSIS
+.nf
+#include <libsimple.h>
+
+char *libsimple_strcasechr(const char *\fIs\fP, int \fIc\fP);
+
+#ifndef strcasechr
+# define strcasechr libsimple_strcasechr
+#endif
+.fi
+
+Link with
+.IR \-lsimple .
+.SH DESCRIPTION
+The
+.BR libsimple_strcasechr ()
+function scans the string
+.I s
+for the first 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_strcasechr ()
+function returns the pointer
+.I s
+with a minimal 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_strcasechr ()
+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_strcasechr ()
+T} Thread safety MT-Safe
+T{
+.BR libsimple_strcasechr ()
+T} Async-signal safety AS-Safe
+T{
+.BR libsimple_strcasechr ()
+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_strcasechrnul (3),
+.BR strchr (3)
diff --git a/man/libsimple_strcasechrnul.3 b/man/libsimple_strcasechrnul.3
new file mode 100644
index 0000000..a92387d
--- /dev/null
+++ b/man/libsimple_strcasechrnul.3
@@ -0,0 +1,76 @@
+.TH LIBSIMPLE_STRCASECHRNUL 3 2018-10-21 libsimple
+.SH NAME
+libsimple_strcasechrnul \- find a character in a string
+.SH SYNOPSIS
+.nf
+#include <libsimple.h>
+
+char *libsimple_strcasechrnul(const char *\fIs\fP, int \fIc\fP);
+
+#ifndef strcasechrnul
+# define strcasechrnul libsimple_strcasechrnul
+#endif
+.fi
+
+Link with
+.IR \-lsimple .
+.SH DESCRIPTION
+The
+.BR libsimple_strcasechrnul ()
+function scans the string
+.I s
+for the first 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_strcasechrnul ()
+function returns the pointer
+.I s
+with a minimal offset such that
+.IR tolower(*r)==tolower(c)||!*r ,
+where
+.I r
+is the returned pointer.
+.SH ERRORS
+The
+.BR libsimple_strcasechrnul ()
+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_strcasechrnul ()
+T} Thread safety MT-Safe
+T{
+.BR libsimple_strcasechrnul ()
+T} Async-signal safety AS-Safe
+T{
+.BR libsimple_strcasechrnul ()
+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 libsimple_strchrnul (3)
diff --git a/man/libsimple_strchrnul.3 b/man/libsimple_strchrnul.3
index 25d6618..8d8f53a 100644
--- a/man/libsimple_strchrnul.3
+++ b/man/libsimple_strchrnul.3
@@ -72,5 +72,6 @@ None.
.SH BUGS
None.
.SH SEE ALSO
+.BR libsimple_strcasechrnul (3),
.BR libsimple_strend (3),
.BR strchr (3)
diff --git a/man/strcasechr.3libsimple b/man/strcasechr.3libsimple
new file mode 120000
index 0000000..719a07d
--- /dev/null
+++ b/man/strcasechr.3libsimple
@@ -0,0 +1 @@
+libsimple_strcasechr.3 \ No newline at end of file
diff --git a/man/strcasechrnul.3libsimple b/man/strcasechrnul.3libsimple
new file mode 120000
index 0000000..ff1b0db
--- /dev/null
+++ b/man/strcasechrnul.3libsimple
@@ -0,0 +1 @@
+libsimple_strcasechrnul.3 \ No newline at end of file
diff --git a/strcasechr.c b/strcasechr.c
new file mode 100644
index 0000000..83e8f73
--- /dev/null
+++ b/strcasechr.c
@@ -0,0 +1,41 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strcasechr(const char *s_, int c)
+{
+ char *s = *(char **)(void *)&s_, lc = (char)tolower(c), uc = (char)toupper(c);
+ if (lc != uc)
+ for (; *s && *s != lc && *s != uc; s++);
+ else
+ for (; *s && *s != lc; s++);
+ return *s ? s : NULL;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strcasechr("abcABCabcABCx123123", 'c'), "cABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechr("abcABCabcABCx123123", 'a'), "abcABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechr("abcABCabcABCx123123", 'x'), "x123123"));
+ assert(!strcmpnul(libsimple_strcasechr("abcABCabcABCx123123", 'C'), "cABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechr("abcABCabcABCx123123", 'A'), "abcABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechr("abcABCabcABCx123123", 'X'), "x123123"));
+ assert(!strcmpnul(libsimple_strcasechr("ABCabcABCabcX123123", 'c'), "CabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechr("ABCabcABCabcX123123", 'a'), "ABCabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechr("ABCabcABCabcX123123", 'x'), "X123123"));
+ assert(!strcmpnul(libsimple_strcasechr("ABCabcABCabcX123123", 'C'), "CabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechr("ABCabcABCabcX123123", 'A'), "ABCabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechr("ABCabcABCabcX123123", 'X'), "X123123"));
+ assert(!libsimple_strcasechr("ABCabcABCabcX123123", '0'));
+ assert(!strcmpnul(libsimple_strcasechr("ABCabcABCabcX123123", '1'), "123123"));
+ return 0;
+}
+
+#endif
diff --git a/strcasechrnul.c b/strcasechrnul.c
new file mode 100644
index 0000000..5afcd54
--- /dev/null
+++ b/strcasechrnul.c
@@ -0,0 +1,41 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_strcasechrnul(const char *s_, int c)
+{
+ char *s = *(char **)(void *)&s_, lc = (char)tolower(c), uc = (char)toupper(c);
+ if (lc != uc)
+ for (; *s && *s != lc && *s != uc; s++);
+ else
+ for (; *s && *s != lc; s++);
+ return s;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_strcasechrnul("abcABCabcABCx123123", 'c'), "cABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("abcABCabcABCx123123", 'a'), "abcABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("abcABCabcABCx123123", 'x'), "x123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("abcABCabcABCx123123", 'C'), "cABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("abcABCabcABCx123123", 'A'), "abcABCabcABCx123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("abcABCabcABCx123123", 'X'), "x123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", 'c'), "CabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", 'a'), "ABCabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", 'x'), "X123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", 'C'), "CabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", 'A'), "ABCabcABCabcX123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", 'X'), "X123123"));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", '0'), ""));
+ assert(!strcmpnul(libsimple_strcasechrnul("ABCabcABCabcX123123", '1'), "123123"));
+ return 0;
+}
+
+#endif
diff --git a/strchrnul.c b/strchrnul.c
index 3ec6a0f..e4ed5ab 100644
--- a/strchrnul.c
+++ b/strchrnul.c
@@ -4,7 +4,7 @@
char *
-libsimple_strchrnul(const char *s_, char c_)
+libsimple_strchrnul(const char *s_, int c_)
{
char *s = *(char **)(void *)&s_, c = (char)c_;
for (; *s && *s != c; s++);
@@ -18,9 +18,20 @@ libsimple_strchrnul(const char *s_, char c_)
int
main(void)
{
- assert(!strcmpnul(libsimple_strchrnul("1234512345", '3'), "34512345"));
- assert(!strcmpnul(libsimple_strchrnul("1234512345", '1'), "1234512345"));
- assert(!strcmpnul(libsimple_strchrnul("1234512345", 'x'), ""));
+ assert(!strcmpnul(libsimple_strchrnul("abcABCabcABCx", 'c'), "cABCabcABCx"));
+ assert(!strcmpnul(libsimple_strchrnul("abcABCabcABCx", 'a'), "abcABCabcABCx"));
+ assert(!strcmpnul(libsimple_strchrnul("abcABCabcABCx", 'x'), "x"));
+ assert(!strcmpnul(libsimple_strchrnul("abcABCabcABCx", 'C'), "CabcABCx"));
+ assert(!strcmpnul(libsimple_strchrnul("abcABCabcABCx", 'A'), "ABCabcABCx"));
+ assert(!strcmpnul(libsimple_strchrnul("abcABCabcABCx", 'X'), ""));
+ assert(!strcmpnul(libsimple_strchrnul("abcABCabcABCx", '0'), ""));
+ assert(!strcmpnul(libsimple_strchrnul("ABCabcABCabcX", 'c'), "cABCabcX"));
+ assert(!strcmpnul(libsimple_strchrnul("ABCabcABCabcX", 'a'), "abcABCabcX"));
+ assert(!strcmpnul(libsimple_strchrnul("ABCabcABCabcX", 'x'), ""));
+ assert(!strcmpnul(libsimple_strchrnul("ABCabcABCabcX", 'C'), "CabcABCabcX"));
+ assert(!strcmpnul(libsimple_strchrnul("ABCabcABCabcX", 'A'), "ABCabcABCabcX"));
+ assert(!strcmpnul(libsimple_strchrnul("ABCabcABCabcX", 'X'), "X"));
+ assert(!strcmpnul(libsimple_strchrnul("ABCabcABCabcX", '0'), ""));
return 0;
}