lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * Adapted from strchr.c code |
| 3 | * |
| 4 | * Copyright (C) 2008 Denys Vlasenko <vda.linux@googlemail.com> |
| 5 | * |
| 6 | * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. |
| 7 | */ |
| 8 | |
| 9 | #include <string.h> |
| 10 | |
| 11 | #undef strchrnul |
| 12 | /*#define strchrnul TESTING*/ |
| 13 | char *strchrnul(const char *s, int c) |
| 14 | { |
| 15 | int esi; |
| 16 | char *eax; |
| 17 | __asm__ __volatile__( |
| 18 | " movb %%al, %%ah\n" |
| 19 | "1: lodsb\n" |
| 20 | " cmpb %%ah, %%al\n" |
| 21 | " je 2f\n" |
| 22 | " testb %%al, %%al\n" |
| 23 | " jnz 1b\n" |
| 24 | /* with this, we'd get strchr(): */ |
| 25 | /* " movl $1, %%esi\n" */ |
| 26 | "2: leal -1(%%esi), %%eax\n" |
| 27 | : "=a" (eax), "=&S" (esi) |
| 28 | : "0" (c), "1" (s) |
| 29 | /* no clobbers */ |
| 30 | ); |
| 31 | return eax; |
| 32 | } |
| 33 | #ifndef strchrnul |
| 34 | libc_hidden_def(strchrnul) |
| 35 | #else |
| 36 | /* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strchrnul.c -o strchrnul |
| 37 | * and run ./strchrnul |
| 38 | */ |
| 39 | int main() |
| 40 | { |
| 41 | static const char str[] = "abc.def"; |
| 42 | printf((char*)strchrnul(str, '.') - str == 3 ? "ok\n" : "BAD!\n"); |
| 43 | printf((char*)strchrnul(str, '*') - str == 7 ? "ok\n" : "BAD!\n"); |
| 44 | printf((char*)strchrnul(str, 0) - str == 7 ? "ok\n" : "BAD!\n"); |
| 45 | printf((char*)strchrnul(str+3, '.') - str == 3 ? "ok\n" : "BAD!\n"); |
| 46 | } |
| 47 | #endif |