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