home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / libg++-2.7.1-base.tgz / libg++-2.7.1-src.tar / fsf / libg++ / libio / dbz / case.c < prev    next >
C/C++ Source or Header  |  1993-08-20  |  3KB  |  130 lines

  1. /*
  2.  * case-mapping stuff
  3.  *
  4.  * We exploit the fact that we are dealing only with headers here, and
  5.  * headers are limited to the ASCII characters by RFC822.  It is barely
  6.  * possible that we might be dealing with a translation into another
  7.  * character set, but in particular it's very unlikely for a header
  8.  * character to be outside -128..255.
  9.  *
  10.  * Life would be a whole lot simpler if tolower() could safely and portably
  11.  * be applied to any char.
  12.  */
  13. #include <stdio.h>
  14. #include "string.h"
  15. #include "case.h"
  16.  
  17. /* note that case.h knows the value of OFFSET */
  18. #define    OFFSET    128        /* avoid trouble with negative chars */
  19. #define    MAPSIZE    (256+OFFSET)
  20. char casemap[MAPSIZE];        /* relies on init to '\0' */
  21. static int primed = 0;        /* has casemap been set up? */
  22.  
  23. /*
  24.  - prime - set up case-mapping stuff
  25.  */
  26. static void
  27. prime()
  28. {
  29.     register char *lp;
  30.     register char *up;
  31.     register int c;
  32.     register int i;
  33.     static char lower[] = "abcdefghijklmnopqrstuvwxyz";
  34.     static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  35.  
  36.     for (lp = lower, up = upper; *lp != '\0'; lp++, up++) {
  37.         c = *lp;
  38.         casemap[c+OFFSET] = c;
  39.         casemap[*up+OFFSET] = c;
  40.     }
  41.     for (i = 0; i < MAPSIZE; i++)
  42.         if (casemap[i] == '\0')
  43.             casemap[i] = (char)(i-OFFSET);
  44.     primed = 1;
  45. }
  46.  
  47. /*
  48.  - cistrncmp - case-independent strncmp
  49.  */
  50. int                /* < == > 0 */
  51. cistrncmp(s1, s2, len)
  52. char *s1;
  53. char *s2;
  54. int len;
  55. {
  56.     register char *p1;
  57.     register char *p2;
  58.     register int n;
  59.  
  60.     if (!primed)
  61.         prime();
  62.  
  63.     p1 = s1;
  64.     p2 = s2;
  65.     n = len;
  66.     while (--n >= 0 && *p1 != '\0' && TOLOW(*p1) == TOLOW(*p2)) {
  67.         p1++;
  68.         p2++;
  69.     }
  70.     if (n < 0)
  71.         return(0);
  72.  
  73.     /*
  74.      * The following case analysis is necessary so that characters
  75.      * which look negative collate low against normal characters but
  76.      * high against the end-of-string NUL.
  77.      */
  78.     if (*p1 == '\0' && *p2 == '\0')
  79.         return(0);
  80.     else if (*p1 == '\0')
  81.         return(-1);
  82.     else if (*p2 == '\0')
  83.         return(1);
  84.     else
  85.         return(TOLOW(*p1) - TOLOW(*p2));
  86. }
  87.  
  88. /*
  89.  - rfc822ize - do the bizarre case conversion needed for rfc822 message-ids
  90.  *
  91.  * Actually, this is not quite complete.  Absolute, total, full RFC822
  92.  * compliance requires a horrible parsing job, because of the arcane
  93.  * quoting conventions -- abc"def"ghi is not equivalent to abc"DEF"ghi,
  94.  * for example.  There are three or four things that might occur in the
  95.  * domain part of a message-id that are case-sensitive.  They don't seem
  96.  * to ever occur in real news, thank Cthulhu.  (What?  You were expecting
  97.  * a merciful and forgiving deity to be invoked in connection with RFC822?
  98.  * Forget it; none of them would come near it.)
  99.  */
  100. char *                /* returns the argument */
  101. rfc822ize(s)
  102. char *s;
  103. {
  104.     register char *p;
  105.     static char post[] = "postmaster";
  106.     static int postlen = sizeof(post)-1;
  107.  
  108.     if (!primed)
  109.         prime();
  110.  
  111.     p = strrchr(s, '@');
  112.     if (p == NULL)            /* no local/domain split */
  113.         p = "";            /* assume all local */
  114.     else if    (p - (s+1) == postlen && CISTREQN(s+1, post, postlen)) {
  115.         /* crazy special case -- "postmaster" is case-insensitive */
  116.         p = s;
  117.     }
  118. #ifdef NONSTANDARD
  119. #ifdef RFCVIOLATION
  120. #ifdef B_2_11_MISTAKE
  121.     p = s;                /* all case-insensitive */
  122. #endif
  123. #endif
  124. #endif
  125.     for (; *p != '\0'; p++)
  126.         *p = TOLOW(*p);
  127.  
  128.     return(s);
  129. }
  130.