: is an optional delimiter for hex strings.
[dhcpcd-ui] / src / libdhcpcd / vis.c
1 /*      $NetBSD: vis.c,v 1.44 2011/03/12 19:52:48 christos Exp $        */
2
3 /*-
4  * Copyright (c) 1989, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 /*-
33  * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
34  * All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  *
45  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
46  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
47  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
49  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55  * POSSIBILITY OF SUCH DAMAGE.
56  */
57
58 /*
59  * HEAVILY trimmed down for use only in dhcpcd.
60  * Please use the source in NetBSD for a fuller working copy.
61  */
62
63 #include <ctype.h>
64 #include <errno.h>
65 #include <limits.h>
66 #include <stdlib.h>
67 #include <string.h>
68
69 #define IN_LIBDHCPCD
70 #include "dhcpcd.h"
71
72 #undef BELL
73 #define BELL '\a'
74
75 #define isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
76 #define iswhite(c)      (c == ' ' || c == '\t' || c == '\n')
77
78 /*
79  * This is do_vis, the central code of vis.
80  * dst:       Pointer to the destination buffer
81  * c:         Character to encode
82  * flag:      Flag word
83  * nextc:     The character following 'c'
84  * extra:     Pointer to the list of extra characters to be
85  *            backslash-protected.
86  */
87 char *
88 dhcpcd_svis(char *dst, int c, int flag, int nextc, const char *extra)
89 {
90         int isextra;
91
92         isextra = strchr(extra, c) != NULL;
93         if (!isextra && isascii(c) && (isgraph(c) || iswhite(c))) {
94                 *dst++ = (char)c;
95                 return dst;
96         }
97         if (flag & VIS_CSTYLE) {
98                 switch (c) {
99                 case '\n':
100                         *dst++ = '\\'; *dst++ = 'n';
101                         return dst;
102                 case '\r':
103                         *dst++ = '\\'; *dst++ = 'r';
104                         return dst;
105                 case '\b':
106                         *dst++ = '\\'; *dst++ = 'b';
107                         return dst;
108                 case BELL:
109                         *dst++ = '\\'; *dst++ = 'a';
110                         return dst;
111                 case '\v':
112                         *dst++ = '\\'; *dst++ = 'v';
113                         return dst;
114                 case '\t':
115                         *dst++ = '\\'; *dst++ = 't';
116                         return dst;
117                 case '\f':
118                         *dst++ = '\\'; *dst++ = 'f';
119                         return dst;
120                 case ' ':
121                         *dst++ = '\\'; *dst++ = 's';
122                         return dst;
123                 case '\0':
124                         *dst++ = '\\'; *dst++ = '0';
125                         if (isoctal(nextc)) {
126                                 *dst++ = '0';
127                                 *dst++ = '0';
128                         }
129                         return dst;
130                 case '$': /* vis(1) - l */
131                         break;
132                 default:
133                         if (isgraph(c)) {
134                                 *dst++ = '\\'; *dst++ = (char)c;
135                                 return dst;
136                         }
137                 }
138         }
139
140         *dst++ = '\\';
141         if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
142                 *dst++ = (char)((((unsigned char)c >> 6) & 03) + '0');
143                 *dst++ = (char)((((unsigned char)c >> 3) & 07) + '0');
144                 *dst++ = (char)(( (unsigned char)c       & 07) + '0');
145         } else {
146                 if (c & 0200) {
147                         c &= 0177; *dst++ = 'M';
148                 }
149
150                 if (iscntrl(c)) {
151                         *dst++ = '^';
152                         if (c == 0177)
153                                 *dst++ = '?';
154                         else
155                                 *dst++ = (char)c + '@';
156                 } else {
157                         *dst++ = '-'; *dst++ = (char)c;
158                 }
159         }
160         return dst;
161 }
162
163 char *
164 dhcpcd_vis(char *dst, int c, int flag, int nextc)
165 {
166
167         return dhcpcd_svis(dst, c, flag, nextc, "");
168 }