]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/sh/shquote.c
commit bash-20040914 snapshot
[thirdparty/bash.git] / lib / sh / shquote.c
CommitLineData
bb70624e
JA
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
28ef6c31 30#include "syntax.h"
f73dda09 31#include <xmalloc.h>
bb70624e
JA
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 *
28ef6c31 42sh_single_quote (string)
bb70624e
JA
43 char *string;
44{
45 register int c;
46 char *result, *r, *s;
47
f73dda09 48 result = (char *)xmalloc (3 + (4 * strlen (string)));
bb70624e
JA
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 *
28ef6c31 72sh_double_quote (string)
bb70624e
JA
73 char *string;
74{
f73dda09 75 register unsigned char c;
bb70624e
JA
76 char *result, *r, *s;
77
f73dda09 78 result = (char *)xmalloc (3 + (2 * strlen (string)));
bb70624e
JA
79 r = result;
80 *r++ = '"';
81
82 for (s = string; s && (c = *s); s++)
83 {
28ef6c31
JA
84 if (sh_syntaxtab[c] & CBSDQUOTE)
85 *r++ = '\\';
d3a24ed2
CR
86 else if (c == CTLESC || c == CTLNUL)
87 *r++ = CTLESC; /* could be '\\'? */
28ef6c31
JA
88
89 *r++ = c;
bb70624e
JA
90 }
91
92 *r++ = '"';
93 *r = '\0';
94
95 return (result);
96}
97
98/* Remove backslashes that are quoting characters that are special between
d3a24ed2
CR
99 double quotes. Return a new string. XXX - should this handle CTLESC
100 and CTLNUL? */
bb70624e 101char *
28ef6c31 102sh_un_double_quote (string)
bb70624e
JA
103 char *string;
104{
105 register int c, pass_next;
106 char *result, *r, *s;
107
f73dda09 108 r = result = (char *)xmalloc (strlen (string) + 1);
bb70624e
JA
109
110 for (pass_next = 0, s = string; s && (c = *s); s++)
111 {
112 if (pass_next)
113 {
114 *r++ = c;
115 pass_next = 0;
116 continue;
117 }
f73dda09 118 if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE))
bb70624e
JA
119 {
120 pass_next = 1;
121 continue;
122 }
123 *r++ = c;
124 }
125
126 *r = '\0';
127 return result;
128}
129
130/* Quote special characters in STRING using backslashes. Return a new
131 string. */
132char *
28ef6c31 133sh_backslash_quote (string)
bb70624e
JA
134 char *string;
135{
136 int c;
137 char *result, *r, *s;
138
f73dda09 139 result = (char *)xmalloc (2 * strlen (string) + 1);
bb70624e
JA
140
141 for (r = result, s = string; s && (c = *s); s++)
142 {
143 switch (c)
144 {
145 case ' ': case '\t': case '\n': /* IFS white space */
146 case '\'': case '"': case '\\': /* quoting chars */
147 case '|': case '&': case ';': /* shell metacharacters */
148 case '(': case ')': case '<': case '>':
149 case '!': case '{': case '}': /* reserved words */
150 case '*': case '[': case '?': case ']': /* globbing chars */
151 case '^':
152 case '$': case '`': /* expansion chars */
7117c2d2 153 case ',': /* brace expansion */
bb70624e
JA
154 *r++ = '\\';
155 *r++ = c;
156 break;
157#if 0
158 case '~': /* tilde expansion */
159 if (s == string || s[-1] == '=' || s[-1] == ':')
160 *r++ = '\\';
161 *r++ = c;
162 break;
163#endif
d3a24ed2
CR
164 case CTLESC: case CTLNUL: /* internal quoting characters */
165 *r++ = CTLESC; /* could be '\\'? */
166 *r++ = c;
167 break;
168
bb70624e
JA
169 case '#': /* comment char */
170 if (s == string)
171 *r++ = '\\';
172 /* FALLTHROUGH */
173 default:
174 *r++ = c;
175 break;
176 }
177 }
178
179 *r = '\0';
180 return (result);
181}
182
28ef6c31
JA
183#if defined (PROMPT_STRING_DECODE)
184/* Quote characters that get special treatment when in double quotes in STRING
185 using backslashes. Return a new string. */
186char *
187sh_backslash_quote_for_double_quotes (string)
188 char *string;
189{
f73dda09 190 unsigned char c;
28ef6c31
JA
191 char *result, *r, *s;
192
f73dda09 193 result = (char *)xmalloc (2 * strlen (string) + 1);
28ef6c31
JA
194
195 for (r = result, s = string; s && (c = *s); s++)
196 {
197 if (sh_syntaxtab[c] & CBSDQUOTE)
198 *r++ = '\\';
d3a24ed2
CR
199 /* I should probably add flags for these to sh_syntaxtab[] */
200 else if (c == CTLESC || c == CTLNUL)
201 *r++ = CTLESC; /* could be '\\'? */
28ef6c31
JA
202
203 *r++ = c;
204 }
205
206 *r = '\0';
207 return (result);
208}
209#endif /* PROMPT_STRING_DECODE */
210
bb70624e 211int
28ef6c31 212sh_contains_shell_metas (string)
bb70624e
JA
213 char *string;
214{
215 char *s;
216
217 for (s = string; s && *s; s++)
218 {
219 switch (*s)
220 {
221 case ' ': case '\t': case '\n': /* IFS white space */
222 case '\'': case '"': case '\\': /* quoting chars */
223 case '|': case '&': case ';': /* shell metacharacters */
224 case '(': case ')': case '<': case '>':
225 case '!': case '{': case '}': /* reserved words */
226 case '*': case '[': case '?': case ']': /* globbing chars */
227 case '^':
228 case '$': case '`': /* expansion chars */
229 return (1);
230 case '~': /* tilde expansion */
231 if (s == string || s[-1] == '=' || s[-1] == ':')
232 return (1);
f73dda09 233 break;
bb70624e
JA
234 case '#':
235 if (s == string) /* comment char */
236 return (1);
237 /* FALLTHROUGH */
238 default:
239 break;
240 }
241 }
242
243 return (0);
244}