diff options
Diffstat (limited to 'libc/string/i386/strchrnul.c')
-rw-r--r-- | libc/string/i386/strchrnul.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/libc/string/i386/strchrnul.c b/libc/string/i386/strchrnul.c new file mode 100644 index 000000000..c4da2b587 --- /dev/null +++ b/libc/string/i386/strchrnul.c @@ -0,0 +1,47 @@ +/* + * Adapted from strchr.c code + * + * Copyright (C) 2008 Denys Vlasenko <vda.linux@googlemail.com> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <string.h> + +#undef strchrnul +//#define strchrnul TESTING +char *strchrnul(const char *s, int c) +{ + int esi; + char *eax; + __asm__ __volatile__( + " movb %%al, %%ah\n" + "1: lodsb\n" + " cmpb %%ah, %%al\n" + " je 2f\n" + " testb %%al, %%al\n" + " jnz 1b\n" + /* with this, we'd get strchr(): */ + /* " movl $1, %%esi\n" */ + "2: leal -1(%%esi), %%eax\n" + : "=a" (eax), "=&S" (esi) + : "0" (c), "1" (s) + /* no clobbers */ + ); + return eax; +} +#ifndef strchrnul +libc_hidden_def(strchrnul) +#else +/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strchrnul.c -o strchrnul + * and run ./strchrnul + */ +int main() +{ + static const char str[] = "abc.def"; + printf((char*)strchrnul(str, '.') - str == 3 ? "ok\n" : "BAD!\n"); + printf((char*)strchrnul(str, '*') - str == 7 ? "ok\n" : "BAD!\n"); + printf((char*)strchrnul(str, 0) - str == 7 ? "ok\n" : "BAD!\n"); + printf((char*)strchrnul(str+3, '.') - str == 3 ? "ok\n" : "BAD!\n"); +} +#endif |