strchrnul.c 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  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. #include <string.h>
  9. #undef strchrnul
  10. //#define strchrnul TESTING
  11. char *strchrnul(const char *s, int c)
  12. {
  13. int esi;
  14. char *eax;
  15. __asm__ __volatile__(
  16. " movb %%al, %%ah\n"
  17. "1: lodsb\n"
  18. " cmpb %%ah, %%al\n"
  19. " je 2f\n"
  20. " testb %%al, %%al\n"
  21. " jnz 1b\n"
  22. /* with this, we'd get strchr(): */
  23. /* " movl $1, %%esi\n" */
  24. "2: leal -1(%%esi), %%eax\n"
  25. : "=a" (eax), "=&S" (esi)
  26. : "0" (c), "1" (s)
  27. /* no clobbers */
  28. );
  29. return eax;
  30. }
  31. #ifndef strchrnul
  32. libc_hidden_def(strchrnul)
  33. #else
  34. /* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strchrnul.c -o strchrnul
  35. * and run ./strchrnul
  36. */
  37. int main()
  38. {
  39. static const char str[] = "abc.def";
  40. printf((char*)strchrnul(str, '.') - str == 3 ? "ok\n" : "BAD!\n");
  41. printf((char*)strchrnul(str, '*') - str == 7 ? "ok\n" : "BAD!\n");
  42. printf((char*)strchrnul(str, 0) - str == 7 ? "ok\n" : "BAD!\n");
  43. printf((char*)strchrnul(str+3, '.') - str == 3 ? "ok\n" : "BAD!\n");
  44. }
  45. #endif