Added gitignore entries needed to ignore derived objects generated from full build...
[bash.git] / lib / sh / shquote.c
bloba1e9146bfa8171ae43bf62b44fc3a12f03c098b5
1 /* shquote - functions to quote and dequote strings */
3 /* Copyright (C) 1999 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #if defined (HAVE_UNISTD_H)
24 # ifdef _MINIX
25 # include <sys/types.h>
26 # endif
27 # include <unistd.h>
28 #endif
30 #include <stdio.h>
32 #include "syntax.h"
33 #include <xmalloc.h>
35 /* **************************************************************** */
36 /* */
37 /* Functions for quoting strings to be re-read as input */
38 /* */
39 /* **************************************************************** */
41 /* Return a new string which is the single-quoted version of STRING.
42 Used by alias and trap, among others. */
43 char *
44 sh_single_quote (string)
45 const char *string;
47 register int c;
48 char *result, *r;
49 const char *s;
51 result = (char *)xmalloc (3 + (4 * strlen (string)));
52 r = result;
53 *r++ = '\'';
55 for (s = string; s && (c = *s); s++)
57 *r++ = c;
59 if (c == '\'')
61 *r++ = '\\'; /* insert escaped single quote */
62 *r++ = '\'';
63 *r++ = '\''; /* start new quoted string */
67 *r++ = '\'';
68 *r = '\0';
70 return (result);
73 /* Quote STRING using double quotes. Return a new string. */
74 char *
75 sh_double_quote (string)
76 const char *string;
78 register unsigned char c;
79 char *result, *r;
80 const char *s;
82 result = (char *)xmalloc (3 + (2 * strlen (string)));
83 r = result;
84 *r++ = '"';
86 for (s = string; s && (c = *s); s++)
88 /* Backslash-newline disappears within double quotes, so don't add one. */
89 if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
90 *r++ = '\\';
91 else if (c == CTLESC || c == CTLNUL)
92 *r++ = CTLESC; /* could be '\\'? */
94 *r++ = c;
97 *r++ = '"';
98 *r = '\0';
100 return (result);
103 /* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote
104 double quote characters in S with backslashes. */
105 char *
106 sh_mkdoublequoted (s, slen, flags)
107 const char *s;
108 int slen, flags;
110 char *r, *ret;
111 int rlen;
113 rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
114 ret = r = (char *)xmalloc (rlen);
116 *r++ = '"';
117 while (*s)
119 if (flags && *s == '"')
120 *r++ = '\\';
121 *r++ = *s++;
123 *r++ = '"';
124 *r = '\0';
126 return ret;
129 /* Remove backslashes that are quoting characters that are special between
130 double quotes. Return a new string. XXX - should this handle CTLESC
131 and CTLNUL? */
132 char *
133 sh_un_double_quote (string)
134 char *string;
136 register int c, pass_next;
137 char *result, *r, *s;
139 r = result = (char *)xmalloc (strlen (string) + 1);
141 for (pass_next = 0, s = string; s && (c = *s); s++)
143 if (pass_next)
145 *r++ = c;
146 pass_next = 0;
147 continue;
149 if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE))
151 pass_next = 1;
152 continue;
154 *r++ = c;
157 *r = '\0';
158 return result;
161 /* Quote special characters in STRING using backslashes. Return a new
162 string. NOTE: if the string is to be further expanded, we need a
163 way to protect the CTLESC and CTLNUL characters. As I write this,
164 the current callers will never cause the string to be expanded without
165 going through the shell parser, which will protect the internal
166 quoting characters. */
167 char *
168 sh_backslash_quote (string)
169 char *string;
171 int c;
172 char *result, *r, *s;
174 result = (char *)xmalloc (2 * strlen (string) + 1);
176 for (r = result, s = string; s && (c = *s); s++)
178 switch (c)
180 case ' ': case '\t': case '\n': /* IFS white space */
181 case '\'': case '"': case '\\': /* quoting chars */
182 case '|': case '&': case ';': /* shell metacharacters */
183 case '(': case ')': case '<': case '>':
184 case '!': case '{': case '}': /* reserved words */
185 case '*': case '[': case '?': case ']': /* globbing chars */
186 case '^':
187 case '$': case '`': /* expansion chars */
188 case ',': /* brace expansion */
189 *r++ = '\\';
190 *r++ = c;
191 break;
192 #if 0
193 case '~': /* tilde expansion */
194 if (s == string || s[-1] == '=' || s[-1] == ':')
195 *r++ = '\\';
196 *r++ = c;
197 break;
199 case CTLESC: case CTLNUL: /* internal quoting characters */
200 *r++ = CTLESC; /* could be '\\'? */
201 *r++ = c;
202 break;
203 #endif
205 case '#': /* comment char */
206 if (s == string)
207 *r++ = '\\';
208 /* FALLTHROUGH */
209 default:
210 *r++ = c;
211 break;
215 *r = '\0';
216 return (result);
219 #if defined (PROMPT_STRING_DECODE)
220 /* Quote characters that get special treatment when in double quotes in STRING
221 using backslashes. Return a new string. */
222 char *
223 sh_backslash_quote_for_double_quotes (string)
224 char *string;
226 unsigned char c;
227 char *result, *r, *s;
229 result = (char *)xmalloc (2 * strlen (string) + 1);
231 for (r = result, s = string; s && (c = *s); s++)
233 if (sh_syntaxtab[c] & CBSDQUOTE)
234 *r++ = '\\';
235 /* I should probably add flags for these to sh_syntaxtab[] */
236 else if (c == CTLESC || c == CTLNUL)
237 *r++ = CTLESC; /* could be '\\'? */
239 *r++ = c;
242 *r = '\0';
243 return (result);
245 #endif /* PROMPT_STRING_DECODE */
248 sh_contains_shell_metas (string)
249 char *string;
251 char *s;
253 for (s = string; s && *s; s++)
255 switch (*s)
257 case ' ': case '\t': case '\n': /* IFS white space */
258 case '\'': case '"': case '\\': /* quoting chars */
259 case '|': case '&': case ';': /* shell metacharacters */
260 case '(': case ')': case '<': case '>':
261 case '!': case '{': case '}': /* reserved words */
262 case '*': case '[': case '?': case ']': /* globbing chars */
263 case '^':
264 case '$': case '`': /* expansion chars */
265 return (1);
266 case '~': /* tilde expansion */
267 if (s == string || s[-1] == '=' || s[-1] == ':')
268 return (1);
269 break;
270 case '#':
271 if (s == string) /* comment char */
272 return (1);
273 /* FALLTHROUGH */
274 default:
275 break;
279 return (0);