]> andersk Git - moira.git/blob - afssync/vis.c
Command line printer manipulation client, and build goo.
[moira.git] / afssync / vis.c
1 /* $Id$
2  * vis functions - visually encode characters
3  * Originally from OpenBSD
4  */
5
6 /*-
7  * Copyright (c) 1989, 1993
8  *      The Regents of the University of California.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 #ifndef HAVE_STRVIS
40 #include "vis.h"
41 /*
42  * vis - visually encode characters
43  */
44 char *
45 vis(dst, c, flag, nextc)
46         register char *dst;
47         int c, nextc;
48         register int flag;
49 {
50         if (isvisible(c)) {
51                 *dst++ = c;
52                 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
53                         *dst++ = '\\';
54                 *dst = '\0';
55                 return (dst);
56         }
57
58         if (flag & VIS_CSTYLE) {
59                 switch(c) {
60                 case '\n':
61                         *dst++ = '\\';
62                         *dst++ = 'n';
63                         goto done;
64                 case '\r':
65                         *dst++ = '\\';
66                         *dst++ = 'r';
67                         goto done;
68                 case '\b':
69                         *dst++ = '\\';
70                         *dst++ = 'b';
71                         goto done;
72 #ifdef __STDC__
73                 case '\a':
74 #else
75                 case '\007':
76 #endif
77                         *dst++ = '\\';
78                         *dst++ = 'a';
79                         goto done;
80                 case '\v':
81                         *dst++ = '\\';
82                         *dst++ = 'v';
83                         goto done;
84                 case '\t':
85                         *dst++ = '\\';
86                         *dst++ = 't';
87                         goto done;
88                 case '\f':
89                         *dst++ = '\\';
90                         *dst++ = 'f';
91                         goto done;
92                 case ' ':
93                         *dst++ = '\\';
94                         *dst++ = 's';
95                         goto done;
96                 case '\0':
97                         *dst++ = '\\';
98                         *dst++ = '0';
99                         if (isoctal(nextc)) {
100                                 *dst++ = '0';
101                                 *dst++ = '0';
102                         }
103                         goto done;
104                 }
105         }
106         if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {        
107                 *dst++ = '\\';
108                 *dst++ = ((u_char)c >> 6 & 07) + '0';
109                 *dst++ = ((u_char)c >> 3 & 07) + '0';
110                 *dst++ = ((u_char)c & 07) + '0';
111                 goto done;
112         }
113         if ((flag & VIS_NOSLASH) == 0)
114                 *dst++ = '\\';
115         if (c & 0200) {
116                 c &= 0177;
117                 *dst++ = 'M';
118         }
119         if (iscntrl(c)) {
120                 *dst++ = '^';
121                 if (c == 0177)
122                         *dst++ = '?';
123                 else
124                         *dst++ = c + '@';
125         } else {
126                 *dst++ = '-';
127                 *dst++ = c;
128         }
129 done:
130         *dst = '\0';
131         return (dst);
132 }
133
134 /*
135  * strvis, strnvis, strvisx - visually encode characters from src into dst
136  *      
137  *      Dst must be 4 times the size of src to account for possible
138  *      expansion.  The length of dst, not including the trailing NULL,
139  *      is returned. 
140  *
141  *      Strnvis will write no more than siz-1 bytes (and will NULL terminate).
142  *      The number of bytes needed to fully encode the string is returned.
143  *
144  *      Strvisx encodes exactly len bytes from src into dst.
145  *      This is useful for encoding a block of data.
146  */
147 int
148 strvis(dst, src, flag)
149         register char *dst;
150         register const char *src;
151         int flag;
152 {
153         register char c;
154         char *start;
155
156         for (start = dst; (c = *src);)
157                 dst = vis(dst, c, flag, *++src);
158         *dst = '\0';
159         return (dst - start);
160 }
161
162 int
163 strnvis(dst, src, siz, flag)
164         register char *dst;
165         register const char *src;
166         size_t siz;
167         int flag;
168 {
169         register char c;
170         char *start, *end;
171
172         for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
173                 if (isvisible(c)) {
174                         *dst++ = c;
175                         if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
176                                 /* need space for the extra '\\' */
177                                 if (dst < end)
178                                         *dst++ = '\\';
179                                 else {
180                                         dst--;
181                                         break;
182                                 }
183                         }
184                         src++;
185                 } else {
186                         /* vis(3) requires up to 4 chars */
187                         if (dst + 3 < end)
188                                 dst = vis(dst, c, flag, *++src);
189                         else
190                                 break;
191                 }
192         }
193         *dst = '\0';
194         if (dst >= end) {
195                 char tbuf[5];
196
197                 /* adjust return value for truncation */
198                 while ((c = *src))
199                         dst += vis(tbuf, c, flag, *++src) - tbuf;
200         }
201         return (dst - start);
202 }
203
204 int
205 strvisx(dst, src, len, flag)
206         register char *dst;
207         register const char *src;
208         register size_t len;
209         int flag;
210 {
211         register char c;
212         char *start;
213
214         for (start = dst; len > 1; len--) {
215                 c = *src;
216                 dst = vis(dst, c, flag, *++src);
217         }
218         if (len)
219                 dst = vis(dst, *src, flag, '\0');
220         *dst = '\0';
221         return (dst - start);
222 }
223
224 /*
225  * unvis - decode characters previously encoded by vis
226  */
227 int
228 #ifdef __STDC__
229 unvis(char *cp, char c, int *astate, int flag)
230 #else
231 unvis(cp, c, astate, flag)
232         char *cp;
233         char c;
234         int *astate, flag;
235 #endif
236 {
237
238         if (flag & UNVIS_END) {
239                 if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
240                         *astate = S_GROUND;
241                         return (UNVIS_VALID);
242                 } 
243                 return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
244         }
245
246         switch (*astate) {
247
248         case S_GROUND:
249                 *cp = 0;
250                 if (c == '\\') {
251                         *astate = S_START;
252                         return (0);
253                 } 
254                 *cp = c;
255                 return (UNVIS_VALID);
256
257         case S_START:
258                 switch(c) {
259                 case '\\':
260                         *cp = c;
261                         *astate = S_GROUND;
262                         return (UNVIS_VALID);
263                 case '0': case '1': case '2': case '3':
264                 case '4': case '5': case '6': case '7':
265                         *cp = (c - '0');
266                         *astate = S_OCTAL2;
267                         return (0);
268                 case 'M':
269                         *cp = (char) 0200;
270                         *astate = S_META;
271                         return (0);
272                 case '^':
273                         *astate = S_CTRL;
274                         return (0);
275                 case 'n':
276                         *cp = '\n';
277                         *astate = S_GROUND;
278                         return (UNVIS_VALID);
279                 case 'r':
280                         *cp = '\r';
281                         *astate = S_GROUND;
282                         return (UNVIS_VALID);
283                 case 'b':
284                         *cp = '\b';
285                         *astate = S_GROUND;
286                         return (UNVIS_VALID);
287                 case 'a':
288                         *cp = '\007';
289                         *astate = S_GROUND;
290                         return (UNVIS_VALID);
291                 case 'v':
292                         *cp = '\v';
293                         *astate = S_GROUND;
294                         return (UNVIS_VALID);
295                 case 't':
296                         *cp = '\t';
297                         *astate = S_GROUND;
298                         return (UNVIS_VALID);
299                 case 'f':
300                         *cp = '\f';
301                         *astate = S_GROUND;
302                         return (UNVIS_VALID);
303                 case 's':
304                         *cp = ' ';
305                         *astate = S_GROUND;
306                         return (UNVIS_VALID);
307                 case 'E':
308                         *cp = '\033';
309                         *astate = S_GROUND;
310                         return (UNVIS_VALID);
311                 case '\n':
312                         /*
313                          * hidden newline
314                          */
315                         *astate = S_GROUND;
316                         return (UNVIS_NOCHAR);
317                 case '$':
318                         /*
319                          * hidden marker
320                          */
321                         *astate = S_GROUND;
322                         return (UNVIS_NOCHAR);
323                 }
324                 *astate = S_GROUND;
325                 return (UNVIS_SYNBAD);
326                  
327         case S_META:
328                 if (c == '-')
329                         *astate = S_META1;
330                 else if (c == '^')
331                         *astate = S_CTRL;
332                 else {
333                         *astate = S_GROUND;
334                         return (UNVIS_SYNBAD);
335                 }
336                 return (0);
337                  
338         case S_META1:
339                 *astate = S_GROUND;
340                 *cp |= c;
341                 return (UNVIS_VALID);
342                  
343         case S_CTRL:
344                 if (c == '?')
345                         *cp |= 0177;
346                 else
347                         *cp |= c & 037;
348                 *astate = S_GROUND;
349                 return (UNVIS_VALID);
350
351         case S_OCTAL2:        /* second possible octal digit */
352                 if (isoctal(c)) {
353                         /* 
354                          * yes - and maybe a third 
355                          */
356                         *cp = (*cp << 3) + (c - '0');
357                         *astate = S_OCTAL3;        
358                         return (0);
359                 } 
360                 /* 
361                  * no - done with current sequence, push back passed char 
362                  */
363                 *astate = S_GROUND;
364                 return (UNVIS_VALIDPUSH);
365
366         case S_OCTAL3:        /* third possible octal digit */
367                 *astate = S_GROUND;
368                 if (isoctal(c)) {
369                         *cp = (*cp << 3) + (c - '0');
370                         return (UNVIS_VALID);
371                 }
372                 /*
373                  * we were done, push back passed char
374                  */
375                 return (UNVIS_VALIDPUSH);
376                         
377         default:        
378                 /* 
379                  * decoder in unknown state - (probably uninitialized) 
380                  */
381                 *astate = S_GROUND;
382                 return (UNVIS_SYNBAD);
383         }
384 }
385
386 /*
387  * strunvis - decode src into dst 
388  *
389  *      Number of chars decoded into dst is returned, -1 on error.
390  *      Dst is null terminated.
391  */
392
393 int
394 strunvis(dst, src)
395         register char *dst;
396         register const char *src;
397 {
398         register char c;
399         char *start = dst;
400         int state = 0;
401
402         while ((c = *src++)) {
403         again:
404                 switch (unvis(dst, c, &state, 0)) {
405                 case UNVIS_VALID:
406                         dst++;
407                         break;
408                 case UNVIS_VALIDPUSH:
409                         dst++;
410                         goto again;
411                 case 0:
412                 case UNVIS_NOCHAR:
413                         break;
414                 default:
415                         return (-1);
416                 }
417         }
418         if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
419                 dst++;
420         *dst = '\0';
421         return (dst - start);
422 }
423
424 #endif /* HAVE_STRVIS */
This page took 2.290807 seconds and 5 git commands to generate.