source: vendor/bash/3.1/lib/sh/shquote.c

Last change on this file was 3228, checked in by bird, 18 years ago

bash 3.1

File size: 6.3 KB
Line 
1/* Copyright (C) 1999 Free Software Foundation, Inc.
2
3 This file is part of GNU Bash, the Bourne Again SHell.
4
5 Bash is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version.
9
10 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with Bash; see the file COPYING. If not, write to the Free Software
17 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
18
19#include <config.h>
20
21#if defined (HAVE_UNISTD_H)
22# ifdef _MINIX
23# include <sys/types.h>
24# endif
25# include <unistd.h>
26#endif
27
28#include <stdio.h>
29
30#include "syntax.h"
31#include <xmalloc.h>
32
33/* **************************************************************** */
34/* */
35/* Functions for quoting strings to be re-read as input */
36/* */
37/* **************************************************************** */
38
39/* Return a new string which is the single-quoted version of STRING.
40 Used by alias and trap, among others. */
41char *
42sh_single_quote (string)
43 char *string;
44{
45 register int c;
46 char *result, *r, *s;
47
48 result = (char *)xmalloc (3 + (4 * strlen (string)));
49 r = result;
50 *r++ = '\'';
51
52 for (s = string; s && (c = *s); s++)
53 {
54 *r++ = c;
55
56 if (c == '\'')
57 {
58 *r++ = '\\'; /* insert escaped single quote */
59 *r++ = '\'';
60 *r++ = '\''; /* start new quoted string */
61 }
62 }
63
64 *r++ = '\'';
65 *r = '\0';
66
67 return (result);
68}
69
70/* Quote STRING using double quotes. Return a new string. */
71char *
72sh_double_quote (string)
73 char *string;
74{
75 register unsigned char c;
76 char *result, *r, *s;
77
78 result = (char *)xmalloc (3 + (2 * strlen (string)));
79 r = result;
80 *r++ = '"';
81
82 for (s = string; s && (c = *s); s++)
83 {
84 /* Backslash-newline disappears within double quotes, so don't add one. */
85 if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
86 *r++ = '\\';
87 else if (c == CTLESC || c == CTLNUL)
88 *r++ = CTLESC; /* could be '\\'? */
89
90 *r++ = c;
91 }
92
93 *r++ = '"';
94 *r = '\0';
95
96 return (result);
97}
98
99/* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote
100 double quote characters in S with backslashes. */
101char *
102sh_mkdoublequoted (s, slen, flags)
103 const char *s;
104 int slen, flags;
105{
106 char *r, *ret;
107 int rlen;
108
109 rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
110 ret = r = (char *)xmalloc (rlen);
111
112 *r++ = '"';
113 while (*s)
114 {
115 if (flags && *s == '"')
116 *r++ = '\\';
117 *r++ = *s++;
118 }
119 *r++ = '"';
120 *r = '\0';
121
122 return ret;
123}
124
125/* Remove backslashes that are quoting characters that are special between
126 double quotes. Return a new string. XXX - should this handle CTLESC
127 and CTLNUL? */
128char *
129sh_un_double_quote (string)
130 char *string;
131{
132 register int c, pass_next;
133 char *result, *r, *s;
134
135 r = result = (char *)xmalloc (strlen (string) + 1);
136
137 for (pass_next = 0, s = string; s && (c = *s); s++)
138 {
139 if (pass_next)
140 {
141 *r++ = c;
142 pass_next = 0;
143 continue;
144 }
145 if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE))
146 {
147 pass_next = 1;
148 continue;
149 }
150 *r++ = c;
151 }
152
153 *r = '\0';
154 return result;
155}
156
157/* Quote special characters in STRING using backslashes. Return a new
158 string. NOTE: if the string is to be further expanded, we need a
159 way to protect the CTLESC and CTLNUL characters. As I write this,
160 the current callers will never cause the string to be expanded without
161 going through the shell parser, which will protect the internal
162 quoting characters. */
163char *
164sh_backslash_quote (string)
165 char *string;
166{
167 int c;
168 char *result, *r, *s;
169
170 result = (char *)xmalloc (2 * strlen (string) + 1);
171
172 for (r = result, s = string; s && (c = *s); s++)
173 {
174 switch (c)
175 {
176 case ' ': case '\t': case '\n': /* IFS white space */
177 case '\'': case '"': case '\\': /* quoting chars */
178 case '|': case '&': case ';': /* shell metacharacters */
179 case '(': case ')': case '<': case '>':
180 case '!': case '{': case '}': /* reserved words */
181 case '*': case '[': case '?': case ']': /* globbing chars */
182 case '^':
183 case '$': case '`': /* expansion chars */
184 case ',': /* brace expansion */
185 *r++ = '\\';
186 *r++ = c;
187 break;
188#if 0
189 case '~': /* tilde expansion */
190 if (s == string || s[-1] == '=' || s[-1] == ':')
191 *r++ = '\\';
192 *r++ = c;
193 break;
194
195 case CTLESC: case CTLNUL: /* internal quoting characters */
196 *r++ = CTLESC; /* could be '\\'? */
197 *r++ = c;
198 break;
199#endif
200
201 case '#': /* comment char */
202 if (s == string)
203 *r++ = '\\';
204 /* FALLTHROUGH */
205 default:
206 *r++ = c;
207 break;
208 }
209 }
210
211 *r = '\0';
212 return (result);
213}
214
215#if defined (PROMPT_STRING_DECODE)
216/* Quote characters that get special treatment when in double quotes in STRING
217 using backslashes. Return a new string. */
218char *
219sh_backslash_quote_for_double_quotes (string)
220 char *string;
221{
222 unsigned char c;
223 char *result, *r, *s;
224
225 result = (char *)xmalloc (2 * strlen (string) + 1);
226
227 for (r = result, s = string; s && (c = *s); s++)
228 {
229 if (sh_syntaxtab[c] & CBSDQUOTE)
230 *r++ = '\\';
231 /* I should probably add flags for these to sh_syntaxtab[] */
232 else if (c == CTLESC || c == CTLNUL)
233 *r++ = CTLESC; /* could be '\\'? */
234
235 *r++ = c;
236 }
237
238 *r = '\0';
239 return (result);
240}
241#endif /* PROMPT_STRING_DECODE */
242
243int
244sh_contains_shell_metas (string)
245 char *string;
246{
247 char *s;
248
249 for (s = string; s && *s; s++)
250 {
251 switch (*s)
252 {
253 case ' ': case '\t': case '\n': /* IFS white space */
254 case '\'': case '"': case '\\': /* quoting chars */
255 case '|': case '&': case ';': /* shell metacharacters */
256 case '(': case ')': case '<': case '>':
257 case '!': case '{': case '}': /* reserved words */
258 case '*': case '[': case '?': case ']': /* globbing chars */
259 case '^':
260 case '$': case '`': /* expansion chars */
261 return (1);
262 case '~': /* tilde expansion */
263 if (s == string || s[-1] == '=' || s[-1] == ':')
264 return (1);
265 break;
266 case '#':
267 if (s == string) /* comment char */
268 return (1);
269 /* FALLTHROUGH */
270 default:
271 break;
272 }
273 }
274
275 return (0);
276}
Note: See TracBrowser for help on using the repository browser.