/* FUNCTION <>---search for character in string INDEX strchr SYNOPSIS #include char * strchr(const char *<[string]>, int <[c]>); DESCRIPTION This function finds the first occurence of <[c]> (converted to a char) in the string pointed to by <[string]> (including the terminating null character). RETURNS Returns a pointer to the located character, or a null pointer if <[c]> does not occur in <[string]>. PORTABILITY <> is ANSI C. <> requires no supporting OS subroutines. QUICKREF strchr ansi pure */ #include #include #include "local.h" char * strchr (const char *s1, int i) { const unsigned char *s = (const unsigned char *)s1; unsigned char c = i; #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) unsigned long mask,j; unsigned long *aligned_addr; /* Special case for finding 0. */ if (!c) { while (UNALIGNED_X(s)) { if (!*s) return (char *) s; s++; } /* Operate a word at a time. */ aligned_addr = (unsigned long *) s; while (!DETECT_NULL(*aligned_addr)) aligned_addr++; /* Found the end of string. */ s = (const unsigned char *) aligned_addr; while (*s) s++; return (char *) s; } /* All other bytes. Align the pointer, then search a long at a time. */ while (UNALIGNED_X(s)) { if (!*s) return NULL; if (*s == c) return (char *) s; s++; } mask = c; for (j = 8; j < sizeof(mask) * 8; j <<= 1) mask = (mask << j) | mask; aligned_addr = (unsigned long *) s; while (!DETECT_NULL(*aligned_addr) && !DETECT_CHAR(*aligned_addr, mask)) aligned_addr++; /* The block of bytes currently pointed to by aligned_addr contains either a null or the target char, or both. We catch it using the bytewise search. */ s = (unsigned char *) aligned_addr; #endif /* not PREFER_SIZE_OVER_SPEED */ while (*s && *s != c) s++; if (*s == c) return (char *)s; return NULL; }