1/* Return the offset of one string within another. 2 Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public License as 7 published by the Free Software Foundation; either version 2 of the 8 License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Boston, MA 02111-1307, USA. */ 19 20/* 21 * My personal strstr() implementation that beats most other algorithms. 22 * Until someone tells me otherwise, I assume that this is the 23 * fastest implementation of strstr() in C. 24 * I deliberately chose not to comment it. You should have at least 25 * as much fun trying to understand it, as I had to write it :-). 26 * 27 * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ 28/* added strcasestr support, davidm@lineo.com */ 29 30#if HAVE_CONFIG_H 31# include <config.h> 32#endif 33 34#ifndef HAVE_STRCASESTR 35 36#if defined HAVE_STRING_H 37# include <string.h> 38#endif 39 40typedef unsigned chartype; 41 42#include <ctype.h> 43#define VAL(x) tolower(x) 44#define FUNC strcasestr 45#undef strcasestr 46 47char * FUNC ( const char *phaystack, const char *pneedle) 48{ 49 register const unsigned char *haystack, *needle; 50 register chartype b, c; 51 52 haystack = (const unsigned char *) phaystack; 53 needle = (const unsigned char *) pneedle; 54 55 b = *needle; 56 if (b != '\0') { 57 haystack--; /* possible ANSI violation */ 58 do { 59 c = *++haystack; 60 if (c == '\0') 61 goto ret0; 62 } 63 while (VAL(c) != VAL(b)); 64 65 c = *++needle; 66 if (c == '\0') 67 goto foundneedle; 68 ++needle; 69 goto jin; 70 71 for (;;) { 72 register chartype a; 73 register const unsigned char *rhaystack, *rneedle; 74 75 do { 76 a = *++haystack; 77 if (a == '\0') 78 goto ret0; 79 if (VAL(a) == VAL(b)) 80 break; 81 a = *++haystack; 82 if (a == '\0') 83 goto ret0; 84 shloop:;} 85 while (VAL(a) != VAL(b)); 86 87 jin:a = *++haystack; 88 if (a == '\0') 89 goto ret0; 90 91 if (VAL(a) != VAL(c)) 92 goto shloop; 93 94 rhaystack = haystack-- + 1; 95 rneedle = needle; 96 a = *rneedle; 97 98 if (VAL(*rhaystack) == VAL(a)) 99 do { 100 if (a == '\0') 101 goto foundneedle; 102 ++rhaystack; 103 a = *++needle; 104 if (VAL(*rhaystack) != VAL(a)) 105 break; 106 if (a == '\0') 107 goto foundneedle; 108 ++rhaystack; 109 a = *++needle; 110 } 111 while (VAL(*rhaystack) == VAL(a)); 112 113 needle = rneedle; /* took the register-poor approach */ 114 115 if (a == '\0') 116 break; 117 } 118 } 119 foundneedle: 120 return (char *) haystack; 121 ret0: 122 return 0; 123} 124#endif 125