]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/sh/shquote.c
713f48199a8deacef81189482e0d37eec6f429be
[thirdparty/bash.git] / lib / sh / shquote.c
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. */
41 char *
42 sh_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. */
71 char *
72 sh_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 if (sh_syntaxtab[c] & CBSDQUOTE)
85 *r++ = '\\';
86
87 *r++ = c;
88 }
89
90 *r++ = '"';
91 *r = '\0';
92
93 return (result);
94 }
95
96 /* Remove backslashes that are quoting characters that are special between
97 double quotes. Return a new string. */
98 char *
99 sh_un_double_quote (string)
100 char *string;
101 {
102 register int c, pass_next;
103 char *result, *r, *s;
104
105 r = result = (char *)xmalloc (strlen (string) + 1);
106
107 for (pass_next = 0, s = string; s && (c = *s); s++)
108 {
109 if (pass_next)
110 {
111 *r++ = c;
112 pass_next = 0;
113 continue;
114 }
115 if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE))
116 {
117 pass_next = 1;
118 continue;
119 }
120 *r++ = c;
121 }
122
123 *r = '\0';
124 return result;
125 }
126
127 /* Quote special characters in STRING using backslashes. Return a new
128 string. */
129 char *
130 sh_backslash_quote (string)
131 char *string;
132 {
133 int c;
134 char *result, *r, *s;
135
136 result = (char *)xmalloc (2 * strlen (string) + 1);
137
138 for (r = result, s = string; s && (c = *s); s++)
139 {
140 switch (c)
141 {
142 case ' ': case '\t': case '\n': /* IFS white space */
143 case '\'': case '"': case '\\': /* quoting chars */
144 case '|': case '&': case ';': /* shell metacharacters */
145 case '(': case ')': case '<': case '>':
146 case '!': case '{': case '}': /* reserved words */
147 case '*': case '[': case '?': case ']': /* globbing chars */
148 case '^':
149 case '$': case '`': /* expansion chars */
150 case ',': /* brace expansion */
151 *r++ = '\\';
152 *r++ = c;
153 break;
154 #if 0
155 case '~': /* tilde expansion */
156 if (s == string || s[-1] == '=' || s[-1] == ':')
157 *r++ = '\\';
158 *r++ = c;
159 break;
160 #endif
161 case '#': /* comment char */
162 if (s == string)
163 *r++ = '\\';
164 /* FALLTHROUGH */
165 default:
166 *r++ = c;
167 break;
168 }
169 }
170
171 *r = '\0';
172 return (result);
173 }
174
175 #if defined (PROMPT_STRING_DECODE)
176 /* Quote characters that get special treatment when in double quotes in STRING
177 using backslashes. Return a new string. */
178 char *
179 sh_backslash_quote_for_double_quotes (string)
180 char *string;
181 {
182 unsigned char c;
183 char *result, *r, *s;
184
185 result = (char *)xmalloc (2 * strlen (string) + 1);
186
187 for (r = result, s = string; s && (c = *s); s++)
188 {
189 if (sh_syntaxtab[c] & CBSDQUOTE)
190 *r++ = '\\';
191
192 *r++ = c;
193 }
194
195 *r = '\0';
196 return (result);
197 }
198 #endif /* PROMPT_STRING_DECODE */
199
200 int
201 sh_contains_shell_metas (string)
202 char *string;
203 {
204 char *s;
205
206 for (s = string; s && *s; s++)
207 {
208 switch (*s)
209 {
210 case ' ': case '\t': case '\n': /* IFS white space */
211 case '\'': case '"': case '\\': /* quoting chars */
212 case '|': case '&': case ';': /* shell metacharacters */
213 case '(': case ')': case '<': case '>':
214 case '!': case '{': case '}': /* reserved words */
215 case '*': case '[': case '?': case ']': /* globbing chars */
216 case '^':
217 case '$': case '`': /* expansion chars */
218 return (1);
219 case '~': /* tilde expansion */
220 if (s == string || s[-1] == '=' || s[-1] == ':')
221 return (1);
222 break;
223 case '#':
224 if (s == string) /* comment char */
225 return (1);
226 /* FALLTHROUGH */
227 default:
228 break;
229 }
230 }
231
232 return (0);
233 }