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 /* 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
);
92 /* Get the value of O's quoting style. If O is null, use the default. */
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. */
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
;
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. */
132 quotearg_buffer (char *buffer
, size_t buffersize
,
133 char const *arg
, size_t argsize
,
134 struct quoting_options
const *o
)
140 struct quoting_options
const *p
= o
? o
: &default_quoting_options
;
141 enum quoting_style quoting_style
= p
->style
;
145 if (len < buffersize) \
151 switch (quoting_style
)
153 case shell_quoting_style
:
154 if (! (argsize
== -1 ? arg
[0] == '\0' : argsize
== 0))
165 if (argsize
== -1 ? arg
[i
] == '\0' : i
== argsize
)
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 */
182 if (p
->quote_these_too
[c
/ INT_BITS
] & (1 << (c
% INT_BITS
)))
194 case shell_always_quoting_style
:
198 case c_quoting_style
:
212 for (i
= 0; ! (argsize
== -1 ? arg
[i
] == '\0' : i
== argsize
); i
++)
216 switch (quoting_style
)
218 case literal_quoting_style
:
221 case shell_quoting_style
:
222 case shell_always_quoting_style
:
231 case c_quoting_style
:
232 case escape_quoting_style
:
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
;
247 if (quoting_style
== escape_quoting_style
)
252 if (quoting_style
== c_quoting_style
)
260 STORE ('0' + (c
>> 6));
261 STORE ('0' + ((c
>> 3) & 3));
268 if (! (p
->quote_these_too
[c
/ INT_BITS
] & (1 << (c
% INT_BITS
))))
283 if (len
< buffersize
)
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. */
294 quotearg_n_options (int n
, char const *arg
, struct quoting_options
*options
)
296 static unsigned nslots
;
297 static struct slotvec
306 size_t s
= n1
* sizeof (struct slotvec
);
307 if (! (0 < n1
&& n1
== s
/ sizeof (struct slotvec
)))
309 slotvec
= (struct slotvec
*) xrealloc (slotvec
, s
);
310 memset (slotvec
+ nslots
, 0, (n1
- nslots
) * sizeof (struct slotvec
));
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
);
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
);
331 quotearg_n (int n
, char const *arg
)
333 return quotearg_n_options (n
, arg
, &default_quoting_options
);
337 quotearg (char const *arg
)
339 return quotearg_n (0, arg
);
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
);
352 quotearg_colon (char const *arg
)
354 return quotearg_char (arg
, ':');