BSD 4_3_Net_2 release
[unix-history] / usr / src / lib / libc / gen / vis.c
index 4ad732e..0609c26 100644 (file)
@@ -1,27 +1,43 @@
-/*
+/*-
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)vis.c      5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)vis.c      5.4 (Berkeley) 2/23/91";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <ctype.h>
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <ctype.h>
-#include <cencode.h>
+#include <vis.h>
 
 #define        isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
 
 
 #define        isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
 
@@ -29,14 +45,19 @@ static char sccsid[] = "@(#)vis.c   5.2 (Berkeley) %G%";
  * vis - visually encode characters
  */
 char *
  * vis - visually encode characters
  */
 char *
+#if __STDC__
+vis(register char *dst, register char c, register int flag, char nextc)
+#else
 vis(dst, c, flag, nextc)
        register char *dst, c;
        char nextc;
        register int flag;
 vis(dst, c, flag, nextc)
        register char *dst, c;
        char nextc;
        register int flag;
+#endif
 {
        if (isascii(c) && isgraph(c) ||
 {
        if (isascii(c) && isgraph(c) ||
-          ((flag & VIS_WHITE) == 0 && 
-               (c == ' ' || c == '\n' || (flag & VIS_TAB) == 0 && c == '\t')) ||
+          ((flag & VIS_SP) == 0 && c == ' ') ||
+          ((flag & VIS_TAB) == 0 && c == '\t') ||
+          ((flag & VIS_NL) == 0 && c == '\n') ||
           ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
                *dst++ = c;
                if (c == '\\' && (flag & VIS_NOSLASH) == 0)
           ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
                *dst++ = c;
                if (c == '\\' && (flag & VIS_NOSLASH) == 0)
@@ -45,37 +66,48 @@ vis(dst, c, flag, nextc)
                return (dst);
        }
 
                return (dst);
        }
 
-       if ((flag & VIS_NOSLASH) == 0)
-               *dst++ = '\\';
        if (flag & VIS_CSTYLE) {
                switch(c) {
                case '\n':
        if (flag & VIS_CSTYLE) {
                switch(c) {
                case '\n':
+                       *dst++ = '\\';
                        *dst++ = 'n';
                        goto done;
                case '\r':
                        *dst++ = 'n';
                        goto done;
                case '\r':
+                       *dst++ = '\\';
                        *dst++ = 'r';
                        goto done;
                case '\b':
                        *dst++ = 'r';
                        goto done;
                case '\b':
+                       *dst++ = '\\';
                        *dst++ = 'b';
                        goto done;
                        *dst++ = 'b';
                        goto done;
-               case '\007':    /* waiting for ansi compiler */
+#if __STDC__
+               case '\a':
+#else
+               case '\007':
+#endif
+                       *dst++ = '\\';
                        *dst++ = 'a';
                        goto done;
                case '\v':
                        *dst++ = 'a';
                        goto done;
                case '\v':
+                       *dst++ = '\\';
                        *dst++ = 'v';
                        goto done;
                case '\t':
                        *dst++ = 'v';
                        goto done;
                case '\t':
+                       *dst++ = '\\';
                        *dst++ = 't';
                        goto done;
                case '\f':
                        *dst++ = 't';
                        goto done;
                case '\f':
+                       *dst++ = '\\';
                        *dst++ = 'f';
                        goto done;
                case ' ':
                        *dst++ = 'f';
                        goto done;
                case ' ':
+                       *dst++ = '\\';
                        *dst++ = 's';
                        goto done;
                case '\0':
                        *dst++ = 's';
                        goto done;
                case '\0':
+                       *dst++ = '\\';
                        *dst++ = '0';
                        *dst++ = '0';
-                       if ((flag & VIS_NEXTC) == 0 || isoctal(nextc)) {
+                       if (isoctal(nextc)) {
                                *dst++ = '0';
                                *dst++ = '0';
                        }
                                *dst++ = '0';
                                *dst++ = '0';
                        }
@@ -83,11 +115,14 @@ vis(dst, c, flag, nextc)
                }
        }
        if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {        
                }
        }
        if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {        
+               *dst++ = '\\';
                *dst++ = ((u_char)c >> 6 & 07) + '0';
                *dst++ = ((u_char)c >> 3 & 07) + '0';
                *dst++ = ((u_char)c & 07) + '0';
                goto done;
        }
                *dst++ = ((u_char)c >> 6 & 07) + '0';
                *dst++ = ((u_char)c >> 3 & 07) + '0';
                *dst++ = ((u_char)c & 07) + '0';
                goto done;
        }
+       if ((flag & VIS_NOSLASH) == 0)
+               *dst++ = '\\';
        if (c & 0200) {
                c &= 0177;
                *dst++ = 'M';
        if (c & 0200) {
                c &= 0177;
                *dst++ = 'M';
@@ -107,173 +142,46 @@ done:
        return (dst);
 }
 
        return (dst);
 }
 
-
-/*
- * decode driven by state machine
- */
-#define        S_NORMAL        1       /* haven't seen escape char */
-#define        S_START         2       /* start decoding special sequence */
-#define        S_META          3       /* metachar started (M) */
-#define        S_META1         4       /* metachar more, regular char (-) */
-#define        S_CTRL          5       /* control char started (^) */
-#define        S_OCTAL         6       /* octal number */
-
 /*
 /*
+ * strvis, strvisx - visually encode characters from src into dst
+ *     
+ *     Dst must be 4 times the size of src to account for possible
+ *     expansion.  The length of dst, not including the trailing NULL,
+ *     is returned. 
  *
  *
+ *     Strvisx encodes exactly len bytes from src into dst.
+ *     This is useful for encoding a block of data.
  */
  */
-cunvis(c, cp, flags)
-       char c;
-       char *cp;
+int
+strvis(dst, src, flag)
+       register char *dst;
+       register const char *src;
+       int flag;
 {
 {
-       static int state = S_NORMAL;
-       static u_char buildchar;
-       static int octal;
+       register char c;
+       char *start = dst;
 
 
-       if (flags&UNVIS_END) {
-               int ostate = state;
-               state = S_NORMAL;
-               if (ostate == S_OCTAL) {
-                       *cp = buildchar;
-                       return(UNVIS_OK);
-               } else if (ostate == S_META1) {
-                       /* slightly forgiving, if not wrong */
-                       *cp = ' ' | 0200;
-                       return(UNVIS_OK);
-               } else
-                       return(ostate == S_NORMAL ? UNVIS_NOCHAR : CDEC_SYNBAD);
-       }
+       for (;c = *src; src++)
+               dst = vis(dst, c, flag, *(src+1));
 
 
-       switch (state) {
-       case S_NORMAL:
-               buildchar = 0;
-               if (c == '\\') {
-                       state = S_START;
-                       return(UNVIS_NEEDMORE);
-               } else if (flags&UNVIS_HAT && c == '^') {
-                       state = S_CTRL;
-                       return(UNVIS_NEEDMORE);
-               } else {
-                       *cp = c;
-                       return(UNVIS_OK);
-               }
-               break;
-       case S_START:
-               state = S_NORMAL;
-               if (c == '\\') {
-                       *cp = c;
-                       return(UNVIS_OK);
-               }
-               if (isoctal(c)) {
-                       buildchar = (c-'0');
-                       octal = 1;
-                       state = S_OCTAL;
-                       return(UNVIS_NEEDMORE);
-               } 
-               switch(c) {
-               case 'M':
-                       buildchar |= 0200;
-                       state = S_META;
-                       return(UNVIS_NEEDMORE);
-               case '^':
-                       state = S_CTRL;
-                       return(UNVIS_NEEDMORE);
-               case 'n':
-                       *cp = '\n';
-                       return(UNVIS_OK);
-               case 'r':
-                       *cp = '\r';
-                       return(UNVIS_OK);
-               case 'b':
-                       *cp = '\b';
-                       return(UNVIS_OK);
-               case 'a':
-                       *cp = '\007';
-                       return(UNVIS_OK);
-               case 'v':
-                       *cp = '\v';
-                       return(UNVIS_OK);
-               case 't':
-                       *cp = '\t';
-                       return(UNVIS_OK);
-               case 'f':
-                       *cp = '\f';
-                       return(UNVIS_OK);
-               case 's':                       /* does anyone use this ? */
-                       *cp = ' ';
-                       return(UNVIS_OK);
-               case 'E':
-                       *cp = '\033';
-                       return(UNVIS_OK);
-               case '\n':
-                       return(UNVIS_NOCHAR);   /* hidden newline */
-               }
-               state = S_NORMAL;
-               return(UNVIS_SYNBAD);
-       case S_META:
-               if (c == '-')
-                       state = S_META1;
-               else if (c == '^')
-                       state = S_CTRL;
-               else {
-                       state = S_NORMAL;
-                       return(UNVIS_SYNBAD);
-               }
-               return(UNVIS_NEEDMORE);
-       case S_META1:
-               state = S_NORMAL;
-               *cp = c | buildchar;
-               return(UNVIS_OK);
-       case S_CTRL:
-               if (c == '?')
-                       buildchar |= 0177;
-               else
-                       buildchar |= c&037;
-               state = S_NORMAL;
-               *cp = buildchar;
-               return(UNVIS_OK);
-       case S_OCTAL:
-               if (isoctal(c)) {
-                       buildchar = (buildchar<<3) + (c-'0');
-                       if (++octal == 3) {
-                               state = S_NORMAL;
-                               *cp = buildchar;
-                               return(UNVIS_OK);
-                       } else
-                               return(UNVIS_NEEDMORE);
-               } else {
-                       state = S_NORMAL;
-                       *cp = buildchar;
-                       return(UNVIS_OKPUSH);
-               }
-       }
+       return (dst - start);
 }
 
 }
 
-/*
- * strvis - visually encode characters from src into dst
- *
- *     If len >= 0, encodes exactly len chars from src (including NULL's).
- *     Otherwise, stops before first NULL in src.  In all cases, dst is 
- *     NULL terminated.
- *
- *     Dst must be 4 times the size of src to account for possible
- *     expansion.  The length of dst, not including the trailing NULL,
- *     is returned.
- */
-strvis(dst, src, len, flag)
-       register char *dst, *src;
-       register int len;
+int
+strvisx(dst, src, len, flag)
+       register char *dst;
+       register const char *src;
+       register size_t len;
+       int flag;
 {
        char *start = dst;
 
 {
        char *start = dst;
 
-       for (;;) {
-               if (len > 0) { 
-                       if (len-- == 0)
-                               break;
-               } else if (!*src)
-                       break;
-               dst = vis(dst, *src, flag | VIS_NEXTC, *(src+1));
-               src++;
+       while (len > 1) {
+               dst = vis(dst, *src, flag, *(src+1));
+               len--;
        }
        }
+       if (len)
+               dst = vis(dst, *src, flag, '\0');
 
        return (dst - start);
 }
 
        return (dst - start);
 }