diff options
-rw-r--r-- | libc/string/i386/strchrnul.c | 47 | ||||
-rw-r--r-- | libc/string/i386/strncpy.c | 2 |
2 files changed, 48 insertions, 1 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 diff --git a/libc/string/i386/strncpy.c b/libc/string/i386/strncpy.c index ba0c41063..e1c7f1dcf 100644 --- a/libc/string/i386/strncpy.c +++ b/libc/string/i386/strncpy.c @@ -68,7 +68,7 @@ int main() str[4] = '*'; str[5] = '+'; strncpy(str, "abc", 5); printf(strcmp(str, "abc") == 0 && str[4] == 0 && str[5] == '+' ? "ok\n" : "BAD!\n"); - strncpy(str, "abc", 0); /* should do nothing */ + strncpy(str, "def", 0); /* should do nothing */ printf(strcmp(str, "abc") == 0 && str[4] == 0 && str[5] == '+' ? "ok\n" : "BAD!\n"); } |