source: trunk/libs/newlib/src/newlib/libc/string/rawmemchr.c @ 567

Last change on this file since 567 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.8 KB
Line 
1/*
2FUNCTION
3        <<rawmemchr>>---find character in memory
4
5INDEX
6        rawmemchr
7
8SYNOPSIS
9        #include <string.h>
10        void *rawmemchr(const void *<[src]>, int <[c]>);
11
12DESCRIPTION
13        This function searches memory starting at <<*<[src]>>> for the
14        character <[c]>.  The search only ends with the first occurrence
15        of <[c]>; in particular, <<NUL>> does not terminate the search.
16        No bounds checking is performed, so this function should only
17        be used when it is certain that the character <[c]> will be found.
18
19RETURNS
20        A pointer to the first occurance of character <[c]>.
21
22PORTABILITY
23<<rawmemchr>> is a GNU extension.
24
25<<rawmemchr>> requires no supporting OS subroutines.
26
27QUICKREF
28        rawmemchr
29*/
30
31#include <_ansi.h>
32#include <string.h>
33#include <limits.h>
34
35/* Nonzero if X is not aligned on a "long" boundary.  */
36#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
37
38/* How many bytes are loaded each iteration of the word copy loop.  */
39#define LBLOCKSIZE (sizeof (long))
40
41/* Threshhold for punting to the bytewise iterator.  */
42#define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
43
44#if LONG_MAX == 2147483647L
45#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
46#else
47#if LONG_MAX == 9223372036854775807L
48/* Nonzero if X (a long int) contains a NULL byte. */
49#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
50#else
51#error long int is not a 32bit or 64bit type.
52#endif
53#endif
54
55#ifndef DETECTNULL
56#error long int is not a 32bit or 64bit byte
57#endif
58
59/* DETECTCHAR returns nonzero if (long)X contains the byte used
60   to fill (long)MASK. */
61#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
62
63void *
64rawmemchr (const void *src_void,
65        int c)
66{
67  const unsigned char *src = (const unsigned char *) src_void;
68  unsigned char d = c;
69
70#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
71  unsigned long *asrc;
72  unsigned long  mask;
73  unsigned int i;
74
75  while (UNALIGNED (src))
76    {
77      if (*src == d)
78        return (void *) src;
79      src++;
80    }
81
82  /* If we get this far, we know that src is word-aligned. */
83  /* The fast code reads the source one word at a time and only
84     performs the bytewise search on word-sized segments if they
85     contain the search character, which is detected by XORing
86     the word-sized segment with a word-sized block of the search
87     character and then detecting for the presence of NUL in the
88     result.  */
89  asrc = (unsigned long *) src;
90  mask = d << 8 | d;
91  mask = mask << 16 | mask;
92  for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
93    mask = (mask << i) | mask;
94
95  while (1)
96    {
97      if (DETECTCHAR (*asrc, mask))
98        break;
99      asrc++;
100    }
101
102  /* We have the matching word, now we resort to a bytewise loop. */
103
104  src = (unsigned char *) asrc;
105
106#endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */
107
108  while (1)
109    {
110      if (*src == d)
111        return (void *) src;
112      src++;
113    }
114}
Note: See TracBrowser for help on using the repository browser.