home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff314.lha / zc / zc.lzh / Examples / Stdio / Translit / translit.c < prev    next >
C/C++ Source or Header  |  1988-07-17  |  5KB  |  258 lines

  1. /*
  2.  * Translit.c - Remap Characters
  3.  *
  4.  * Adapted from Kernighan and Plauger's "Software Tools"
  5.  *         into "C" by Jeff Lydiatt
  6.  *         22 Dec 1985
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11.  
  12. #define MAXSET   81
  13. #define MAXARR   81
  14. #define ESCAPE   '@'
  15. #define NOT      '!'
  16. #define DASH     '-'
  17. #define EOS      '\0'
  18. #define YES      1
  19. #define NO       0
  20. #define TRUE     1
  21. #define FALSE     0
  22.  
  23. main (argc, argv)
  24. int argc;
  25. char *argv[];
  26. {
  27.  
  28. char arg[MAXARR];
  29. register char c;
  30. char from[MAXSET], to[MAXSET];
  31. int makeset();
  32. int allbut, collapse;
  33. register int i, lastto;
  34. int xindex();
  35. extern int strlen();
  36. extern int Enable_Abort;
  37.  
  38. Enable_Abort = YES;
  39. if (setcmd(argc, argv, 1, arg, MAXARR) == FALSE)
  40.    error("Usage: Translit <from >to FromSet ToSet.");
  41. else if (arg[0] == NOT)
  42.    {
  43.     allbut = YES;
  44.     if (makeset(arg, 1, from, MAXSET) == NO)
  45.        error("FromSet: too large.");
  46.    }
  47. else
  48.    {
  49.     allbut = NO;
  50.     if (makeset(arg, 0, from, MAXSET) == NO)
  51.       error("FromSet: too large");
  52.    }
  53.  
  54. if (setcmd(argc, argv, 2, arg, MAXARR) == FALSE)
  55.   to[0] = EOS;
  56. else if (makeset(arg, 0, to, MAXSET) == NO)
  57.   error("ToSet: too large.");
  58.  
  59. lastto = strlen(to) - 1;
  60. if (strlen(from) >= lastto || allbut == YES)
  61.    collapse = YES;
  62. else
  63.    collapse = NO;
  64. do
  65.   {
  66.    i = xindex(from, c = getchar(), allbut, lastto);
  67.    if (feof(stdin))
  68.       break;
  69.    if (collapse == YES && i >= lastto && lastto >= 0)
  70.      {
  71.       putchar(to[lastto]); /* Collapse */
  72.       do
  73.         {
  74.          i = xindex (from, c = getchar(), allbut, lastto);
  75.         }
  76.         while (i >= lastto && !feof(stdin));
  77.      }
  78.    if (feof(stdin))
  79.      break;
  80.    if (i >= 0 && lastto >= 0)
  81.       putchar(to[i]); /* translate */
  82.    else if (i < 0)
  83.       putchar(c);     /* copy */
  84.    else ;          /* Delete */
  85.   }
  86.     while(TRUE);
  87. }
  88.  
  89. /* makeset: creates the from and to sets by calling fillset
  90.             and addset */
  91.  
  92. int makeset (str, k, set, size)
  93.    int k, size;
  94.    char str[], set[];
  95. {
  96.    int i, j;
  97.    int addset();
  98.  
  99.    i = k;
  100.    j = 0;
  101.    fillset(EOS, str, &i, set, &j, size);
  102.    return addset(EOS, set, &j, size);
  103. }
  104.  
  105. /* addset: - put c in set(j) if it fits, increment j */
  106.  
  107. int addset (c, set, j, maxsize)
  108.    char c, set[];
  109.    int *j, maxsize;
  110. {
  111.    if (*j > maxsize)
  112.      return NO;
  113.    else
  114.      {
  115.       set[(*j)++] = c;
  116.       return YES;
  117.      }
  118. }
  119.  
  120. /* fillset: expand set at str(i) into set(j), stop at delim */
  121.  
  122.    fillset (delim, str, i, set, j, maxset)
  123.    int *i, *j, maxset;
  124.    char str[], delim, set[];
  125. {
  126.    char esc();
  127.    int  junk;
  128.    static char * digits = "0123456789";
  129.    static char * lowalf = "abcdefghijklmnopqrstuvwxyz";
  130.    static char * upalf  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  131.  
  132.    for (; str[*i] != delim && str[*i] != EOS; (*i)++)
  133.      {
  134.       if (str[*i] == ESCAPE)
  135.          junk = addset(esc(str, i), set, j, maxset);
  136.       else if (str[*i] != DASH)
  137.          junk = addset(str[*i], set, j, maxset);
  138.       else if (*j <= 0  || str[*i+1] == EOS) /* literal - */
  139.          junk = addset(DASH, set, j, maxset);
  140.       else if (isdigit(set[*j-1]))
  141.          dodash (digits, str, i, set, j, maxset);
  142.       else if (islower(set[*j-1]))
  143.          dodash(lowalf, str, i, set, j, maxset);
  144.       else if (isupper(set[*j-1]))
  145.          dodash(upalf, str, i, set, j, maxset);
  146.       else
  147.           junk = addset(DASH, set, j, maxset);
  148.     }
  149. }
  150.  
  151. /* esc --- map str(i) into escaped character */
  152.  
  153. char esc (str, i)
  154.    char str[];
  155.    int *i;
  156. {
  157.    if (str[*i] != ESCAPE)
  158.       return str[*i];
  159.    else if (str[*i+1] == EOS) /* Esc not special at end */
  160.       return ESCAPE;
  161.    else
  162.       switch (str[++(*i)])
  163.         {
  164.          case 'n': return '\n';
  165.          case 'r': return '\r';
  166.          case 't': return '\t';
  167.          default:  return str[*i];
  168.         }
  169. }
  170.  
  171. /* dodash: expand str(i-1) to str(i+1) into set(j) */
  172.  
  173. dodash (valid, str, i, set, j, maxset)
  174. char valid[], str[], set[];
  175. int  *i, *j, maxset;
  176. {
  177.    char esc();
  178.    int junk, addset();
  179.    int k, limit;
  180.    int index();
  181.    (*i)++;
  182.    (*j)--;
  183.    limit = index (valid, esc(str, i));
  184.    for (k = index(valid, set[*j]); k <= limit; k++)
  185.       junk = addset (valid[k], set, j, maxset);
  186. }
  187.  
  188. /* index: find the character c in string str */
  189.  
  190. int index (str, c)
  191. char str[], c;
  192. {
  193.    register int i;
  194.  
  195.    for (i = 0; str[i] != EOS; i++)
  196.       {
  197.        if (str[i] == c)
  198.           return i;
  199.       }
  200.    return (int) -1;
  201. }
  202.  
  203. /* xindex: invert the condition returned by index */
  204.  
  205. int xindex (str, c, allbut, lastto)
  206. char str[], c;
  207. int allbut, lastto;
  208. {
  209.    int index();
  210.  
  211.    if (c == EOF)
  212.       return (int) -1;
  213.    else if (allbut == NO)
  214.        return index(str, c);
  215.    else if (index(str, c) >= 0)
  216.       return (int) -1;
  217.    else
  218.       return (int) (lastto + 1);
  219. }
  220.  
  221. /* error: Print error message and quit */
  222.  
  223. error(msg)
  224. char * msg;
  225. {
  226.    extern void exit();
  227.    fputs(msg, stderr);
  228.    fputs("\n", stderr);
  229.    exit(12);
  230. }
  231.  
  232. /* setcmd: set the n'th command line parameter into str */
  233.  
  234. setcmd (Nargs, Arg, n, str, maxsize)
  235. int Nargs, n, maxsize;
  236. char *Arg[], str[];
  237. {
  238.    register char *s1, *s2, *smax;
  239.  
  240.    if (n >= Nargs)
  241.      return FALSE;
  242.    s1 = Arg[n];
  243.    s2 = str;
  244.    smax = s1 + maxsize - 2;
  245.    if (*s1 == '"')
  246.       {
  247.        for (++s1; *s1 != EOS && *s1 != '"' && s1 < smax;)
  248.           *s2++ = *s1++;
  249.       }
  250.    else
  251.       {
  252.        for (; *s1 != EOS && s1 < smax;)
  253.           *s2++ = *s1++;
  254.       }
  255.    *s2 = EOS;
  256.    return TRUE;
  257. }
  258.