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)
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[] =
74 "literal", "shell", "shell-always", "c", "escape", 0
77 /* Allocate a new set of quoting options, with contents initially identical
78 to O if O is not null, or to a default value if O is null.
79 It is the caller's responsibility to free the result. */
80 struct quoting_options *
81 clone_quoting_options (struct quoting_options *o)
83 struct quoting_options *p
84 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
88 memset (p, 0, sizeof *p);
92 /* Get the value of O's quoting style. */
94 get_quoting_style (struct quoting_options *o)
99 /* In O, set the value of the quoting style to S. */
101 set_quoting_style (struct quoting_options *o, enum quoting_style s)
106 /* In O, set the value of the quoting options for character C to I.
107 Return the old value. Currently, the only values defined for I are
108 0 (the default) and 1 (which means to quote the character even if
109 it would not otherwise be quoted). */
111 set_char_quoting (struct quoting_options *o, char c, int i)
113 unsigned char uc = c;
114 int *p = o->quote_these_too + uc / INT_BITS;
115 int shift = uc % INT_BITS;
116 int r = (*p >> shift) & 1;
117 *p ^= ((i & 1) ^ r) << shift;
121 /* Place into buffer BUF (of size BUFSIZE) a quoted version of
122 argument ARG (of size ARGSIZE), using O to control quoting.
123 Terminate the output with a null character, and return the written
124 size of the output, not counting the terminating null.
125 If BUFSIZE is too small to store the output string, return the
126 value that would have been returned had BUFSIZE been large enough.
127 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
129 quotearg_buffer (char *buf, size_t bufsize,
130 char const *arg, size_t argsize,
131 struct quoting_options const *o)
137 enum quoting_style quoting_style = o->style;
138 #define STORE(c) do { if (len < bufsize) buf[len] = (c); len++; } while (0)
140 switch (quoting_style)
142 case shell_quoting_style:
143 if (! (argsize == -1 ? arg[0] == '\0' : argsize == 0))
154 if (argsize == -1 ? arg[i] == '\0' : i == argsize)
161 case '\t': case '\n': case ' ':
162 case '!': /* special in csh */
163 case '"': case '$': case '&': case '\'':
164 case '(': case ')': case '*': case ';':
165 case '<': case '>': case '?': case '[': case '\\':
166 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
171 if (o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
183 case shell_always_quoting_style:
187 case c_quoting_style:
201 for (i = 0; ! (argsize == -1 ? arg[i] == '\0' : i == argsize); i++)
205 switch (quoting_style)
207 case literal_quoting_style:
210 case shell_quoting_style:
211 case shell_always_quoting_style:
220 case c_quoting_style:
221 case escape_quoting_style:
224 case '?': /* Do not generate trigraphs. */
225 case '\\': goto store_escape;
226 /* Not all C compilers know what \a means. */
227 case 7 : c = 'a'; goto store_escape;
228 case '\b': c = 'b'; goto store_escape;
229 case '\f': c = 'f'; goto store_escape;
230 case '\n': c = 'n'; goto store_escape;
231 case '\r': c = 'r'; goto store_escape;
232 case '\t': c = 't'; goto store_escape;
233 case '\v': c = 'v'; goto store_escape;
236 if (quoting_style == escape_quoting_style)
241 if (quoting_style == c_quoting_style)
249 STORE ('0' + (c >> 6));
250 STORE ('0' + ((c >> 3) & 3));
257 if (! (o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
277 /* Use storage slot N to return a quoted version of the string ARG.
278 OPTIONS specifies the quoting options.
279 The returned value points to static storage that can be
280 reused by the next call to this function with the same value of N.
281 N must be nonnegative. */
283 quotearg_n_options (int n, char const *arg, struct quoting_options *options)
285 static unsigned nslots;
286 static struct slotvec
295 size_t s = n1 * sizeof (struct slotvec);
296 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
298 slotvec = (struct slotvec *) xrealloc (slotvec, s);
299 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
304 size_t size = slotvec[n].size;
305 char *val = slotvec[n].val;
306 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
310 slotvec[n].size = size = qsize + 1;
311 slotvec[n].val = val = xrealloc (val, size);
312 quotearg_buffer (val, size, arg, (size_t) -1, options);
319 struct quoting_options quotearg_quoting_options;
322 quotearg_n (int n, char const *arg)
324 return quotearg_n_options (n, arg, "earg_quoting_options);
328 quotearg (char const *arg)
330 return quotearg_n (0, arg);
334 quotearg_char (char const *arg, char ch)
336 struct quoting_options options;
337 options = quotearg_quoting_options;
338 set_char_quoting (&options, ch, 1);
339 return quotearg_n_options (0, arg, &options);
343 quotearg_colon (char const *arg)
345 return quotearg_char (arg, ':');