| /* |
| * 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 |