home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / sp / part01 / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-19  |  3.6 KB  |  210 lines

  1. /* misc.c */
  2.  
  3. /* vi: set tabstop=4 : */
  4.  
  5. #include <ctype.h>
  6. #include <stdio.h>
  7.  
  8. #include "sp.h"
  9.  
  10. /*
  11.  * Special character map that determines what the second character of a word
  12.  * can be; see sp.h
  13.  * May be expanded to contain up to 12 entries plus the terminating entry
  14.  * Must end with an entry of two null bytes
  15.  */
  16. struct spchar_map spchar_map[] = {
  17.     '\'',    QUOTE_CHAR,
  18.     '&',    AMPER_CHAR,
  19.     '.',    PERIOD_CHAR,
  20.     ' ',    SPACE_CHAR,
  21.     '\0',    '\0'
  22. };
  23.  
  24. mk_key(key, soundex, count)
  25. key_t *key;
  26. int soundex;
  27. int count;
  28. {
  29.  
  30.     key[0] = soundex & 0377;
  31.     key[1] = ((soundex & 037400) >> 8) | ((count & 03) << 6);
  32.     key[2] = (count & 01774) >> 2;
  33. #ifdef DEBUG
  34.     if (ex_soundex(key) != soundex)
  35.         fprintf(stderr, "mk_key: soundex failed\n");
  36.     if (ex_count(key) != count)
  37.         fprintf(stderr, "mk_key: count failed\n");
  38. #endif DEBUG
  39. }
  40.  
  41. ex_soundex(key)
  42. key_t *key;
  43. {
  44.     register int soundex;
  45.  
  46.     soundex = key[0] & 0377;
  47.     soundex |= (key[1] & 077) << 8;
  48.     return(soundex);
  49. }
  50.  
  51. ex_count(key)
  52. key_t *key;
  53. {
  54.     register int count;
  55.  
  56.     count = (key[1] & 0300) >> 6;
  57.     count |= ((key[2] & 0377) << 2);
  58.     return(count);
  59. }
  60.  
  61. /*
  62. ex_char(key)
  63. key_t *key;
  64. {
  65.     int ch;
  66.  
  67.     ch = (key[1] & 076) >> 1;
  68.     return(ch + 'a');
  69. }
  70. */
  71.  
  72. /*
  73.  * Unpack a word given the retrieved word of length len and its soundex
  74.  * Extract the first letter from the soundex code
  75.  * If the length is 1 and if it is marked as a single character word
  76.  * then the marked character will be overlaid with a null
  77.  * otherwise a null will be appended to the string
  78.  * Adjust for upper case leading character if necessary
  79.  * Return address of the copy
  80.  */
  81. char *
  82. mk_word(p, len, s)
  83. char *p;
  84. int len, s;
  85. {
  86.     register char *q, ch;
  87.     static char word[MAXWORDLEN + 2];
  88.  
  89.     q = word;
  90.     if (len == 1 && (*p & SINGLE_CHAR)) {
  91.         *(q + 1) = '\0';
  92.         len = 0;
  93.     }
  94.     else
  95.         *(q + len + 1) = '\0';
  96.  
  97.     /*
  98.      * Extract the first character from the soundex and
  99.      * adjust case
  100.      */
  101.     if (*p & UPPER_CHAR)
  102.         ch = (s & 037) + 'A';
  103.     else
  104.         ch = (s & 037) + 'a';
  105.     *q++ = ch;
  106.  
  107.     if (len != 0) {                /* if more than one char adjust second char */
  108.         ch = *p & MASK_CHAR;
  109.         if (ch < 26)
  110.             ch += 'a';
  111.         else if (ch < 52)
  112.             ch = ch - 26 + 'A';
  113.         else if ((ch = fromspchar(ch)) == '\0') {
  114.             fprintf(stderr, "Bogus second char in mk_word\n");
  115.             exit(1);
  116.         }
  117.         *q++ = ch;
  118.         p++;
  119.         len--;
  120.     }
  121.  
  122.     while (len-- > 0)
  123.         *q++ = *p++;
  124.     return(word);
  125. }
  126.  
  127. /*
  128.  * Convert the second character of a word to a special character code
  129.  * Return null if there is no mapping
  130.  */
  131. tospchar(ch)
  132. char ch;
  133. {
  134.     register struct spchar_map *m;
  135.  
  136.     for (m = spchar_map; m->spchar != '\0'; m++)
  137.         if (ch == m->spchar)
  138.             break;
  139.     return(m->code);
  140. }
  141.  
  142. /*
  143.  * Convert from the special character code to the ASCII code
  144.  * Return null if there is no mapping
  145.  */
  146. fromspchar(ch)
  147. char ch;
  148. {
  149.     register struct spchar_map *m;
  150.  
  151.     for (m = spchar_map; m->spchar != '\0'; m++)
  152.         if (ch == m->code)
  153.             break;
  154.     return(m->spchar);
  155. }
  156.  
  157. /*
  158.  * Compare two strings, independent of case, given their lengths
  159.  */
  160. /*
  161. strnmatch(str1, len1, str2, len2)
  162. char *str1, *str2;
  163. int len1, len2;
  164. {
  165.     register char ch1, ch2;
  166.  
  167.     if (len1 != len2)
  168.         return(0);
  169.     while (len1-- > 0) {
  170.         ch1 = *str1++;
  171.         ch2 = *str2++;
  172.         if (ch1 != ch2) {
  173.             if (isupper(ch1))
  174.                 ch1 = tolower(ch1);
  175.             if (isupper(ch2))
  176.                 ch2 = tolower(ch2);
  177.             if (ch1 != ch2)
  178.                 return(0);
  179.         }
  180.     }
  181.     return(1);
  182. }
  183. */
  184.  
  185. /*
  186.  * Compare two strings, independent of case
  187.  */
  188. strmatch(p, q)
  189. char *p, *q;
  190. {
  191.     register char ch1, ch2;
  192.  
  193.     while (1) {
  194.         ch1 = *p++;
  195.         ch2 = *q++;
  196.         if (ch1 == '\0' || ch2 == '\0')
  197.             break;
  198.         if (ch1 != ch2) {
  199.             if (isupper(ch1))
  200.                 ch1 = tolower(ch1);
  201.             if (isupper(ch2))
  202.                 ch2 = tolower(ch2);
  203.             if (ch1 != ch2)
  204.                 break;
  205.         }
  206.     }
  207.     return(ch1 - ch2);
  208. }
  209.  
  210.