home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / LIBSRC.ZOO / libsrc / gen / unvis.c < prev    next >
C/C++ Source or Header  |  1992-02-01  |  6KB  |  253 lines

  1. /*-
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if defined(LIBC_SCCS) && !defined(lint)
  35. static char sccsid[] = "@(#)unvis.c    1.4 (Berkeley) 2/23/91";
  36. #endif /* LIBC_SCCS and not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <ctype.h>
  40. #include <vis.h>
  41.  
  42. /*
  43.  * decode driven by state machine
  44.  */
  45. #define    S_GROUND    0    /* haven't seen escape char */
  46. #define    S_START        1    /* start decoding special sequence */
  47. #define    S_META        2    /* metachar started (M) */
  48. #define    S_META1        3    /* metachar more, regular char (-) */
  49. #define    S_CTRL        4    /* control char started (^) */
  50. #define    S_OCTAL2    5    /* octal digit 2 */
  51. #define    S_OCTAL3    6    /* octal digit 3 */
  52.  
  53. #define    isoctal(c)    (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
  54.  
  55. /*
  56.  * unvis - decode characters previously encoded by vis
  57.  */
  58. int
  59. #if __STDC__
  60. unvis(char *cp, char c, int *astate, int flag)
  61. #else
  62. unvis(cp, c, astate, flag)
  63.     char *cp, c;
  64.     int *astate, flag;
  65. #endif
  66. {
  67.  
  68.     if (flag & UNVIS_END) {
  69.         if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
  70.             *astate = S_GROUND;
  71.             return (UNVIS_VALID);
  72.         } 
  73.         return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
  74.     }
  75.  
  76.     switch (*astate) {
  77.  
  78.     case S_GROUND:
  79.         *cp = 0;
  80.         if (c == '\\') {
  81.             *astate = S_START;
  82.             return (0);
  83.         } 
  84.         *cp = c;
  85.         return (UNVIS_VALID);
  86.  
  87.     case S_START:
  88.         switch(c) {
  89.         case '\\':
  90.             *cp = c;
  91.             *astate = S_GROUND;
  92.             return (UNVIS_VALID);
  93.         case '0': case '1': case '2': case '3':
  94.         case '4': case '5': case '6': case '7':
  95.             *cp = (c - '0');
  96.             *astate = S_OCTAL2;
  97.             return (0);
  98.         case 'M':
  99.             *cp = 0200;
  100.             *astate = S_META;
  101.             return (0);
  102.         case '^':
  103.             *astate = S_CTRL;
  104.             return (0);
  105.         case 'n':
  106.             *cp = '\n';
  107.             *astate = S_GROUND;
  108.             return (UNVIS_VALID);
  109.         case 'r':
  110.             *cp = '\r';
  111.             *astate = S_GROUND;
  112.             return (UNVIS_VALID);
  113.         case 'b':
  114.             *cp = '\b';
  115.             *astate = S_GROUND;
  116.             return (UNVIS_VALID);
  117.         case 'a':
  118.             *cp = '\007';
  119.             *astate = S_GROUND;
  120.             return (UNVIS_VALID);
  121.         case 'v':
  122.             *cp = '\v';
  123.             *astate = S_GROUND;
  124.             return (UNVIS_VALID);
  125.         case 't':
  126.             *cp = '\t';
  127.             *astate = S_GROUND;
  128.             return (UNVIS_VALID);
  129.         case 'f':
  130.             *cp = '\f';
  131.             *astate = S_GROUND;
  132.             return (UNVIS_VALID);
  133.         case 's':
  134.             *cp = ' ';
  135.             *astate = S_GROUND;
  136.             return (UNVIS_VALID);
  137.         case 'E':
  138.             *cp = '\033';
  139.             *astate = S_GROUND;
  140.             return (UNVIS_VALID);
  141.         case '\n':
  142.             /*
  143.              * hidden newline
  144.              */
  145.             *astate = S_GROUND;
  146.             return (UNVIS_NOCHAR);
  147.         case '$':
  148.             /*
  149.              * hidden marker
  150.              */
  151.             *astate = S_GROUND;
  152.             return (UNVIS_NOCHAR);
  153.         }
  154.         *astate = S_GROUND;
  155.         return (UNVIS_SYNBAD);
  156.          
  157.     case S_META:
  158.         if (c == '-')
  159.             *astate = S_META1;
  160.         else if (c == '^')
  161.             *astate = S_CTRL;
  162.         else {
  163.             *astate = S_GROUND;
  164.             return (UNVIS_SYNBAD);
  165.         }
  166.         return (0);
  167.          
  168.     case S_META1:
  169.         *astate = S_GROUND;
  170.         *cp |= c;
  171.         return (UNVIS_VALID);
  172.          
  173.     case S_CTRL:
  174.         if (c == '?')
  175.             *cp |= 0177;
  176.         else
  177.             *cp |= c & 037;
  178.         *astate = S_GROUND;
  179.         return (UNVIS_VALID);
  180.  
  181.     case S_OCTAL2:    /* second possible octal digit */
  182.         if (isoctal(c)) {
  183.             /* 
  184.              * yes - and maybe a third 
  185.              */
  186.             *cp = (*cp << 3) + (c - '0');
  187.             *astate = S_OCTAL3;    
  188.             return (0);
  189.         } 
  190.         /* 
  191.          * no - done with current sequence, push back passed char 
  192.          */
  193.         *astate = S_GROUND;
  194.         return (UNVIS_VALIDPUSH);
  195.  
  196.     case S_OCTAL3:    /* third possible octal digit */
  197.         *astate = S_GROUND;
  198.         if (isoctal(c)) {
  199.             *cp = (*cp << 3) + (c - '0');
  200.             return (UNVIS_VALID);
  201.         }
  202.         /*
  203.          * we were done, push back passed char
  204.          */
  205.         return (UNVIS_VALIDPUSH);
  206.             
  207.     default:    
  208.         /* 
  209.          * decoder in unknown state - (probably uninitialized) 
  210.          */
  211.         *astate = S_GROUND;
  212.         return (UNVIS_SYNBAD);
  213.     }
  214. }
  215.  
  216. /*
  217.  * strunvis - decode src into dst 
  218.  *
  219.  *    Number of chars decoded into dst is returned, -1 on error.
  220.  *    Dst is null terminated.
  221.  */
  222.  
  223. int
  224. strunvis(dst, src)
  225.     register char *dst;
  226.     register const char *src;
  227. {
  228.     register char c;
  229.     char *start = dst;
  230.     int state = 0;
  231.  
  232.     while (c = *src++) {
  233.     again:
  234.         switch (unvis(dst, c, &state, 0)) {
  235.         case UNVIS_VALID:
  236.             dst++;
  237.             break;
  238.         case UNVIS_VALIDPUSH:
  239.             dst++;
  240.             goto again;
  241.         case 0:
  242.         case UNVIS_NOCHAR:
  243.             break;
  244.         default:
  245.             return (-1);
  246.         }
  247.     }
  248.     if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
  249.         dst++;
  250.     *dst = '\0';
  251.     return (dst - start);
  252. }
  253.