home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / lib / libc / gen / vis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-06  |  4.5 KB  |  185 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[] = "@(#)vis.c    5.6 (Berkeley) 2/5/92";
  36. #endif /* LIBC_SCCS and not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <limits.h>
  40. #include <ctype.h>
  41. #include <vis.h>
  42.  
  43. #define    isoctal(c)    (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
  44.  
  45. /*
  46.  * vis - visually encode characters
  47.  */
  48. char *
  49. vis(dst, c, flag, nextc)
  50.     register char *dst;
  51.     int c, nextc;
  52.     register int flag;
  53. {
  54.     if ((u_int)c <= UCHAR_MAX && isgraph(c) ||
  55.        ((flag & VIS_SP) == 0 && c == ' ') ||
  56.        ((flag & VIS_TAB) == 0 && c == '\t') ||
  57.        ((flag & VIS_NL) == 0 && c == '\n') ||
  58.        ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
  59.         *dst++ = c;
  60.         if (c == '\\' && (flag & VIS_NOSLASH) == 0)
  61.             *dst++ = '\\';
  62.         *dst = '\0';
  63.         return (dst);
  64.     }
  65.  
  66.     if (flag & VIS_CSTYLE) {
  67.         switch(c) {
  68.         case '\n':
  69.             *dst++ = '\\';
  70.             *dst++ = 'n';
  71.             goto done;
  72.         case '\r':
  73.             *dst++ = '\\';
  74.             *dst++ = 'r';
  75.             goto done;
  76.         case '\b':
  77.             *dst++ = '\\';
  78.             *dst++ = 'b';
  79.             goto done;
  80. #if __STDC__
  81.         case '\a':
  82. #else
  83.         case '\007':
  84. #endif
  85.             *dst++ = '\\';
  86.             *dst++ = 'a';
  87.             goto done;
  88.         case '\v':
  89.             *dst++ = '\\';
  90.             *dst++ = 'v';
  91.             goto done;
  92.         case '\t':
  93.             *dst++ = '\\';
  94.             *dst++ = 't';
  95.             goto done;
  96.         case '\f':
  97.             *dst++ = '\\';
  98.             *dst++ = 'f';
  99.             goto done;
  100.         case ' ':
  101.             *dst++ = '\\';
  102.             *dst++ = 's';
  103.             goto done;
  104.         case '\0':
  105.             *dst++ = '\\';
  106.             *dst++ = '0';
  107.             if (isoctal(nextc)) {
  108.                 *dst++ = '0';
  109.                 *dst++ = '0';
  110.             }
  111.             goto done;
  112.         }
  113.     }
  114.     if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {    
  115.         *dst++ = '\\';
  116.         *dst++ = ((u_char)c >> 6 & 07) + '0';
  117.         *dst++ = ((u_char)c >> 3 & 07) + '0';
  118.         *dst++ = ((u_char)c & 07) + '0';
  119.         goto done;
  120.     }
  121.     if ((flag & VIS_NOSLASH) == 0)
  122.         *dst++ = '\\';
  123.     if (c & 0200) {
  124.         c &= 0177;
  125.         *dst++ = 'M';
  126.     }
  127.     if (iscntrl(c)) {
  128.         *dst++ = '^';
  129.         if (c == 0177)
  130.             *dst++ = '?';
  131.         else
  132.             *dst++ = c + '@';
  133.     } else {
  134.         *dst++ = '-';
  135.         *dst++ = c;
  136.     }
  137. done:
  138.     *dst = '\0';
  139.     return (dst);
  140. }
  141.  
  142. /*
  143.  * strvis, strvisx - visually encode characters from src into dst
  144.  *    
  145.  *    Dst must be 4 times the size of src to account for possible
  146.  *    expansion.  The length of dst, not including the trailing NULL,
  147.  *    is returned. 
  148.  *
  149.  *    Strvisx encodes exactly len bytes from src into dst.
  150.  *    This is useful for encoding a block of data.
  151.  */
  152. int
  153. strvis(dst, src, flag)
  154.     register char *dst;
  155.     register const char *src;
  156.     int flag;
  157. {
  158.     register char c;
  159.     char *start;
  160.  
  161.     for (start = dst; c = *src;)
  162.         dst = vis(dst, c, flag, *++src);
  163.     *dst = '\0';
  164.     return (dst - start);
  165. }
  166.  
  167. int
  168. strvisx(dst, src, len, flag)
  169.     register char *dst;
  170.     register const char *src;
  171.     register size_t len;
  172.     int flag;
  173. {
  174.     char *start = dst;
  175.  
  176.     while (len > 1) {
  177.         dst = vis(dst, *src, flag, *(src+1));
  178.         len--;
  179.     }
  180.     if (len)
  181.         dst = vis(dst, *src, flag, '\0');
  182.  
  183.     return (dst - start);
  184. }
  185.