114 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
| FUNCTION
 | |
| 	<<memcmp>>---compare two memory areas
 | |
| 
 | |
| INDEX
 | |
| 	memcmp
 | |
| 
 | |
| ANSI_SYNOPSIS
 | |
| 	#include <string.h>
 | |
| 	int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
 | |
| 
 | |
| TRAD_SYNOPSIS
 | |
| 	#include <string.h>
 | |
| 	int memcmp(<[s1]>, <[s2]>, <[n]>)
 | |
| 	void *<[s1]>;
 | |
| 	void *<[s2]>;
 | |
| 	size_t <[n]>;
 | |
| 
 | |
| DESCRIPTION
 | |
| 	This function compares not more than <[n]> characters of the
 | |
| 	object pointed to by <[s1]> with the object pointed to by <[s2]>.
 | |
| 
 | |
| 
 | |
| RETURNS
 | |
| 	The function returns an integer greater than, equal to or
 | |
| 	less than zero 	according to whether the object pointed to by
 | |
| 	<[s1]> is greater than, equal to or less than the object
 | |
| 	pointed to by <[s2]>.
 | |
| 
 | |
| PORTABILITY
 | |
| <<memcmp>> is ANSI C.
 | |
| 
 | |
| <<memcmp>> requires no supporting OS subroutines.
 | |
| 
 | |
| QUICKREF
 | |
| 	memcmp ansi pure
 | |
| */
 | |
| 
 | |
| #include <string.h>
 | |
| 
 | |
| 
 | |
| /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 | |
| #define UNALIGNED(X, Y) \
 | |
|   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
 | |
| 
 | |
| /* How many bytes are copied each iteration of the word copy loop.  */
 | |
| #define LBLOCKSIZE (sizeof (long))
 | |
| 
 | |
| /* Threshhold for punting to the byte copier.  */
 | |
| #define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
 | |
| 
 | |
| int
 | |
| _DEFUN (memcmp, (m1, m2, n),
 | |
| 	_CONST _PTR m1 _AND
 | |
| 	_CONST _PTR m2 _AND
 | |
| 	size_t n)
 | |
| {
 | |
| #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
 | |
|   unsigned char *s1 = (unsigned char *) m1;
 | |
|   unsigned char *s2 = (unsigned char *) m2;
 | |
| 
 | |
|   while (n--)
 | |
|     {
 | |
|       if (*s1 != *s2)
 | |
| 	{
 | |
| 	  return *s1 - *s2;
 | |
| 	}
 | |
|       s1++;
 | |
|       s2++;
 | |
|     }
 | |
|   return 0;
 | |
| #else  
 | |
|   unsigned char *s1 = (unsigned char *) m1;
 | |
|   unsigned char *s2 = (unsigned char *) m2;
 | |
|   unsigned long *a1;
 | |
|   unsigned long *a2;
 | |
| 
 | |
|   /* If the size is too small, or either pointer is unaligned,
 | |
|      then we punt to the byte compare loop.  Hopefully this will
 | |
|      not turn up in inner loops.  */
 | |
|   if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
 | |
|     {
 | |
|       /* Otherwise, load and compare the blocks of memory one 
 | |
|          word at a time.  */
 | |
|       a1 = (unsigned long*) s1;
 | |
|       a2 = (unsigned long*) s2;
 | |
|       while (n >= LBLOCKSIZE)
 | |
|         {
 | |
|           if (*a1 != *a2) 
 | |
|    	    break;
 | |
|           a1++;
 | |
|           a2++;
 | |
|           n -= LBLOCKSIZE;
 | |
|         }
 | |
| 
 | |
|       /* check m mod LBLOCKSIZE remaining characters */
 | |
| 
 | |
|       s1 = (unsigned char*)a1;
 | |
|       s2 = (unsigned char*)a2;
 | |
|     }
 | |
| 
 | |
|   while (n--)
 | |
|     {
 | |
|       if (*s1 != *s2)
 | |
| 	return *s1 - *s2;
 | |
|       s1++;
 | |
|       s2++;
 | |
|     }
 | |
| 
 | |
|   return 0;
 | |
| #endif /* not PREFER_SIZE_OVER_SPEED */
 | |
| }
 | |
| 
 |