Mercurial > hg > octave-kai > gnulib-hg
annotate lib/quotearg.c @ 1650:aa48c3374848
(quotearg_n_options): Declare n1 to be of type
unsigned int, not just int.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Sat, 16 Jan 1999 15:55:20 +0000 |
parents | e4824ae11924 |
children | 8ae2c5884032 |
rev | line source |
---|---|
1248 | 1 /* quotearg.c - quote arguments for output |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc. |
1248 | 3 |
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) | |
7 any later version. | |
8 | |
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. | |
13 | |
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. */ | |
17 | |
18 /* Written by Paul Eggert <eggert@twinsun.com> */ | |
19 | |
20 #if HAVE_CONFIG_H | |
21 # include <config.h> | |
22 #endif | |
23 | |
24 #include <sys/types.h> | |
25 #include <quotearg.h> | |
26 #include <xalloc.h> | |
27 | |
28 #include <ctype.h> | |
29 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) | |
30 # define ISASCII(c) 1 | |
31 #else | |
32 # define ISASCII(c) isascii (c) | |
33 #endif | |
34 #ifdef isgraph | |
35 # define ISGRAPH(c) (ISASCII (c) && isgraph (c)) | |
36 #else | |
37 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) | |
38 #endif | |
39 | |
40 #if HAVE_LIMITS_H | |
41 # include <limits.h> | |
42 #endif | |
43 #ifndef CHAR_BIT | |
44 # define CHAR_BIT 8 | |
45 #endif | |
46 #ifndef UCHAR_MAX | |
47 # define UCHAR_MAX ((unsigned char) -1) | |
48 #endif | |
49 | |
50 #if HAVE_STDLIB_H | |
51 # include <stdlib.h> | |
52 #endif | |
53 | |
54 #if HAVE_STRING_H | |
55 # include <string.h> | |
56 #endif | |
57 | |
58 #define INT_BITS (sizeof (int) * CHAR_BIT) | |
59 | |
60 struct quoting_options | |
61 { | |
62 /* Basic quoting style. */ | |
63 enum quoting_style style; | |
64 | |
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))]; | |
69 }; | |
70 | |
71 /* Names of quoting styles. */ | |
72 char const *const quoting_style_args[] = | |
73 { | |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
74 "literal", |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
75 "shell", |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
76 "shell-always", |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
77 "c", |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
78 "escape", |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
79 0 |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
80 }; |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
81 |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
82 /* Correspondances to quoting style names. */ |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
83 enum quoting_style const quoting_style_vals[] = |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
84 { |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
85 literal_quoting_style, |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
86 shell_quoting_style, |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
87 shell_always_quoting_style, |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
88 c_quoting_style, |
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
89 escape_quoting_style |
1248 | 90 }; |
91 | |
1282 | 92 /* The default quoting options. */ |
93 static struct quoting_options default_quoting_options; | |
94 | |
1248 | 95 /* Allocate a new set of quoting options, with contents initially identical |
1282 | 96 to O if O is not null, or to the default if O is null. |
1248 | 97 It is the caller's responsibility to free the result. */ |
98 struct quoting_options * | |
99 clone_quoting_options (struct quoting_options *o) | |
100 { | |
101 struct quoting_options *p | |
102 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options)); | |
1282 | 103 *p = *(o ? o : &default_quoting_options); |
1248 | 104 return p; |
105 } | |
106 | |
1282 | 107 /* Get the value of O's quoting style. If O is null, use the default. */ |
1248 | 108 enum quoting_style |
109 get_quoting_style (struct quoting_options *o) | |
110 { | |
1282 | 111 return (o ? o : &default_quoting_options)->style; |
1248 | 112 } |
113 | |
1282 | 114 /* In O (or in the default if O is null), |
115 set the value of the quoting style to S. */ | |
1248 | 116 void |
117 set_quoting_style (struct quoting_options *o, enum quoting_style s) | |
118 { | |
1282 | 119 (o ? o : &default_quoting_options)->style = s; |
1248 | 120 } |
121 | |
1282 | 122 /* In O (or in the default if O is null), |
123 set the value of the quoting options for character C to I. | |
1248 | 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). */ | |
127 int | |
128 set_char_quoting (struct quoting_options *o, char c, int i) | |
129 { | |
130 unsigned char uc = c; | |
1282 | 131 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; |
1248 | 132 int shift = uc % INT_BITS; |
133 int r = (*p >> shift) & 1; | |
134 *p ^= ((i & 1) ^ r) << shift; | |
135 return r; | |
136 } | |
137 | |
1282 | 138 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of |
1248 | 139 argument ARG (of size ARGSIZE), using O to control quoting. |
1282 | 140 If O is null, use the default. |
1248 | 141 Terminate the output with a null character, and return the written |
142 size of the output, not counting the terminating null. | |
1282 | 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. | |
1248 | 145 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ |
146 size_t | |
1282 | 147 quotearg_buffer (char *buffer, size_t buffersize, |
1248 | 148 char const *arg, size_t argsize, |
149 struct quoting_options const *o) | |
150 { | |
151 unsigned char c; | |
152 size_t i; | |
153 size_t len; | |
154 int quote_mark; | |
1282 | 155 struct quoting_options const *p = o ? o : &default_quoting_options; |
156 enum quoting_style quoting_style = p->style; | |
157 #define STORE(c) \ | |
158 do \ | |
159 { \ | |
160 if (len < buffersize) \ | |
161 buffer[len] = (c); \ | |
162 len++; \ | |
163 } \ | |
164 while (0) | |
1248 | 165 |
166 switch (quoting_style) | |
167 { | |
168 case shell_quoting_style: | |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
169 if (! (argsize == (size_t) -1 ? arg[0] == '\0' : argsize == 0)) |
1248 | 170 { |
171 switch (arg[0]) | |
172 { | |
173 case '#': case '~': | |
174 break; | |
175 | |
176 default: | |
177 len = 0; | |
178 for (i = 0; ; i++) | |
179 { | |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
180 if (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize) |
1248 | 181 goto done; |
182 | |
183 c = arg[i]; | |
184 | |
185 switch (c) | |
186 { | |
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 */ | |
193 case '`': case '|': | |
194 goto needs_quoting; | |
195 } | |
196 | |
1282 | 197 if (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))) |
1248 | 198 goto needs_quoting; |
199 | |
200 STORE (c); | |
201 } | |
202 | |
203 needs_quoting:; | |
204 break; | |
205 } | |
206 } | |
207 /* Fall through. */ | |
208 | |
209 case shell_always_quoting_style: | |
210 quote_mark = '\''; | |
211 break; | |
212 | |
213 case c_quoting_style: | |
214 quote_mark = '"'; | |
215 break; | |
216 | |
217 default: | |
218 quote_mark = 0; | |
219 break; | |
220 } | |
221 | |
222 len = 0; | |
223 | |
224 if (quote_mark) | |
225 STORE (quote_mark); | |
226 | |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
227 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++) |
1248 | 228 { |
229 c = arg[i]; | |
230 | |
231 switch (quoting_style) | |
232 { | |
233 case literal_quoting_style: | |
234 break; | |
235 | |
236 case shell_quoting_style: | |
237 case shell_always_quoting_style: | |
238 if (c == '\'') | |
239 { | |
240 STORE ('\''); | |
241 STORE ('\\'); | |
242 STORE ('\''); | |
243 } | |
244 break; | |
245 | |
246 case c_quoting_style: | |
247 case escape_quoting_style: | |
248 switch (c) | |
249 { | |
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; | |
260 | |
261 case '"': | |
262 if (quoting_style == c_quoting_style) | |
263 goto store_escape; | |
264 break; | |
265 | |
266 default: | |
267 if (!ISGRAPH (c)) | |
268 { | |
269 STORE ('\\'); | |
270 STORE ('0' + (c >> 6)); | |
1565
56dbd84ae920
(quotearg_buffer): Use `7' as the mask, not `3'.
Jim Meyering <jim@meyering.net>
parents:
1282
diff
changeset
|
271 STORE ('0' + ((c >> 3) & 7)); |
56dbd84ae920
(quotearg_buffer): Use `7' as the mask, not `3'.
Jim Meyering <jim@meyering.net>
parents:
1282
diff
changeset
|
272 c = '0' + (c & 7); |
1248 | 273 goto store_c; |
274 } | |
275 break; | |
276 } | |
277 | |
1282 | 278 if (! (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))) |
1248 | 279 goto store_c; |
280 | |
281 store_escape: | |
282 STORE ('\\'); | |
283 } | |
284 | |
285 store_c: | |
286 STORE (c); | |
287 } | |
288 | |
289 if (quote_mark) | |
290 STORE (quote_mark); | |
291 | |
292 done: | |
1282 | 293 if (len < buffersize) |
294 buffer[len] = '\0'; | |
1248 | 295 return len; |
296 } | |
297 | |
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. */ | |
303 static char * | |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
304 quotearg_n_options (unsigned int n, char const *arg, |
1598
d0dff44eca51
(quotearg_n_options): Make `options' parameter be `const'.
Jim Meyering <jim@meyering.net>
parents:
1597
diff
changeset
|
305 struct quoting_options const *options) |
1248 | 306 { |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
307 static unsigned int nslots; |
1248 | 308 static struct slotvec |
309 { | |
310 size_t size; | |
311 char *val; | |
312 } *slotvec; | |
313 | |
314 if (nslots <= n) | |
315 { | |
1650
aa48c3374848
(quotearg_n_options): Declare n1 to be of type
Jim Meyering <jim@meyering.net>
parents:
1633
diff
changeset
|
316 unsigned int n1 = n + 1; |
1248 | 317 size_t s = n1 * sizeof (struct slotvec); |
318 if (! (0 < n1 && n1 == s / sizeof (struct slotvec))) | |
319 abort (); | |
320 slotvec = (struct slotvec *) xrealloc (slotvec, s); | |
321 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec)); | |
322 nslots = n; | |
323 } | |
324 | |
325 { | |
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); | |
329 | |
330 if (size <= qsize) | |
331 { | |
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); | |
335 } | |
336 | |
337 return val; | |
338 } | |
339 } | |
340 | |
341 char * | |
1597
287550eb5c15
(quotearg_buffer): Cast -1 to size_t before comparing.
Jim Meyering <jim@meyering.net>
parents:
1565
diff
changeset
|
342 quotearg_n (unsigned int n, char const *arg) |
1248 | 343 { |
1282 | 344 return quotearg_n_options (n, arg, &default_quoting_options); |
1248 | 345 } |
346 | |
347 char * | |
348 quotearg (char const *arg) | |
349 { | |
350 return quotearg_n (0, arg); | |
351 } | |
352 | |
353 char * | |
354 quotearg_char (char const *arg, char ch) | |
355 { | |
356 struct quoting_options options; | |
1282 | 357 options = default_quoting_options; |
1248 | 358 set_char_quoting (&options, ch, 1); |
359 return quotearg_n_options (0, arg, &options); | |
360 } | |
361 | |
362 char * | |
363 quotearg_colon (char const *arg) | |
364 { | |
365 return quotearg_char (arg, ':'); | |
366 } |