.
[coreutils.git] / lib / quotearg.c
blobb5fa7355df9a540892e145087d6c2419d636cc4c
1 /* quotearg.c - quote arguments for output
2 Copyright (C) 1998 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Written by Paul Eggert <eggert@twinsun.com> */
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include <sys/types.h>
25 #include <quotearg.h>
26 #include <xalloc.h>
28 #include <ctype.h>
29 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
30 # define ISASCII(c) 1
31 #else
32 # define ISASCII(c) isascii (c)
33 #endif
34 #ifdef isgraph
35 # define ISGRAPH(c) (ISASCII (c) && isgraph (c))
36 #else
37 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
38 #endif
40 #if HAVE_LIMITS_H
41 # include <limits.h>
42 #endif
43 #ifndef CHAR_BIT
44 # define CHAR_BIT 8
45 #endif
46 #ifndef UCHAR_MAX
47 # define UCHAR_MAX ((unsigned char) -1)
48 #endif
50 #if HAVE_STDLIB_H
51 # include <stdlib.h>
52 #endif
54 #if HAVE_STRING_H
55 # include <string.h>
56 #endif
58 #define INT_BITS (sizeof (int) * CHAR_BIT)
60 struct quoting_options
62 /* Basic quoting style. */
63 enum quoting_style style;
65 /* Quote the chararacters indicated by this bit vector even if the
66 quoting style would not normally require them to be quoted. */
67 int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
68 + ((UCHAR_MAX + 1) % INT_BITS != 0))];
71 /* Names of quoting styles. */
72 char const *const quoting_style_args[] =
74 "literal", "shell", "shell-always", "c", "escape", 0
77 /* The default quoting options. */
78 static struct quoting_options default_quoting_options;
80 /* Allocate a new set of quoting options, with contents initially identical
81 to O if O is not null, or to the default if O is null.
82 It is the caller's responsibility to free the result. */
83 struct quoting_options *
84 clone_quoting_options (struct quoting_options *o)
86 struct quoting_options *p
87 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
88 *p = *(o ? o : &default_quoting_options);
89 return p;
92 /* Get the value of O's quoting style. If O is null, use the default. */
93 enum quoting_style
94 get_quoting_style (struct quoting_options *o)
96 return (o ? o : &default_quoting_options)->style;
99 /* In O (or in the default if O is null),
100 set the value of the quoting style to S. */
101 void
102 set_quoting_style (struct quoting_options *o, enum quoting_style s)
104 (o ? o : &default_quoting_options)->style = s;
107 /* In O (or in the default if O is null),
108 set the value of the quoting options for character C to I.
109 Return the old value. Currently, the only values defined for I are
110 0 (the default) and 1 (which means to quote the character even if
111 it would not otherwise be quoted). */
113 set_char_quoting (struct quoting_options *o, char c, int i)
115 unsigned char uc = c;
116 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
117 int shift = uc % INT_BITS;
118 int r = (*p >> shift) & 1;
119 *p ^= ((i & 1) ^ r) << shift;
120 return r;
123 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
124 argument ARG (of size ARGSIZE), using O to control quoting.
125 If O is null, use the default.
126 Terminate the output with a null character, and return the written
127 size of the output, not counting the terminating null.
128 If BUFFERSIZE is too small to store the output string, return the
129 value that would have been returned had BUFFERSIZE been large enough.
130 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
131 size_t
132 quotearg_buffer (char *buffer, size_t buffersize,
133 char const *arg, size_t argsize,
134 struct quoting_options const *o)
136 unsigned char c;
137 size_t i;
138 size_t len;
139 int quote_mark;
140 struct quoting_options const *p = o ? o : &default_quoting_options;
141 enum quoting_style quoting_style = p->style;
142 #define STORE(c) \
143 do \
145 if (len < buffersize) \
146 buffer[len] = (c); \
147 len++; \
149 while (0)
151 switch (quoting_style)
153 case shell_quoting_style:
154 if (! (argsize == -1 ? arg[0] == '\0' : argsize == 0))
156 switch (arg[0])
158 case '#': case '~':
159 break;
161 default:
162 len = 0;
163 for (i = 0; ; i++)
165 if (argsize == -1 ? arg[i] == '\0' : i == argsize)
166 goto done;
168 c = arg[i];
170 switch (c)
172 case '\t': case '\n': case ' ':
173 case '!': /* special in csh */
174 case '"': case '$': case '&': case '\'':
175 case '(': case ')': case '*': case ';':
176 case '<': case '>': case '?': case '[': case '\\':
177 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
178 case '`': case '|':
179 goto needs_quoting;
182 if (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
183 goto needs_quoting;
185 STORE (c);
188 needs_quoting:;
189 break;
192 /* Fall through. */
194 case shell_always_quoting_style:
195 quote_mark = '\'';
196 break;
198 case c_quoting_style:
199 quote_mark = '"';
200 break;
202 default:
203 quote_mark = 0;
204 break;
207 len = 0;
209 if (quote_mark)
210 STORE (quote_mark);
212 for (i = 0; ! (argsize == -1 ? arg[i] == '\0' : i == argsize); i++)
214 c = arg[i];
216 switch (quoting_style)
218 case literal_quoting_style:
219 break;
221 case shell_quoting_style:
222 case shell_always_quoting_style:
223 if (c == '\'')
225 STORE ('\'');
226 STORE ('\\');
227 STORE ('\'');
229 break;
231 case c_quoting_style:
232 case escape_quoting_style:
233 switch (c)
235 case '?': /* Do not generate trigraphs. */
236 case '\\': goto store_escape;
237 /* Not all C compilers know what \a means. */
238 case 7 : c = 'a'; goto store_escape;
239 case '\b': c = 'b'; goto store_escape;
240 case '\f': c = 'f'; goto store_escape;
241 case '\n': c = 'n'; goto store_escape;
242 case '\r': c = 'r'; goto store_escape;
243 case '\t': c = 't'; goto store_escape;
244 case '\v': c = 'v'; goto store_escape;
246 case ' ':
247 if (quoting_style == escape_quoting_style)
248 goto store_escape;
249 break;
251 case '"':
252 if (quoting_style == c_quoting_style)
253 goto store_escape;
254 break;
256 default:
257 if (!ISGRAPH (c))
259 STORE ('\\');
260 STORE ('0' + (c >> 6));
261 STORE ('0' + ((c >> 3) & 3));
262 c = '0' + (c & 3);
263 goto store_c;
265 break;
268 if (! (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
269 goto store_c;
271 store_escape:
272 STORE ('\\');
275 store_c:
276 STORE (c);
279 if (quote_mark)
280 STORE (quote_mark);
282 done:
283 if (len < buffersize)
284 buffer[len] = '\0';
285 return len;
288 /* Use storage slot N to return a quoted version of the string ARG.
289 OPTIONS specifies the quoting options.
290 The returned value points to static storage that can be
291 reused by the next call to this function with the same value of N.
292 N must be nonnegative. */
293 static char *
294 quotearg_n_options (int n, char const *arg, struct quoting_options *options)
296 static unsigned nslots;
297 static struct slotvec
299 size_t size;
300 char *val;
301 } *slotvec;
303 if (nslots <= n)
305 int n1 = n + 1;
306 size_t s = n1 * sizeof (struct slotvec);
307 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
308 abort ();
309 slotvec = (struct slotvec *) xrealloc (slotvec, s);
310 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
311 nslots = n;
315 size_t size = slotvec[n].size;
316 char *val = slotvec[n].val;
317 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
319 if (size <= qsize)
321 slotvec[n].size = size = qsize + 1;
322 slotvec[n].val = val = xrealloc (val, size);
323 quotearg_buffer (val, size, arg, (size_t) -1, options);
326 return val;
330 char *
331 quotearg_n (int n, char const *arg)
333 return quotearg_n_options (n, arg, &default_quoting_options);
336 char *
337 quotearg (char const *arg)
339 return quotearg_n (0, arg);
342 char *
343 quotearg_char (char const *arg, char ch)
345 struct quoting_options options;
346 options = default_quoting_options;
347 set_char_quoting (&options, ch, 1);
348 return quotearg_n_options (0, arg, &options);
351 char *
352 quotearg_colon (char const *arg)
354 return quotearg_char (arg, ':');