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. N is deliberately declared with type `int'
303 to allow for future extensions (using negative values). */
305 quotearg_n_options (int n
, char const *arg
,
306 struct quoting_options
const *options
)
308 static unsigned int nslots
;
309 static struct slotvec
318 size_t s
= n1
* sizeof (struct slotvec
);
319 if (! (0 < n1
&& n1
== s
/ sizeof (struct slotvec
)))
321 slotvec
= (struct slotvec
*) xrealloc (slotvec
, s
);
322 memset (slotvec
+ nslots
, 0, (n1
- nslots
) * sizeof (struct slotvec
));
327 size_t size
= slotvec
[n
].size
;
328 char *val
= slotvec
[n
].val
;
329 size_t qsize
= quotearg_buffer (val
, size
, arg
, (size_t) -1, options
);
333 slotvec
[n
].size
= size
= qsize
+ 1;
334 slotvec
[n
].val
= val
= xrealloc (val
, size
);
335 quotearg_buffer (val
, size
, arg
, (size_t) -1, options
);
343 quotearg_n (unsigned int n
, char const *arg
)
345 return quotearg_n_options (n
, arg
, &default_quoting_options
);
349 quotearg (char const *arg
)
351 return quotearg_n (0, arg
);
355 quotearg_char (char const *arg
, char ch
)
357 struct quoting_options options
;
358 options
= default_quoting_options
;
359 set_char_quoting (&options
, ch
, 1);
360 return quotearg_n_options (0, arg
, &options
);
364 quotearg_colon (char const *arg
)
366 return quotearg_char (arg
, ':');