Back to index

tetex-bin  3.0
strstr.c
Go to the documentation of this file.
00001 /* Copyright (C) 1994, 95 Free Software Foundation, Inc.
00002 This file was part of the GNU C Library. Modified by kb@mail.tug.org.
00003 
00004 This file is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU Library General Public License as
00006 published by the Free Software Foundation; either version 2 of the
00007 License, or (at your option) any later version.
00008 
00009 This file is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 Library General Public License for more details.
00013 
00014 You should have received a copy of the GNU Library General Public
00015 License along with this file; see the file COPYING.LIB.  If not, write
00016 to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017 Boston, MA 02111-1307, USA.  */
00018 
00019 
00020 /*
00021  * My personal strstr() implementation that beats most other algorithms.
00022  * Until someone tells me otherwise, I assume that this is the
00023  * fastest implementation of strstr() in C.
00024  * I deliberately chose not to comment it.  You should have at least
00025  * as much fun trying to understand it, as I had to write it :-).
00026  *
00027  * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de       */
00028 
00029 #if !defined (__STDC__) || !__STDC__
00030 /* This is a separate conditional since some stdc systems
00031    reject `defined (const)'.  */
00032 #ifndef const
00033 #define const
00034 #endif
00035 #endif
00036 
00037 typedef unsigned chartype;
00038 
00039 char *
00040 strstr (phaystack, pneedle)
00041      const char *phaystack;
00042      const char *pneedle;
00043 {
00044   register const unsigned char *haystack, *needle;
00045   register chartype b, c;
00046 
00047   haystack = (const unsigned char *) phaystack;
00048   needle = (const unsigned char *) pneedle;
00049 
00050   b = *needle;
00051   if (b != '\0')
00052     {
00053       haystack--;                         /* possible ANSI violation */
00054       do
00055        {
00056          c = *++haystack;
00057          if (c == '\0')
00058            goto ret0;
00059        }
00060       while (c != b);
00061 
00062       c = *++needle;
00063       if (c == '\0')
00064        goto foundneedle;
00065       ++needle;
00066       goto jin;
00067 
00068       for (;;)
00069         { 
00070           register chartype a;
00071          register const unsigned char *rhaystack, *rneedle;
00072 
00073          do
00074            {
00075              a = *++haystack;
00076              if (a == '\0')
00077               goto ret0;
00078              if (a == b)
00079               break;
00080              a = *++haystack;
00081              if (a == '\0')
00082               goto ret0;
00083 shloop:           }
00084           while (a != b);
00085 
00086 jin:     a = *++haystack;
00087          if (a == '\0')
00088            goto ret0;
00089 
00090          if (a != c)
00091            goto shloop;
00092 
00093          rhaystack = haystack-- + 1;
00094          rneedle = needle;
00095          a = *rneedle;
00096 
00097          if (*rhaystack == a)
00098            do
00099              {
00100               if (a == '\0')
00101                 goto foundneedle;
00102               ++rhaystack;
00103               a = *++needle;
00104               if (*rhaystack != a)
00105                 break;
00106               if (a == '\0')
00107                 goto foundneedle;
00108               ++rhaystack;
00109               a = *++needle;
00110              }
00111            while (*rhaystack == a);
00112 
00113          needle = rneedle;            /* took the register-poor aproach */
00114 
00115          if (a == '\0')
00116            break;
00117         }
00118     }
00119 foundneedle:
00120   return (char*) haystack;
00121 ret0:
00122   return 0;
00123 }