mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-01 11:52:47 +00:00
122 lines
2.9 KiB
C
122 lines
2.9 KiB
C
|
/*
|
||
|
FUNCTION
|
||
|
<<strstr>>---find string segment
|
||
|
|
||
|
INDEX
|
||
|
strstr
|
||
|
|
||
|
ANSI_SYNOPSIS
|
||
|
#include <string.h>
|
||
|
char *strstr(const char *<[s1]>, const char *<[s2]>);
|
||
|
|
||
|
TRAD_SYNOPSIS
|
||
|
#include <string.h>
|
||
|
char *strstr(<[s1]>, <[s2]>)
|
||
|
char *<[s1]>;
|
||
|
char *<[s2]>;
|
||
|
|
||
|
DESCRIPTION
|
||
|
Locates the first occurrence in the string pointed to by <[s1]> of
|
||
|
the sequence of characters in the string pointed to by <[s2]>
|
||
|
(excluding the terminating null character).
|
||
|
|
||
|
RETURNS
|
||
|
Returns a pointer to the located string segment, or a null
|
||
|
pointer if the string <[s2]> is not found. If <[s2]> points to
|
||
|
a string with zero length, <[s1]> is returned.
|
||
|
|
||
|
PORTABILITY
|
||
|
<<strstr>> is ANSI C.
|
||
|
|
||
|
<<strstr>> requires no supporting OS subroutines.
|
||
|
|
||
|
QUICKREF
|
||
|
strstr ansi pure
|
||
|
*/
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
|
||
|
# define RETURN_TYPE char *
|
||
|
# define AVAILABLE(h, h_l, j, n_l) \
|
||
|
(!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
|
||
|
&& ((h_l) = (j) + (n_l)))
|
||
|
# include "str-two-way.h"
|
||
|
#endif
|
||
|
|
||
|
char *
|
||
|
_DEFUN (strstr, (searchee, lookfor),
|
||
|
_CONST char *searchee _AND
|
||
|
_CONST char *lookfor)
|
||
|
{
|
||
|
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
|
||
|
|
||
|
/* Less code size, but quadratic performance in the worst case. */
|
||
|
if (*searchee == 0)
|
||
|
{
|
||
|
if (*lookfor)
|
||
|
return (char *) NULL;
|
||
|
return (char *) searchee;
|
||
|
}
|
||
|
|
||
|
while (*searchee)
|
||
|
{
|
||
|
size_t i;
|
||
|
i = 0;
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
if (lookfor[i] == 0)
|
||
|
{
|
||
|
return (char *) searchee;
|
||
|
}
|
||
|
|
||
|
if (lookfor[i] != searchee[i])
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
searchee++;
|
||
|
}
|
||
|
|
||
|
return (char *) NULL;
|
||
|
|
||
|
#else /* compilation for speed */
|
||
|
|
||
|
/* Larger code size, but guaranteed linear performance. */
|
||
|
const char *haystack = searchee;
|
||
|
const char *needle = lookfor;
|
||
|
size_t needle_len; /* Length of NEEDLE. */
|
||
|
size_t haystack_len; /* Known minimum length of HAYSTACK. */
|
||
|
int ok = 1; /* True if NEEDLE is prefix of HAYSTACK. */
|
||
|
|
||
|
/* Determine length of NEEDLE, and in the process, make sure
|
||
|
HAYSTACK is at least as long (no point processing all of a long
|
||
|
NEEDLE if HAYSTACK is too short). */
|
||
|
while (*haystack && *needle)
|
||
|
ok &= *haystack++ == *needle++;
|
||
|
if (*needle)
|
||
|
return NULL;
|
||
|
if (ok)
|
||
|
return (char *) searchee;
|
||
|
|
||
|
/* Reduce the size of haystack using strchr, since it has a smaller
|
||
|
linear coefficient than the Two-Way algorithm. */
|
||
|
needle_len = needle - lookfor;
|
||
|
haystack = strchr (searchee + 1, *lookfor);
|
||
|
if (!haystack || needle_len == 1)
|
||
|
return (char *) haystack;
|
||
|
haystack_len = (haystack > searchee + needle_len ? 1
|
||
|
: needle_len + searchee - haystack);
|
||
|
|
||
|
/* Perform the search. */
|
||
|
if (needle_len < LONG_NEEDLE_THRESHOLD)
|
||
|
return two_way_short_needle ((const unsigned char *) haystack,
|
||
|
haystack_len,
|
||
|
(const unsigned char *) lookfor, needle_len);
|
||
|
return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
|
||
|
(const unsigned char *) lookfor, needle_len);
|
||
|
#endif /* compilation for speed */
|
||
|
}
|