home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / src / strcmp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  2.7 KB  |  127 lines

  1. /* In SunOS 4.1.1 the strcmp and strncmp functions reference memory
  2.    past the last byte of the string! This will core dump if the memory 
  3.    following the last byte is not mapped.
  4.  
  5.    Here are correct versions by hbs@lucid.com.
  6. */
  7.  
  8. #include <string.h>
  9. #define ALIGNED(x) (!(((unsigned long) (x)) & (sizeof (unsigned long) - 1)))
  10.  
  11. #define MAGIC    0x7efefeff
  12. #define HIGH_BIT_P(c) ((c) & hi_bit)
  13. #define HAS_ZERO(c) (((((c) + magic) ^ (c)) & not_magic) != not_magic)
  14.  
  15. int
  16. strcmp (const char *x, const char *y)
  17. {
  18.   if (x == y)
  19.     return 0;
  20.   else if (ALIGNED (x) && ALIGNED (y))
  21.     {
  22.       register unsigned long *x1 = (unsigned long *) x;
  23.       register unsigned long *y1 = (unsigned long *) y;
  24.       register unsigned long c;
  25.       register unsigned long magic = MAGIC;
  26.       register unsigned long not_magic = ~magic;
  27.       register unsigned long hi_bit = 0x80000000;
  28.  
  29.       while ((c = *x1) == *y1)
  30.         {
  31.           if (HAS_ZERO(c)) 
  32.             {
  33.               if (!HIGH_BIT_P (c))
  34.                 return 0;
  35.               else
  36.                 {
  37.                   x = (char *) x1;
  38.                   y = (char *) y1;
  39.                   goto slow_loop;
  40.                 }
  41.             }
  42.               
  43.           x1++; 
  44.           y1++;
  45.         }
  46.  
  47.       x = (char *) x1;
  48.       y = (char *) y1;
  49.       goto slow_loop;
  50.     }
  51.   else
  52.     {
  53.       char c;
  54.  
  55.     slow_loop:
  56.  
  57.       while ((c = *x) == *y)
  58.         {
  59.           if (c == (char) 0) return 0;
  60.           x++; 
  61.           y++;
  62.         }
  63.       return (*x - *y);
  64.     }
  65. }
  66.  
  67.  
  68. int
  69. strncmp (const char *x, const char *y, size_t n)
  70. {
  71.   if ((x == y) || (n <= 0))
  72.     return 0;
  73.   else if (ALIGNED (x) && ALIGNED (y))
  74.     {
  75.       register unsigned long *x1 = (unsigned long *) x;
  76.       register unsigned long *y1 = (unsigned long *) y;
  77.       register unsigned long c;
  78.       register unsigned long magic = MAGIC;
  79.       register unsigned long not_magic = ~magic;
  80.       register unsigned long hi_bit = 0x80000000;
  81.  
  82.       while ((c = *x1) == *y1)
  83.         {
  84.           n -= sizeof (unsigned long);
  85.           if (n <= 0)
  86.             return 0;
  87.           
  88.           if (HAS_ZERO(c)) 
  89.             {
  90.               if (!HIGH_BIT_P (c))
  91.                 return 0;
  92.               else
  93.                 {
  94.                   x = (char *) x1;
  95.                   y = (char *) y1;
  96.                   goto slow_loop;
  97.                 }
  98.             }
  99.               
  100.           x1++; 
  101.           y1++;
  102.         }
  103.  
  104.       x = (char *) x1;
  105.       y = (char *) y1;
  106.       goto slow_loop;
  107.     }
  108.   else
  109.     {
  110.       char c;
  111.  
  112.     slow_loop:
  113.  
  114.       while ((c = *x) == *y)
  115.         {
  116.           n--;
  117.           if (n <= 0)
  118.             return 0;
  119.           if (c == (char) 0) 
  120.             return 0;
  121.           x++; 
  122.           y++;
  123.         }
  124.       return (*x - *y);
  125.     }
  126. }
  127.