aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--libsimple/mem.h22
-rw-r--r--man/libsimple_memcasechr.381
-rw-r--r--man/libsimple_memrcasechr.34
-rw-r--r--man/libsimple_rawmemcasechr.31
-rw-r--r--memcasechr.c35
6 files changed, 139 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 3b2f653..b0834c9 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,7 @@ OBJ =\
envputenvf.o\
envreallocn.o\
isutf8.o\
+ memcasechr.o\
memcaseeqlen.o\
memdup.o\
memelem.o\
diff --git a/libsimple/mem.h b/libsimple/mem.h
index dbfbbc5..7ca2f41 100644
--- a/libsimple/mem.h
+++ b/libsimple/mem.h
@@ -1,8 +1,6 @@
/* See LICENSE file for copyright and license details. */
-/* TODO memcasechr */
-/* TODO rawmemrcasechr */
/* TODO memcasemem */
/* TODO memrcasemem */
/* TODO memcasestarts */
@@ -13,6 +11,24 @@
/**
* Finds the first occurence of a byte value in an array of bytes,
+ * the comparison is case-insensitive
+ *
+ * @param s The array of bytes to search
+ * @param c The byte value to search for
+ * @param n The number of bytes in the byte array
+ * @return `s` with a minimal offset such that `tolower(*r) == tolower(c)`,
+ * where `r` is the returned pointer `NULL` if no
+ * such offset exists within [s, &s[n])
+ */
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+void *libsimple_memcasechr(const void *, int, size_t);
+#ifndef memcasechr
+# define memcasechr libsimple_memcasechr
+#endif
+
+
+/**
+ * Finds the first occurence of a byte value in an array of bytes,
* the comparison is case-sensitive
*
* This function is optimised for instances where it is already
@@ -78,7 +94,7 @@ void *libsimple_memrchr(const void *, int, size_t);
* @param s The array of bytes to search
* @param c The byte value to search for
* @param n The number of bytes in the byte array
- * @return `s` with a maximal offset such that `*r == c`,
+ * @return `s` with a maximal offset such that `tolower(*r) == tolower(c)`,
* where `r` is the returned pointer `NULL` if no
* such offset exists within [s, &s[n])
*/
diff --git a/man/libsimple_memcasechr.3 b/man/libsimple_memcasechr.3
new file mode 100644
index 0000000..d90c7d4
--- /dev/null
+++ b/man/libsimple_memcasechr.3
@@ -0,0 +1,81 @@
+.TH LIBSIMPLE_MEMCASECHR 3 2018-10-21 libsimple
+.SH NAME
+libsimple_memcasechr \- find byte in memory
+.SH SYNOPSIS
+.nf
+#include <libsimple.h>
+
+void *libsimple_memcasechr(const void *\fIs\fP, int \fIc\fP, size_t \fIn\fP);
+
+#ifndef memcasechr
+# define memcasechr libsimple_memcasechr
+#endif
+.fi
+.PP
+Link with
+.IR \-lsimple .
+.SH DESCRIPTION
+The
+.BR libsimple_memcasechr ()
+function scans the memory segment
+.IR s ,
+with the size
+.IR n ,
+for the first occurence of the byte
+.I c
+(it is converted to a
+.BR char ).
+.PP
+The comparison is case-insensitive.
+.SH RETURN VALUE
+The
+.BR libsimple_memcasechr ()
+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,
+.B NULL
+is returned.
+.SH ERRORS
+The
+.BR libsimple_memcasechr ()
+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_memcasechr ()
+T} Thread safety MT-Safe
+T{
+.BR libsimple_memcasechr ()
+T} Async-signal safety AS-Safe
+T{
+.BR libsimple_memcasechr ()
+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_memrcasechr (3),
+.BR libsimple_rawmemcasechr (3),
+.BR libsimple_memcasemem (3),
+.BR memchr (3)
diff --git a/man/libsimple_memrcasechr.3 b/man/libsimple_memrcasechr.3
index caf7868..a86a345 100644
--- a/man/libsimple_memrcasechr.3
+++ b/man/libsimple_memrcasechr.3
@@ -75,7 +75,7 @@ None.
.SH BUGS
None.
.SH SEE ALSO
+.BR libsimple_memcasechr (3),
.BR libsimple_memrchr (3),
.BR libsimple_rawmemrcasechr (3),
-.BR libsimple_memrcasemem (3),
-.BR libsimple_memcasechr (3)
+.BR libsimple_memrcasemem (3)
diff --git a/man/libsimple_rawmemcasechr.3 b/man/libsimple_rawmemcasechr.3
index 4c3129c..2e06898 100644
--- a/man/libsimple_rawmemcasechr.3
+++ b/man/libsimple_rawmemcasechr.3
@@ -76,6 +76,7 @@ None.
.SH BUGS
None.
.SH SEE ALSO
+.BR libsimple_memcasechr (3),
.BR libsimple_rawmemchr (3),
.BR libsimple_rawmemrcasechr (3),
.BR libsimple_memcasechr (3)
diff --git a/memcasechr.c b/memcasechr.c
new file mode 100644
index 0000000..4277849
--- /dev/null
+++ b/memcasechr.c
@@ -0,0 +1,35 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+void *
+libsimple_memcasechr(const void *s_, int c, size_t n)
+{
+ char *s = *(char **)(void *)&s_;
+ size_t i = 0;
+ c = tolower(c);
+ for (; i < n && tolower(s[i]) != c; i++);
+ return i < n ? &s[i] : NULL;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ assert(!strcmpnul(libsimple_memcasechr("abcABCabcABC", 'a', sizeof("abcABCabcABC") - 1), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_memcasechr("abcABCabcABC", 'c', sizeof("abcABCabcABC") - 1), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_memcasechr("abcABCabcABC", 'A', sizeof("abcABCabcABC") - 1), "abcABCabcABC"));
+ assert(!strcmpnul(libsimple_memcasechr("abcABCabcABC", 'C', sizeof("abcABCabcABC") - 1), "cABCabcABC"));
+ assert(!strcmpnul(libsimple_memcasechr("ABCabcABCabc", 'a', sizeof("ABCabcABCabc") - 1), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_memcasechr("ABCabcABCabc", 'c', sizeof("ABCabcABCabc") - 1), "CabcABCabc"));
+ assert(!strcmpnul(libsimple_memcasechr("ABCabcABCabc", 'A', sizeof("ABCabcABCabc") - 1), "ABCabcABCabc"));
+ assert(!strcmpnul(libsimple_memcasechr("ABCabcABCabc", 'C', sizeof("ABCabcABCabc") - 1), "CabcABCabc"));
+ assert(!libsimple_memcasechr("abcABCabcABC", 'x', sizeof("abcABCabcABC") - 1));
+ return 0;
+}
+
+#endif