summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-04-13 08:36:29 -0400
committerRich Felker <dalias@aerifal.cx>2011-04-13 08:36:29 -0400
commit6597f9ac133fd4f47dea307d6260fd52eae77816 (patch)
tree980c26e132ffeb5f1d6d5a8bec383c61cb0550bf
parent750b738e53f799443fcfcd3a0751318c072a022f (diff)
downloadmusl-6597f9ac133fd4f47dea307d6260fd52eae77816.tar.gz
implement memrchr (nonstandard) and optimize strrchr in terms of it
-rw-r--r--include/string.h1
-rw-r--r--src/string/memrchr.c12
-rw-r--r--src/string/strrchr.c7
3 files changed, 16 insertions, 4 deletions
diff --git a/include/string.h b/include/string.h
index c755c601..4fc89e94 100644
--- a/include/string.h
+++ b/include/string.h
@@ -74,6 +74,7 @@ int strncasecmp (const char *, const char *, size_t);
char *strchrnul(const char *, int);
char *strcasestr(const char *, const char *);
char *strsep(char **, const char *);
+void *memrchr(const void *, int, size_t);
#endif
#ifdef __cplusplus
diff --git a/src/string/memrchr.c b/src/string/memrchr.c
new file mode 100644
index 00000000..a78e9d6c
--- /dev/null
+++ b/src/string/memrchr.c
@@ -0,0 +1,12 @@
+#include <string.h>
+#include "libc.h"
+
+void *__memrchr(const void *m, int c, size_t n)
+{
+ const unsigned char *s = m;
+ c = (unsigned char)c;
+ while (n--) if (s[n]==c) return (void *)(s+n);
+ return 0;
+}
+
+weak_alias(__memrchr, memrchr);
diff --git a/src/string/strrchr.c b/src/string/strrchr.c
index 31c8e0b8..9c683087 100644
--- a/src/string/strrchr.c
+++ b/src/string/strrchr.c
@@ -1,9 +1,8 @@
#include <string.h>
+void *__memrchr(const void *, int, size_t);
+
char *strrchr(const char *s, int c)
{
- const char *p;
- c = (char)c;
- for (p=s+strlen(s); p>=s && *p!=c; p--);
- return p>=s ? (char *)p : 0;
+ return __memrchr(s, c, strlen(s));
}