73
by Michael Hope
Added the C only routines from Newlib 1.20+20120605~git3af2fa7 |
1 |
/*
|
2 |
FUNCTION
|
|
3 |
<<memcmp>>---compare two memory areas
|
|
4 |
||
5 |
INDEX
|
|
6 |
memcmp
|
|
7 |
||
8 |
ANSI_SYNOPSIS
|
|
9 |
#include <string.h>
|
|
10 |
int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
|
|
11 |
||
12 |
TRAD_SYNOPSIS
|
|
13 |
#include <string.h>
|
|
14 |
int memcmp(<[s1]>, <[s2]>, <[n]>)
|
|
15 |
void *<[s1]>;
|
|
16 |
void *<[s2]>;
|
|
17 |
size_t <[n]>;
|
|
18 |
||
19 |
DESCRIPTION
|
|
20 |
This function compares not more than <[n]> characters of the
|
|
21 |
object pointed to by <[s1]> with the object pointed to by <[s2]>.
|
|
22 |
||
23 |
||
24 |
RETURNS
|
|
25 |
The function returns an integer greater than, equal to or
|
|
26 |
less than zero according to whether the object pointed to by
|
|
27 |
<[s1]> is greater than, equal to or less than the object
|
|
28 |
pointed to by <[s2]>.
|
|
29 |
||
30 |
PORTABILITY
|
|
31 |
<<memcmp>> is ANSI C.
|
|
32 |
||
33 |
<<memcmp>> requires no supporting OS subroutines.
|
|
34 |
||
35 |
QUICKREF
|
|
36 |
memcmp ansi pure
|
|
37 |
*/
|
|
38 |
||
39 |
#include "shim.h" |
|
40 |
#include <string.h> |
|
41 |
||
42 |
||
43 |
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
|
|
44 |
#define UNALIGNED(X, Y) \
|
|
45 |
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
|
|
46 |
||
47 |
/* How many bytes are copied each iteration of the word copy loop. */
|
|
48 |
#define LBLOCKSIZE (sizeof (long))
|
|
49 |
||
50 |
/* Threshhold for punting to the byte copier. */
|
|
51 |
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
|
|
52 |
||
53 |
int
|
|
54 |
_DEFUN (memcmp, (m1, m2, n), |
|
55 |
_CONST _PTR m1 _AND |
|
56 |
_CONST _PTR m2 _AND |
|
57 |
size_t n) |
|
58 |
{
|
|
59 |
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
|
|
60 |
unsigned char *s1 = (unsigned char *) m1; |
|
61 |
unsigned char *s2 = (unsigned char *) m2; |
|
62 |
||
63 |
while (n--) |
|
64 |
{
|
|
65 |
if (*s1 != *s2) |
|
66 |
{
|
|
67 |
return *s1 - *s2; |
|
68 |
}
|
|
69 |
s1++; |
|
70 |
s2++; |
|
71 |
}
|
|
72 |
return 0; |
|
73 |
#else
|
|
74 |
unsigned char *s1 = (unsigned char *) m1; |
|
75 |
unsigned char *s2 = (unsigned char *) m2; |
|
76 |
unsigned long *a1; |
|
77 |
unsigned long *a2; |
|
78 |
||
79 |
/* If the size is too small, or either pointer is unaligned,
|
|
80 |
then we punt to the byte compare loop. Hopefully this will
|
|
81 |
not turn up in inner loops. */
|
|
82 |
if (!TOO_SMALL(n) && !UNALIGNED(s1,s2)) |
|
83 |
{
|
|
84 |
/* Otherwise, load and compare the blocks of memory one
|
|
85 |
word at a time. */
|
|
86 |
a1 = (unsigned long*) s1; |
|
87 |
a2 = (unsigned long*) s2; |
|
88 |
while (n >= LBLOCKSIZE) |
|
89 |
{
|
|
90 |
if (*a1 != *a2) |
|
91 |
break; |
|
92 |
a1++; |
|
93 |
a2++; |
|
94 |
n -= LBLOCKSIZE; |
|
95 |
}
|
|
96 |
||
97 |
/* check m mod LBLOCKSIZE remaining characters */
|
|
98 |
||
99 |
s1 = (unsigned char*)a1; |
|
100 |
s2 = (unsigned char*)a2; |
|
101 |
}
|
|
102 |
||
103 |
while (n--) |
|
104 |
{
|
|
105 |
if (*s1 != *s2) |
|
106 |
return *s1 - *s2; |
|
107 |
s1++; |
|
108 |
s2++; |
|
109 |
}
|
|
110 |
||
111 |
return 0; |
|
112 |
#endif /* not PREFER_SIZE_OVER_SPEED */ |
|
113 |
}
|
|
114 |