Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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