aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--close_range.c2
-rw-r--r--config.mk4
-rw-r--r--libsimple.h34
-rw-r--r--libsimple/definitions.h24
-rw-r--r--memcasemem.c26
-rw-r--r--memmem.c33
6 files changed, 108 insertions, 15 deletions
diff --git a/close_range.c b/close_range.c
index 29602c9..096aa56 100644
--- a/close_range.c
+++ b/close_range.c
@@ -128,7 +128,7 @@ fallback:
} while (first++ < last);
out:
- (next)
+ if (next)
*next = last + (last < LIBSIMPLE_CLOSE_RANGE_MAX);
errno = saved_errno;
return 0;
diff --git a/config.mk b/config.mk
index c7eb5ca..85ba3e0 100644
--- a/config.mk
+++ b/config.mk
@@ -1,8 +1,8 @@
PREFIX = /usr
MANPREFIX = $(PREFIX)/share/man
-CC = cc
+CC = cc -std=c11
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
-CFLAGS = -std=c11 -Wall -Wextra -O2
+CFLAGS = -Wall -Wextra -O2
LDFLAGS = -s -lm
diff --git a/libsimple.h b/libsimple.h
index 6d1867e..6e5f170 100644
--- a/libsimple.h
+++ b/libsimple.h
@@ -125,6 +125,40 @@
#endif
+/* TODO doc, man, since 1.8, check which are supported by clang */
+#if defined(__GNUC__) && !defined(__clang__)
+# define LIBSIMPLE_PURE __attribute__((pure))
+# define LIBSIMPLE_CONST __attribute__((const))
+# define LIBSIMPLE_NONNULL_RETURN __attribute__((returns_nonnull))
+# define LIBSIMPLE_USE_RETURN __attribute__((warn_unused_result))
+# define LIBSIMPLE_NONNULL_ARGS(...) __attribute__((nonnull__(__VA_ARGS__)))
+# define LIBSIMPLE_NO_NULL_ARGS __attribute__((nonnull))
+# define LIBSIMPLE_RETURNS_TWICE __attribute__((returns_twice))
+# define LIBSIMPLE_UNREACHABLE __builtin_unreachable()
+# define LIBSIMPLE_EXPECT(V, LIKELY) __builtin_expect((V), (LIKELY))
+# define LIBSIMPLE_ALIGNED(P) __builtin_assume_aligned((P), sizeof(*(P)))
+# define LIBSIMPLE_ALIGNED_TO(P, A) __builtin_assume_aligned((P), (A))
+# define LIBSIMPLE_MISALIGNED(P, OFF) __builtin_assume_aligned((P), sizeof(*(P)), 0)
+# define LIBSIMPLE_MISALIGNED_FROM(P, A, OFF) __builtin_assume_aligned((P), (A), 0)
+#else
+# define LIBSIMPLE_PURE
+# define LIBSIMPLE_CONST
+# define LIBSIMPLE_NONNULL_RETURN
+# define LIBSIMPLE_USE_RETURN
+# define LIBSIMPLE_NONNULL_ARGS(...)
+# define LIBSIMPLE_NO_NULL_ARGS
+# define LIBSIMPLE_RETURNS_TWICE
+# define LIBSIMPLE_UNREACHABLE abort()
+# define LIBSIMPLE_EXPECT(V, LIKELY) (V)
+# define LIBSIMPLE_ALIGNED(P) (P)
+# define LIBSIMPLE_ALIGNED_TO(P, A) (P)
+# define LIBSIMPLE_MISALIGNED(P, OFF) (P)
+# define LIBSIMPLE_MISALIGNED_FROM(P, A, OFF) (P)
+#endif
+#define LIBSIMPLE_LIKELY(V) LIBSIMPLE_EXPECT(!!(V), 1)
+#define LIBSIMPLE_UNLIKELY(V) LIBSIMPLE_EXPECT(!!(V), 0)
+
+
#include "libsimple/overflow.h"
#include "libsimple/printf.h"
#include "libsimple/definitions.h"
diff --git a/libsimple/definitions.h b/libsimple/definitions.h
index 98c3a15..e5dca61 100644
--- a/libsimple/definitions.h
+++ b/libsimple/definitions.h
@@ -218,13 +218,13 @@
*
* This macro does not support the wide-character strings
*
- * @param STR:const char [] The string, must be a literal
- * @return :size_t The value of `strlen(STR)` as a constant expression
+ * @param STR:string literal The string (must be a literal)
+ * @return :size_t The value of `strlen(STR)` as a constant expression
*
* @since 1.0
*/
#ifndef STRLEN
-# define STRLEN(STR) (sizeof(STR) - 1)
+# define STRLEN(STR) (sizeof(STR) - 1U)
#endif
@@ -381,6 +381,24 @@
#endif
+/* TODO man, doc, since 1.8 */
+#define LIBSIMPLE_0_TO_7 "01234567"
+#define LIBSIMPLE_0_TO_9 "0123456789"
+#define LIBSIMPLE_a_TO_f "abcdef"
+#define LIBSIMPLE_A_TO_F "ABCDEF"
+#define LIBSIMPLE_a_TO_z "abcdefghijklmnopqrstuvwxyz"
+#define LIBSIMPLE_A_TO_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define LIBSIMPLE_0_TO_f LIBSIMPLE_0_TO_9 LIBSIMPLE_a_TO_f
+#define LIBSIMPLE_0_TO_F LIBSIMPLE_0_TO_9 LIBSIMPLE_A_TO_F
+
+
+/* TODO man, doc, since 1.8 */
+#define LIBSIMPLE_SIZEOF_MEMBER(STRUCT, MEMBER) (sizeof(((STRUCT *)NULL)->MEMBER))
+#ifndef sizeof_member
+#define sizeof_member(STRUCT, MEMBER) LIBSIMPLE_SIZEOF_MEMBER(STRUCT, MEMBER)
+#endif
+
+
/* --- Maximum values (since 1.0) --- */
#ifndef BLKCNT64_MAX
diff --git a/memcasemem.c b/memcasemem.c
index b3ea476..d883b62 100644
--- a/memcasemem.c
+++ b/memcasemem.c
@@ -8,7 +8,7 @@ libsimple_memcasemem(const void *hay_, size_t hayn, const void *sub_, size_t sub
{
const char *hay = hay_;
const char *sub = sub_;
- const char *end;
+ size_t *next, i, j;
if (!subn)
return REMOVE_CONST(hay, char *);
@@ -17,9 +17,29 @@ libsimple_memcasemem(const void *hay_, size_t hayn, const void *sub_, size_t sub
if (subn == 1)
return libsimple_memcasechr(hay, *sub, hayn);
- for (end = &hay[hayn - subn + 1]; hay != end; hay++)
- if (tolower(*hay) == tolower(*sub) && !libsimple_memcasecmp(hay, sub, subn))
+ next = alloca((subn + 1U) * sizeof(*next));
+ i = 0, j = SIZE_MAX;
+ goto beginning;
+ for (; i < subn; i++, j++) {
+ if (tolower(sub[i]) == tolower(sub[j])) {
+ next[i] = next[j];
+ } else {
+ beginning:
+ next[i] = j;
+ while (j != SIZE_MAX && tolower(sub[i]) != tolower(sub[j]))
+ j = next[j];
+ }
+ }
+
+ for (i = j = 0; i < hayn;) {
+ while (j != SIZE_MAX && tolower(sub[j]) != tolower(hay[i]))
+ j = next[j];
+ i++;
+ if (++j == subn) {
+ hay = &hay[i - j];
return REMOVE_CONST(hay, char *);
+ }
+ }
return NULL;
}
diff --git a/memmem.c b/memmem.c
index 847c4f0..5d6e711 100644
--- a/memmem.c
+++ b/memmem.c
@@ -6,19 +6,40 @@
void *
libsimple_memmem(const void *hay_, size_t hayn, const void *sub_, size_t subn)
{
- const char *hay = hay_, *end;
- const char *sub = sub_;
+ const unsigned char *hay = hay_;
+ const unsigned char *sub = sub_;
+ size_t *next, i, j;
if (!subn)
- return REMOVE_CONST(hay, char *);
+ return REMOVE_CONST(hay, unsigned char *);
if (hayn < subn)
return NULL;
if (subn == 1)
return memchr(hay, *sub, hayn);
- for (end = &hay[hayn - subn + 1]; hay != end; hay++)
- if (*hay == *sub && !memcmp(hay, sub, subn))
- return REMOVE_CONST(hay, char *);
+ next = alloca((subn + 1U) * sizeof(*next));
+ i = 0, j = SIZE_MAX;
+ goto beginning;
+ for (; i < subn; i++, j++) {
+ if (sub[i] == sub[j]) {
+ next[i] = next[j];
+ } else {
+ beginning:
+ next[i] = j;
+ while (j != SIZE_MAX && sub[i] != sub[j])
+ j = next[j];
+ }
+ }
+
+ for (i = j = 0; i < hayn;) {
+ while (j != SIZE_MAX && sub[j] != hay[i])
+ j = next[j];
+ i++;
+ if (++j == subn) {
+ hay = &hay[i - j];
+ return REMOVE_CONST(hay, unsigned char *);
+ }
+ }
return NULL;
}