home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / filutl / tr.arc / TR.C
C/C++ Source or Header  |  1988-07-28  |  5KB  |  193 lines

  1. /* filter to transliterate characters */
  2.  
  3. /*    The program tr implements character transliteration and behaves the same
  4.  *    as the program in Software Tools by the same name.  It is a pure filter.
  5.  */
  6.  
  7.  
  8. #include <stdio.h>
  9.  
  10. #define ESCAPE '@'
  11. #define MAXSET 400
  12. #define NOT '!'
  13.  
  14. xindex(c, s, allbut, lastto) /* reverse sense of index if allbut = YES */
  15. register int c;
  16. char *s;
  17. int allbut, lastto;
  18. {
  19.     int cindex();
  20.  
  21.     if(c == EOF)                return -1;                /* never process EOF */
  22.     else if(allbut == NO)        return cindex(c, s);    /* tell the truth */
  23.     else if(cindex(c, s) >= 0)    return -1;                /* lie */
  24.     else                        return lastto + 1;        /* assure collapse */
  25. }
  26.  
  27. cindex(c, s) /* Find index of character c in string s; return -1 if not found */
  28. char c, s[];
  29. {
  30.     register int i;
  31.  
  32.     for(i = 0; s[i] != '\0'; ++i)
  33.         if(c == s[i]) return(i);
  34.     return(-1);
  35. }
  36.  
  37. char *esc(str) /* handle escape sequence; return pointer to "fixed" character */
  38. register char *str;
  39. {
  40.  
  41.     if(*str != ESCAPE) return(str);     /* nothing to do */
  42.     if(*(str + 1) == '\0') return(str); /* not special at end */
  43.     if(*++str == 'b')    *str = '\b';
  44.     else if(*str == 'f') *str = '\f';
  45.     else if(*str == 'n') *str = '\n';
  46.     else if(*str == 'q') *str = '"';
  47.     else if(*str == 'r') *str = '\r';
  48.     else if(*str == 's') *str = ' ';
  49.     else if(*str == 't') *str = '\t';
  50.     else if(*str == '0')
  51.     {
  52.     char buf[3];
  53.     int atoh();
  54.  
  55.         buf[0] = *++str;
  56.         buf[1] = *++str;
  57.         buf[2] = '\0';
  58.         *str = (char) atoh(buf);
  59.     }
  60.     return(str);
  61. }
  62.  
  63. char *dodash(valid, s, start) /* expand *psetDASH*s into pset ... from valid */
  64. char valid[];
  65. char *s;
  66. int start;
  67. {
  68.     int cindex(), addchar();
  69.     register int i, limit;
  70.  
  71.     if( (limit = cindex(*(s + 1), valid) ) < 0) /* not valid; literal dash */
  72.     {
  73.         addchar('-');
  74.         return s;
  75.     }
  76.     ++s;
  77.     for(i = start; i <= limit; i++)
  78.         addchar(valid[];
  79.     reun s;
  80. }
  81.  
  82. static int count_set;
  83. static char *pset;
  84.  
  85. main(arg,rgv)
  86. int ar;hr*rgv[];
  87. {
  88.     int fill(), addchar(), strln) index(), getchar(), putchar()  char from[MAXSET + 1], to[MAXSET + 1];
  89.     char *caller;
  90.     int allbut, collapse;
  91.     register int i, lastto, c;
  92.  
  93.     caller = *argv;
  94.     if(argc = 1)
  95.     {
  96.         tfprintf(stder"sage: %s from [to]\n", caller);
  97.       ext1);
  98.     }
  99.     pset = from;
  100.     count_set = MAXSET;
  101.     i = 0;
  102.     if((++arv[i] == NOT)
  103.     {        allbut = YES;
  104.       i++;
  105.     }    else
  106.         allbut = NO
  107.    
  108.     if((*argv)[i] = '-')
  109.     
  110.        addchar'');
  111.         i++;
  112.    }
  113.     if(fill(*argv + i) =NO
  114.    {
  115.         tfprint(tderr, "%s: romstis too large\n", caller);
  116.      eit(2);
  117.     }
  118.     if(argc > 2)
  119.     {
  120.         count_set = MAXSET;
  121.         pset = to;
  122.       i = 0;
  123.         if(*++ag)[i] == '-')
  124.         {
  125.            addchar('-');           i+;        }
  126.         if(fill(*arv + i = NO)
  127.         {
  128.             tfprintf(stderr, "%s: to set is too large\n, caller)
  129.            exit(2);
  130.         }
  131.         lastto = strlen(to) - 1;
  132.     }
  133.     else lastto = -1;
  134.  
  135.    if(strlen(from) > lastto || allbut == YES) collapse = YES;
  136.   le                                      collapse = NO;
  137.  
  138.     for(;;)
  139.     {
  140.         i = xindex((c = getchar()), from, allbut, lastto);
  141.       if(collapse == YES && i >= lastto && lastto >= 0)        /* collapse */
  142.         {
  143.             putchar(to[lastto]);
  144.             do i = xindex((c = getchar()), from, allbut, lastto);
  145.                 while(i >= lastto);                    /* skip runs */
  146.         }
  147.         if(c == EOF) break;                         /* done */
  148.  
  149.         if( i >= 0 && lastto >= 0) putchar(to[i]);    /* transliterate */
  150.  
  151.         else if(i == -1) putchar(c);                /* copy */
  152.  
  153.                                                     /* else delete */
  154.     }
  155. }
  156.  
  157. addchar(c) /* add input character to end of set if there is room*
  158. char c;
  159. {
  160.     if(--count_set >= 0)
  161.     {
  162.         *pset++ = c;
  163.         retur YES;
  164.     }
  165.     else return NO    
  166. }
  167.  
  168. static char dgts[] = "0123456789"
  169. tatcchar lower[] = "abcdefghknprtuvwxyz";
  170. static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  171.  
  172. fill(str) /* expand input character set into pset */
  173. register char *str;
  174. {
  175.     char *esc(), *dodash();
  176.     int addchar(), cindex();
  177.     register int i;
  178.  
  179.     for(; *str != '\0'; ++str)
  180.         if(*str != '-' || *(str +1 = '\0') /* not dash or dash at end */
  181.             addchar( *( str = esc(str) ) );
  182.         else if( (i = cindex(*(pset - 1), digits) ) >= 0)
  183.             str = dodash(digits, str, ++i);
  184.         else if( (i = cindex(*(pset - 1), lower) ) >= 0)
  185.             str = dodash(lower, str, ++i);
  186.         else if( (i = cindex(*(pset - 1), upper) ) >= 0)
  187.             str = dodash(upper, str, ++i);
  188.         else
  189.             addchar('-');          /* dash is literal with "other" before it */
  190.             
  191.     return addchar('\0');
  192. }
  193.