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 == c_quoting_style)
270 STORE ('0' + (c >> 6));
271 STORE ('0' + ((c >> 3) & 7));
278 if (! (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
293 if (len < buffersize)
298 /* Use storage slot N to return a quoted version of the string ARG.
299 OPTIONS specifies the quoting options.
300 The returned value points to static storage that can be
301 reused by the next call to this function with the same value of N.
302 N must be nonnegative. */
304 quotearg_n_options (unsigned int n, char const *arg,
305 struct quoting_options const *options)
307 static unsigned int nslots;
308 static struct slotvec
316 unsigned int n1 = n + 1;
317 size_t s = n1 * sizeof (struct slotvec);
318 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
320 slotvec = (struct slotvec *) xrealloc (slotvec, s);
321 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
326 size_t size = slotvec[n].size;
327 char *val = slotvec[n].val;
328 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
332 slotvec[n].size = size = qsize + 1;
333 slotvec[n].val = val = xrealloc (val, size);
334 quotearg_buffer (val, size, arg, (size_t) -1, options);
342 quotearg_n (unsigned int n, char const *arg)
344 return quotearg_n_options (n, arg, &default_quoting_options);
348 quotearg (char const *arg)
350 return quotearg_n (0, arg);
354 quotearg_char (char const *arg, char ch)
356 struct quoting_options options;
357 options = default_quoting_options;
358 set_char_quoting (&options, ch, 1);
359 return quotearg_n_options (0, arg, &options);
363 quotearg_colon (char const *arg)
365 return quotearg_char (arg, ':');