1 /* strtrans.c - Translate and untranslate strings with ANSI-C escape
5 Free Software Foundation, Inc.
7 This file is part of GNU Bash, the Bourne Again SHell.
9 Bash is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License along
20 with Bash; see the file COPYING. If not, write to the Free Software
21 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
25 #if defined (HAVE_UNISTD_H)
31 #include <chartypes.h>
38 #define ESC '\033' /* ASCII */
40 /* Convert STRING by expanding the escape sequences specified by the
41 ANSI C standard. If SAWC is non-null, recognize `\c' and use that
42 as a string terminator. If we see \c, set *SAWC to 1 before
43 returning. LEN is the length of STRING. FOR_ECHO is a flag that
44 means, if non-zero, that we're translating a string for `echo -e',
45 and therefore should not treat a single quote as a character that
46 may be escaped with a backslash. */
48 ansicstr (string, len, for_echo, sawc, rlen)
50 int len, for_echo, *sawc, *rlen;
55 if (string == 0 || *string == '\0')
56 return ((char *)NULL);
58 ret = (char *)xmalloc (len + 1);
59 for (r = ret, s = string; s && *s; )
62 if (c != '\\' || *s == '\0')
68 #if defined (__STDC__)
69 case 'a': c = '\a'; break;
70 case 'v': c = '\v'; break;
72 case 'a': c = '\007'; break;
73 case 'v': c = (int) 0x0B; break;
75 case 'b': c = '\b'; break;
76 case 'e': case 'E': /* ESC -- non-ANSI */
78 case 'f': c = '\f'; break;
79 case 'n': c = '\n'; break;
80 case 'r': c = '\r'; break;
81 case 't': c = '\t'; break;
82 case '0': case '1': case '2': case '3':
83 case '4': case '5': case '6': case '7':
84 for (temp = 2, c -= '0'; ISOCTAL (*s) && temp--; s++)
85 c = (c * 8) + OCTVALUE (*s);
88 case 'x': /* Hex digit -- non-ANSI */
89 for (temp = 2, c = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++)
90 c = (c * 16) + HEXVALUE (*s);
91 /* \x followed by non-hex digits is passed through unchanged */
114 default: *r++ = '\\'; break;
125 /* Take a string STR, possibly containing non-printing characters, and turn it
126 into a $'...' ANSI-C style quoted string. Returns a new string. */
128 ansic_quote (str, flags, rlen)
132 char *r, *ret, *s, obuf[8];
136 if (str == 0 || *str == 0)
141 r = ret = (char *)xmalloc (rsize);
146 for (s = str, l = 0; *s; s++)
149 l = 1; /* 1 == add backslash; 0 == no backslash */
152 case ESC: c = 'E'; break;
154 case '\a': c = 'a'; break;
155 case '\v': c = 'v'; break;
157 case '\007': c = 'a'; break;
158 case 0x0b: c = 'v'; break;
161 case '\b': c = 'b'; break;
162 case '\f': c = 'f'; break;
163 case '\n': c = 'n'; break;
164 case '\r': c = 'r'; break;
165 case '\t': c = 't'; break;
170 if (ISPRINT (c) == 0)
172 sprintf (obuf, "\\%.3o", c);
174 RESIZE_MALLOCED_BUFFER (ret, t, 5, rsize, 16);
175 r = ret + t; /* in case reallocated */
176 for (t = 0; t < 4; t++)
195 /* return 1 if we need to quote with $'...' because of non-printing chars. */
196 ansic_shouldquote (string)
205 for (s = string; c = *s; s++)
206 if (ISPRINT (c) == 0)