Welcome to little lamb

Code » limb » commit 226d911

bytestr.h: Add byte_istr()

author Olivier Brunel
2023-12-16 21:30:12 UTC
committer Olivier Brunel
2024-01-01 19:10:12 UTC
parent 8dfdc46f269e181626ab660ee7d8ef639668fe0c

bytestr.h: Add byte_istr()

It's byte_str() but case-insensitive.
It's also very much *not* optimized; use with care.

src/doc/bytestr.h/byte_istr.3.md +1 -0
src/doc/bytestr.h/byte_str.3.md +11 -3
src/doc/bytestr.h/bytestr.h.0.md +3 -0
src/liblimb/bytestr.h/byte_istr.c +23 -0
src/liblimb/include/limb/bytestr.h +1 -0

diff --git a/src/doc/bytestr.h/byte_istr.3.md b/src/doc/bytestr.h/byte_istr.3.md
new file mode 120000
index 0000000..4efbe9b
--- /dev/null
+++ b/src/doc/bytestr.h/byte_istr.3.md
@@ -0,0 +1 @@
+byte_str.3.md
\ No newline at end of file
diff --git a/src/doc/bytestr.h/byte_str.3.md b/src/doc/bytestr.h/byte_str.3.md
index 9769117..bacb11a 100644
--- a/src/doc/bytestr.h/byte_str.3.md
+++ b/src/doc/bytestr.h/byte_str.3.md
@@ -3,7 +3,7 @@
 
 # NAME
 
-byte_str - locate a byte array within another byte array
+byte_str byte_istr - locate a byte array within another byte array
 
 # SYNOPSIS
 
@@ -11,6 +11,7 @@ byte_str - locate a byte array within another byte array
 
 ```pre hl
 size_t byte_str(const char *<em>haystack</em>, size_t <em>hlen</em>, const char *<em>needle</em>, size_t <em>nlen</em>)
+size_t byte_istr(const char *<em>haystack</em>, size_t <em>hlen</em>, const char *<em>needle</em>, size_t <em>nlen</em>)
 ```
 
 # DESCRIPTION
@@ -21,7 +22,14 @@ The `byte_str`() function looks for the first occurrence of the byte array
 Neither `haystack` nor `needle` need be NUL-terminated, and in fact can contain
 themselves bytes of any value.
 
+The `byte_istr`() function is similar but performing case-insensitive
+comparisons for the current locale. (Specifically, it relies on [tolower](3).)
+
+! WARNING:
+! Unless both arrays are small, the `byte_istr`() function will perform poorly.
+
 # RETURN VALUE
 
-The `byte_str`() function returns the offset of the first occurrence of `needle`
-within `haystack` if found. Otherwise, it returns `hlen`.
+The `byte_str`() and `byte_istr`() functions return the offset of the first
+occurrence of `needle` within `haystack` if found. Otherwise, they returns
+`hlen`.
diff --git a/src/doc/bytestr.h/bytestr.h.0.md b/src/doc/bytestr.h/bytestr.h.0.md
index 0fca05f..f6007eb 100644
--- a/src/doc/bytestr.h/bytestr.h.0.md
+++ b/src/doc/bytestr.h/bytestr.h.0.md
@@ -41,6 +41,9 @@ The following functions are defined :
 : [byte_in](3)
 :: Find the first occurence of any of the given bytes in a byte array.
 
+: [byte_istr](3)
+:: Similar to [byte_str](3) but performing case-insensitive comparisons.
+
 : [byte_rchr](3)
 :: Find the last occurence of a character (byte) in a byte array.
 
diff --git a/src/liblimb/bytestr.h/byte_istr.c b/src/liblimb/bytestr.h/byte_istr.c
new file mode 100644
index 0000000..c326181
--- /dev/null
+++ b/src/liblimb/bytestr.h/byte_istr.c
@@ -0,0 +1,23 @@
+/* This file is part of limb                           https://lila.oss/limb
+ * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <ctype.h>
+#include <limb/bytestr.h>
+
+size_t
+byte_istr(const char *haystack, size_t hlen, const char *needle, size_t nlen)
+{
+    if (!hlen || !nlen || nlen > hlen) return hlen;
+
+    size_t from, n;
+    for (from = 0, n = 0; from < hlen - nlen && n < nlen; ) {
+        if (tolower(haystack[from + n]) != tolower(needle[n])) {
+            n = 0;
+            ++from;
+        } else {
+            ++n;
+        }
+    }
+
+    return (n == nlen) ? from : hlen;
+}
diff --git a/src/liblimb/include/limb/bytestr.h b/src/liblimb/include/limb/bytestr.h
index bc59b28..45c3c43 100644
--- a/src/liblimb/include/limb/bytestr.h
+++ b/src/liblimb/include/limb/bytestr.h
@@ -7,6 +7,7 @@
 #include <skalibs/bytestr.h>
 
 extern size_t byte_str(const char *haystack, size_t hlen, const char *needle, size_t nlen);
+extern size_t byte_istr(const char *haystack, size_t hlen, const char *needle, size_t nlen);
 
 extern int byte_get_match_full(int *first, const char *str, size_t slen,
                                const void *list_, size_t offset, size_t llen);