memmem.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /* -*-comment-start: "//";comment-end:""-*-
  2. * GNU Mes --- Maxwell Equations of Software
  3. * Copyright © 1997--2015,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  4. * Copyright (C) 1997--2015,2018 Han-Wen Nienhuys <hanwen@xs4all.nl>
  5. *
  6. * This file is part of GNU Mes.
  7. *
  8. * GNU Mes is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * GNU Mes is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <string.h>
  22. /** locate a substring. #memmem# finds the first occurrence of
  23. #needle# in #haystack#. This is not ANSI-C.
  24. The prototype is not in accordance with the Linux Programmer's
  25. Manual v1.15, but it is with /usr/include/string.h */
  26. unsigned char *
  27. _memmem (unsigned char const *haystack, int haystack_len, unsigned char const *needle, int needle_len)
  28. {
  29. unsigned char const *end_haystack = haystack + haystack_len - needle_len + 1;
  30. unsigned char const *end_needle = needle + needle_len;
  31. /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation
  32. is the spice of life */
  33. while (haystack < end_haystack)
  34. {
  35. unsigned char const *subneedle = needle;
  36. unsigned char const *subhaystack = haystack;
  37. while (subneedle < end_needle)
  38. if (*subneedle++ != *subhaystack++)
  39. goto next;
  40. /* Completed the needle. Gotcha. */
  41. return (unsigned char *) haystack;
  42. next:
  43. haystack++;
  44. }
  45. return 0;
  46. }
  47. void *
  48. memmem (void const *haystack, int haystack_len, void const *needle, int needle_len)
  49. {
  50. unsigned char const *haystack_byte_c = (unsigned char const *) haystack;
  51. unsigned char const *needle_byte_c = (unsigned char const *) needle;
  52. return _memmem (haystack_byte_c, haystack_len, needle_byte_c, needle_len);
  53. }