home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 9 / amigaformatcd09.iso / coverdisks / subsdisk / subs.dms / subs.adf / cookie.LZX / cookietool / src / strstuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-03  |  4.1 KB  |  145 lines

  1. /*************************************************************************\
  2.                   strstuff.c: a set of string functions, 
  3.       more powerful than those from the standard library in <string.h>
  4. \*************************************************************************/
  5.  
  6. #include <stddef.h>
  7. #include <stdio.h>
  8. #include "strstuff.h"
  9.  
  10. UBYTE to_upper[256];     /* conversion table */
  11. int is_space[256];       /* lookup table */
  12. int bordermode, case_sense;
  13.  
  14. void str_setup(int bm, int cs)
  15. /* Set up a conversion table that can convert all national characters from
  16.  * the ISO 8859-1/ECMA 94 charset to uppercase, not only 'a'-'z'.
  17.  * Depending on the global variable <case_sense> this table may just as 
  18.  * well do nothing at all.  Similarly, the is_space[] table which is built
  19.  * here, too, may call anything but alphanumerics a 'space', depending on
  20.  * the setting of <bordermode>.
  21.  */
  22. {
  23.   int c,d;
  24.  
  25.   bordermode = bm; case_sense = cs;  /* set global variables */
  26.   for (c=0; c<256; c++) {
  27.     to_upper[c] = c;
  28.     is_space[c] = (bordermode<2 || (c & 0x7f)<=' ');
  29.   }
  30.   for (c='a'; c<='z'; c++) {
  31.     d = c + 'A'-'a'; to_upper[c] = d;
  32.     is_space[c] = 0; is_space[d] = 0;
  33.   }
  34.   for (c='0'; c<='9'; c++) {
  35.     is_space[c] = 0;
  36.   }
  37.   for (c=224; c<256; c++)
  38.     if (c != 247) {         /* 247 is the division sign -:- */
  39.       d = c - 32; 
  40.       is_space[c] = 0; is_space[d] = 0;
  41.       if (c != 255)         /* and don't convert '"y' to 'ss' :) */
  42.         to_upper[c] = d;
  43.     }
  44.   if (case_sense)     /* destroy the to_upper[] table again */
  45.     for (c=0; c<256; c++)
  46.       to_upper[c] = c;
  47.   is_space[0] = 0;    /* important, will be taken advantage of! */
  48. }
  49.  
  50.  
  51. int str_cmp(UBYTE *s, UBYTE *t)
  52. /* Will work like strcmp(), if (case_sense && bordermode == 3), but can
  53.  * change its behaviour depending on those variables.
  54.  * Will also indicate by special (but legal) return values if <s> was an 
  55.  * abbreviation of <t> or vice versa.
  56.  */
  57. {
  58.   if (bordermode<3) {    /* modes where number of 'spaces' doesn't count */
  59.     while (is_space[*s]) s++;  /* advance to first word */
  60.     while (is_space[*t]) t++;
  61.     while (to_upper[*s] == to_upper[*t]) {
  62.       if (*s == '\0')  return 0;
  63.       s++; t++;
  64.       if (!bordermode || is_space[*s] && is_space[*t]) {
  65.         /* both at the end of a word OR in sloppy bordermode */
  66.         while (is_space[*s]) s++;  /* skip the spaces */
  67.         while (is_space[*t]) t++;
  68.       }
  69.     }
  70.   } else {
  71.     while (to_upper[*s] == to_upper[*t]) {
  72.       if (*s == '\0')  return 0;
  73.       s++; t++;
  74.     }
  75.   }
  76.   if (*s=='\0')
  77.     return STR_SHORTER;
  78.   else if (*t=='\0')
  79.     return STR_LONGER;
  80.   else
  81.     return (to_upper[*s] - to_upper[*t]);
  82. }
  83.  
  84.  
  85. int strn_cmp(UBYTE *s, UBYTE *t, size_t n)
  86. /* The same as str_cmp, but will only compare up to <n> characters.
  87.  * (Only two lines of code are different.)
  88.  */
  89. {
  90.   if (bordermode<3) {
  91.     while (is_space[*s]) s++;
  92.     while (is_space[*t]) t++;
  93.     while (to_upper[*s] == to_upper[*t]) {
  94.       if (--n == 0 || *s == '\0')  return 0;   /* that's the difference */
  95.       s++; t++;
  96.       if (!bordermode || is_space[*s] && is_space[*t]) {
  97.         while (is_space[*s]) s++;
  98.         while (is_space[*t]) t++;
  99.       }
  100.     }
  101.   } else {
  102.     while (to_upper[*s] == to_upper[*t]) {
  103.       if (--n == 0 || *s == '\0')  return 0;   /* and here once more */
  104.       s++; t++;
  105.     }
  106.   }
  107.   if (*s=='\0')
  108.     return STR_SHORTER;
  109.   else if (*t=='\0')
  110.     return STR_LONGER;
  111.   else
  112.     return (to_upper[*s] - to_upper[*t]);
  113. }
  114.  
  115.  
  116. UBYTE *str_str(UBYTE *s, UBYTE *t)
  117. /* find a copy of t in s, like strstr() does */
  118. {
  119.   int c;
  120.  
  121.   while (*s) {
  122.     c = str_cmp(s, t);
  123.     if (c == 0 || c == STR_LONGER)
  124.       return s;
  125.     s++;
  126.   }
  127.   return NULL;
  128. }
  129.  
  130.  
  131. void print_strstat(void)
  132. /* some user info printed to <stdout> */
  133. {
  134.   printf("string processing:\n");
  135.   printf("  upper-/lowercase: ");
  136.   if (case_sense) printf("fussy\n"); else printf("'ABC'='abc'\n");
  137.   printf("  word delimiters:  ");
  138.   switch (bordermode) {
  139.     case 0: printf("'a,b c'='abc'\n"); break;
  140.     case 1: printf("'a, b, c'='a,b c'\n"); break;
  141.     case 2: printf("'a  b  c'='a b c'\n"); break;
  142.     case 3: printf("fussy\n"); break;
  143.   }
  144. }
  145.