home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / gen_library / rcs / unvis.c,v < prev    next >
Encoding:
Text File  |  1992-07-04  |  5.1 KB  |  257 lines

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