Subversion Repositories Kolibri OS

Rev

Rev 4872 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
FUNCTION
3
	<>---character string compare
4
 
5
INDEX
6
	strncmp
7
 
8
ANSI_SYNOPSIS
9
	#include 
10
	int strncmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
11
 
12
TRAD_SYNOPSIS
13
	#include 
14
	int strncmp(<[a]>, <[b]>, <[length]>)
15
	char *<[a]>;
16
	char *<[b]>;
17
	size_t <[length]>
18
 
19
DESCRIPTION
20
	<> compares up to <[length]> characters
21
	from the string at <[a]> to the string at <[b]>.
22
 
23
RETURNS
24
	If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
25
	<> returns a number greater than zero.  If the two
26
	strings are equivalent, <> returns zero.  If <<*<[a]>>>
27
	sorts lexicographically before <<*<[b]>>>, <> returns a
28
	number less than zero.
29
 
30
PORTABILITY
31
<> is ANSI C.
32
 
33
<> requires no supporting OS subroutines.
34
 
35
QUICKREF
36
	strncmp ansi pure
37
*/
38
 
39
#include 
40
#include 
41
 
42
/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
43
#define UNALIGNED(X, Y) \
44
  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
45
 
46
/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
47
#if LONG_MAX == 2147483647L
48
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
49
#else
50
#if LONG_MAX == 9223372036854775807L
51
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
52
#else
53
#error long int is not a 32bit or 64bit type.
54
#endif
55
#endif
56
 
57
#ifndef DETECTNULL
58
#error long int is not a 32bit or 64bit byte
59
#endif
60
 
61
int
62
_DEFUN (strncmp, (s1, s2, n),
63
	_CONST char *s1 _AND
64
	_CONST char *s2 _AND
65
	size_t n)
66
{
67
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
68
  if (n == 0)
69
    return 0;
70
 
71
  while (n-- != 0 && *s1 == *s2)
72
    {
73
      if (n == 0 || *s1 == '\0')
74
	break;
75
      s1++;
76
      s2++;
77
    }
78
 
79
  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
80
#else
81
  unsigned long *a1;
82
  unsigned long *a2;
83
 
84
  if (n == 0)
85
    return 0;
86
 
87
  /* If s1 or s2 are unaligned, then compare bytes. */
88
  if (!UNALIGNED (s1, s2))
89
    {
90
      /* If s1 and s2 are word-aligned, compare them a word at a time. */
91
      a1 = (unsigned long*)s1;
92
      a2 = (unsigned long*)s2;
93
      while (n >= sizeof (long) && *a1 == *a2)
94
        {
95
          n -= sizeof (long);
96
 
97
          /* If we've run out of bytes or hit a null, return zero
98
	     since we already know *a1 == *a2.  */
99
          if (n == 0 || DETECTNULL (*a1))
100
	    return 0;
101
 
102
          a1++;
103
          a2++;
104
        }
105
 
106
      /* A difference was detected in last few bytes of s1, so search bytewise */
107
      s1 = (char*)a1;
108
      s2 = (char*)a2;
109
    }
110
 
111
  while (n-- > 0 && *s1 == *s2)
112
    {
113
      /* If we've run out of bytes or hit a null, return zero
114
	 since we already know *s1 == *s2.  */
115
      if (n == 0 || *s1 == '\0')
116
	return 0;
117
      s1++;
118
      s2++;
119
    }
120
  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
121
#endif /* not PREFER_SIZE_OVER_SPEED */
122
}