summaryrefslogtreecommitdiff
path: root/lib/mlibc/options/posix/generic/strings-stubs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mlibc/options/posix/generic/strings-stubs.cpp')
-rw-r--r--lib/mlibc/options/posix/generic/strings-stubs.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/lib/mlibc/options/posix/generic/strings-stubs.cpp b/lib/mlibc/options/posix/generic/strings-stubs.cpp
new file mode 100644
index 0000000..524c424
--- /dev/null
+++ b/lib/mlibc/options/posix/generic/strings-stubs.cpp
@@ -0,0 +1,107 @@
+
+#include <strings.h>
+#include <string.h>
+
+#include <ctype.h>
+#include <bits/ensure.h>
+#include <mlibc/strings.hpp>
+
+char *index (const char *s, int c) {
+ return strchr(s, c);
+}
+
+char *rindex(const char *s, int c) {
+ return strrchr(s, c);
+}
+
+namespace {
+
+ template<typename T>
+ int ffs_generic(T i) {
+ //Non-portably assume a byte has 8 bits; fine in all plausible cases.
+ for(size_t b = 0; b < sizeof(T) * 8;)
+ if(i & (static_cast<T>(0x1) << b++))
+ return b;
+
+ return 0;
+ }
+
+}
+
+// On RISC-V, __builtin_ffs just calls into ffs, so we can't use it here.
+#if defined(__has_builtin) && !defined(__riscv)
+# if __has_builtin(__builtin_ffs)
+# define __mlibc_ffs __builtin_ffs
+# endif
+# if __has_builtin(__builtin_ffsl)
+# define __mlibc_ffsl __builtin_ffsl
+# endif
+# if __has_builtin(__builtin_ffsll)
+# define __mlibc_ffsll __builtin_ffsll
+# endif
+#endif
+
+int ffs(int i) {
+#ifdef __mlibc_ffs
+ return __mlibc_ffs(i);
+#else
+ return ffs_generic<int>(i);
+#endif
+}
+
+/*
+ Both ffsl() and ffsll() are glibc extensions
+ defined in string.h. They are however implemented
+ here because of similarity in logic and
+ shared code.
+*/
+
+int ffsl(long i) {
+#ifdef __mlibc_ffsl
+ return __mlibc_ffsl(i);
+#else
+ return ffs_generic<long>(i);
+#endif
+}
+
+int ffsll(long long i) {
+#ifdef __mlibc_ffsll
+ return __mlibc_ffsll(i);
+#else
+ return ffs_generic<long long>(i);
+#endif
+}
+
+int strcasecmp(const char *a, const char *b) {
+ size_t i = 0;
+ while(true) {
+ unsigned char a_byte = tolower(a[i]);
+ unsigned char b_byte = tolower(b[i]);
+ if(!a_byte && !b_byte)
+ return 0;
+ // If only one char is null, one of the following cases applies.
+ if(a_byte < b_byte)
+ return -1;
+ if(a_byte > b_byte)
+ return 1;
+ i++;
+ }
+}
+
+int strncasecmp(const char *a, const char *b, size_t size) {
+ return mlibc::strncasecmp(a, b, size);
+}
+
+// Marked as obsolete in posix 2008 but used by at least tracker
+int bcmp(const void *s1, const void *s2, size_t n) {
+ return memcmp(s1, s2, n);
+}
+
+void bcopy(const void *s1, void *s2, size_t n) {
+ memmove(s2, s1, n);
+}
+
+void bzero(void *s, size_t n) {
+ memset(s, 0, n);
+}
+