blob: d484272142e4adaaf111f3248001163401ce133d [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
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*/
13char *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
34libc_hidden_def(strchrnul)
35#else
36/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strchrnul.c -o strchrnul
37 * and run ./strchrnul
38 */
39int 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