]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/sh/shquote.c
Imported from ../bash-2.04.tar.gz.
[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 #if !defined(slashify_in_quotes)
31 # define slashify_in_quotes "\\`$\"\n"
32 #endif
33
34 extern char *xmalloc ();
35
36 /* **************************************************************** */
37 /* */
38 /* Functions for quoting strings to be re-read as input */
39 /* */
40 /* **************************************************************** */
41
42 /* Return a new string which is the single-quoted version of STRING.
43 Used by alias and trap, among others. */
44 char *
45 single_quote (string)
46 char *string;
47 {
48 register int c;
49 char *result, *r, *s;
50
51 result = xmalloc (3 + (4 * strlen (string)));
52 r = result;
53 *r++ = '\'';
54
55 for (s = string; s && (c = *s); s++)
56 {
57 *r++ = c;
58
59 if (c == '\'')
60 {
61 *r++ = '\\'; /* insert escaped single quote */
62 *r++ = '\'';
63 *r++ = '\''; /* start new quoted string */
64 }
65 }
66
67 *r++ = '\'';
68 *r = '\0';
69
70 return (result);
71 }
72
73 /* Quote STRING using double quotes. Return a new string. */
74 char *
75 double_quote (string)
76 char *string;
77 {
78 register int c;
79 char *result, *r, *s;
80
81 result = xmalloc (3 + (2 * strlen (string)));
82 r = result;
83 *r++ = '"';
84
85 for (s = string; s && (c = *s); s++)
86 {
87 switch (c)
88 {
89 case '"':
90 case '$':
91 case '`':
92 case '\\':
93 case '\n': /* XXX */
94 *r++ = '\\';
95 default:
96 *r++ = c;
97 break;
98 }
99 }
100
101 *r++ = '"';
102 *r = '\0';
103
104 return (result);
105 }
106
107 /* Remove backslashes that are quoting characters that are special between
108 double quotes. Return a new string. */
109 char *
110 un_double_quote (string)
111 char *string;
112 {
113 register int c, pass_next;
114 char *result, *r, *s;
115
116 r = result = xmalloc (strlen (string) + 1);
117
118 for (pass_next = 0, s = string; s && (c = *s); s++)
119 {
120 if (pass_next)
121 {
122 *r++ = c;
123 pass_next = 0;
124 continue;
125 }
126 if (c == '\\' && strchr (slashify_in_quotes, s[1]))
127 {
128 pass_next = 1;
129 continue;
130 }
131 *r++ = c;
132 }
133
134 *r = '\0';
135 return result;
136 }
137
138 /* Quote special characters in STRING using backslashes. Return a new
139 string. */
140 char *
141 backslash_quote (string)
142 char *string;
143 {
144 int c;
145 char *result, *r, *s;
146
147 result = xmalloc (2 * strlen (string) + 1);
148
149 for (r = result, s = string; s && (c = *s); s++)
150 {
151 switch (c)
152 {
153 case ' ': case '\t': case '\n': /* IFS white space */
154 case '\'': case '"': case '\\': /* quoting chars */
155 case '|': case '&': case ';': /* shell metacharacters */
156 case '(': case ')': case '<': case '>':
157 case '!': case '{': case '}': /* reserved words */
158 case '*': case '[': case '?': case ']': /* globbing chars */
159 case '^':
160 case '$': case '`': /* expansion chars */
161 *r++ = '\\';
162 *r++ = c;
163 break;
164 #if 0
165 case '~': /* tilde expansion */
166 if (s == string || s[-1] == '=' || s[-1] == ':')
167 *r++ = '\\';
168 *r++ = c;
169 break;
170 #endif
171 case '#': /* comment char */
172 if (s == string)
173 *r++ = '\\';
174 /* FALLTHROUGH */
175 default:
176 *r++ = c;
177 break;
178 }
179 }
180
181 *r = '\0';
182 return (result);
183 }
184
185 int
186 contains_shell_metas (string)
187 char *string;
188 {
189 char *s;
190
191 for (s = string; s && *s; s++)
192 {
193 switch (*s)
194 {
195 case ' ': case '\t': case '\n': /* IFS white space */
196 case '\'': case '"': case '\\': /* quoting chars */
197 case '|': case '&': case ';': /* shell metacharacters */
198 case '(': case ')': case '<': case '>':
199 case '!': case '{': case '}': /* reserved words */
200 case '*': case '[': case '?': case ']': /* globbing chars */
201 case '^':
202 case '$': case '`': /* expansion chars */
203 return (1);
204 case '~': /* tilde expansion */
205 if (s == string || s[-1] == '=' || s[-1] == ':')
206 return (1);
207 case '#':
208 if (s == string) /* comment char */
209 return (1);
210 /* FALLTHROUGH */
211 default:
212 break;
213 }
214 }
215
216 return (0);
217 }