1 /* quotearg.c - quote arguments for output
2 Copyright (C) 1998, 1999 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)
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> */
24 #include <sys/types.h>
29 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
32 # define ISASCII(c) isascii (c)
35 # define ISGRAPH(c) (ISASCII (c) && isgraph (c))
37 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
47 # define UCHAR_MAX ((unsigned char) -1)
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[] =
82 /* Correspondances to quoting style names. */
83 enum quoting_style const quoting_style_vals[] =
85 literal_quoting_style,
87 shell_always_quoting_style,
92 /* The default quoting options. */
93 static struct quoting_options default_quoting_options;
95 /* Allocate a new set of quoting options, with contents initially identical
96 to O if O is not null, or to the default if O is null.
97 It is the caller's responsibility to free the result. */
98 struct quoting_options *
99 clone_quoting_options (struct quoting_options *o)
101 struct quoting_options *p
102 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
103 *p = *(o ? o : &default_quoting_options);
107 /* Get the value of O's quoting style. If O is null, use the default. */
109 get_quoting_style (struct quoting_options *o)
111 return (o ? o : &default_quoting_options)->style;
114 /* In O (or in the default if O is null),
115 set the value of the quoting style to S. */
117 set_quoting_style (struct quoting_options *o, enum quoting_style s)
119 (o ? o : &default_quoting_options)->style = s;
122 /* In O (or in the default if O is null),
123 set the value of the quoting options for character C to I.
124 Return the old value. Currently, the only values defined for I are
125 0 (the default) and 1 (which means to quote the character even if
126 it would not otherwise be quoted). */
128 set_char_quoting (struct quoting_options *o, char c, int i)
130 unsigned char uc = c;
131 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
132 int shift = uc % INT_BITS;
133 int r = (*p >> shift) & 1;
134 *p ^= ((i & 1) ^ r) << shift;
138 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
139 argument ARG (of size ARGSIZE), using O to control quoting.
140 If O is null, use the default.
141 Terminate the output with a null character, and return the written
142 size of the output, not counting the terminating null.
143 If BUFFERSIZE is too small to store the output string, return the
144 value that would have been returned had BUFFERSIZE been large enough.
145 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
147 quotearg_buffer (char *buffer, size_t buffersize,
148 char const *arg, size_t argsize,
149 struct quoting_options const *o)
155 struct quoting_options const *p = o ? o : &default_quoting_options;
156 enum quoting_style quoting_style = p->style;
160 if (len < buffersize) \
166 switch (quoting_style)
168 case shell_quoting_style:
169 if (! (argsize == (size_t) -1 ? arg[0] == '\0' : argsize == 0))
180 if (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize)
187 case '\t': case '\n': case ' ':
188 case '!': /* special in csh */
189 case '"': case '$': case '&': case '\'':
190 case '(': case ')': case '*': case ';':
191 case '<': case '>': case '?': case '[': case '\\':
192 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
197 if (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
209 case shell_always_quoting_style:
213 case c_quoting_style:
227 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
231 switch (quoting_style)
233 case literal_quoting_style:
236 case shell_quoting_style:
237 case shell_always_quoting_style:
246 case c_quoting_style:
247 case escape_quoting_style:
250 case '?': /* Do not generate trigraphs. */
251 case '\\': goto store_escape;
252 /* Not all C compilers know what \a means. */
253 case 7 : c = 'a'; goto store_escape;
254 case '\b': c = 'b'; goto store_escape;
255 case '\f': c = 'f'; goto store_escape;
256 case '\n': c = 'n'; goto store_escape;
257 case '\r': c = 'r'; goto store_escape;
258 case '\t': c = 't'; goto store_escape;
259 case '\v': c = 'v'; goto store_escape;
262 if (quoting_style == escape_quoting_style)
267 if (quoting_style == c_quoting_style)
275 STORE ('0' + (c >> 6));
276 STORE ('0' + ((c >> 3) & 7));
283 if (! (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
298 if (len < buffersize)
303 /* Use storage slot N to return a quoted version of the string ARG.
304 OPTIONS specifies the quoting options.
305 The returned value points to static storage that can be
306 reused by the next call to this function with the same value of N.
307 N must be nonnegative. */
309 quotearg_n_options (unsigned int n, char const *arg,
310 struct quoting_options *options)
312 static unsigned int nslots;
313 static struct slotvec
322 size_t s = n1 * sizeof (struct slotvec);
323 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
325 slotvec = (struct slotvec *) xrealloc (slotvec, s);
326 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
331 size_t size = slotvec[n].size;
332 char *val = slotvec[n].val;
333 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
337 slotvec[n].size = size = qsize + 1;
338 slotvec[n].val = val = xrealloc (val, size);
339 quotearg_buffer (val, size, arg, (size_t) -1, options);
347 quotearg_n (unsigned int n, char const *arg)
349 return quotearg_n_options (n, arg, &default_quoting_options);
353 quotearg (char const *arg)
355 return quotearg_n (0, arg);
359 quotearg_char (char const *arg, char ch)
361 struct quoting_options options;
362 options = default_quoting_options;
363 set_char_quoting (&options, ch, 1);
364 return quotearg_n_options (0, arg, &options);
368 quotearg_colon (char const *arg)
370 return quotearg_char (arg, ':');