1 /* Test of quotearg family of functions.
2 Copyright (C) 2008-2012 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 3, 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, see <http://www.gnu.org/licenses/>. */
17 /* Written by Eric Blake <ebb9@byu.net>, 2008. */
29 #include "localcharset.h"
33 #include "test-quotearg.h"
35 static struct result_groups results_g[] = {
36 /* literal_quoting_style */
37 { { "", "\0""1\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
39 { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
41 { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
44 /* shell_quoting_style */
45 { { "''", "\0""1\0", 3, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
46 "'a\\b'", LQ RQ, LQ RQ },
47 { "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
48 "'a\\b'", LQ RQ, LQ RQ },
49 { "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
50 "'a\\b'", LQ RQ, LQ RQ } },
52 /* shell_always_quoting_style */
53 { { "''", "'\0""1\0'", 5, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
54 "'a\\b'", "'" LQ RQ "'", "'" LQ RQ "'" },
55 { "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
56 "'a\\b'", "'" LQ RQ "'", "'" LQ RQ "'" },
57 { "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
58 "'a\\b'", "'" LQ RQ "'", "'" LQ RQ "'" } },
61 { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
62 "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
63 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
64 { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
65 "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
66 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
67 { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
68 "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
69 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } },
71 /* c_maybe_quoting_style */
72 { { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
73 "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
74 { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
75 "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
76 { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
77 "\"a:b\"", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
79 /* escape_quoting_style */
80 { { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
81 "a\\\\b", LQ_ENC RQ_ENC, LQ RQ },
82 { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
83 "a\\\\b", LQ_ENC RQ_ENC, LQ RQ },
84 { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a\\:b",
85 "a\\\\b", LQ_ENC RQ_ENC, LQ RQ } },
87 /* locale_quoting_style */
88 { { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
89 "'a:b'", "'a\\\\b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
90 { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
91 "'a:b'", "'a\\\\b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
92 { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
93 "'a\\:b'", "'a\\\\b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" } },
95 /* clocale_quoting_style */
96 { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
97 "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
98 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
99 { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
100 "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
101 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
102 { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
103 "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
104 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } }
107 static struct result_groups flag_results[] = {
108 /* literal_quoting_style and QA_ELIDE_NULL_BYTES */
109 { { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ,
111 { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ,
113 { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ,
116 /* c_quoting_style and QA_ELIDE_OUTER_QUOTES */
117 { { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
118 "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
119 { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
120 "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
121 { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
122 "\"a:b\"", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
124 /* c_quoting_style and QA_SPLIT_TRIGRAPHS */
125 { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
126 "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
127 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
128 { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
129 "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
130 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
131 { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
132 "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
133 "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } }
136 static char const *custom_quotes[][2] = {
146 static struct result_groups custom_results[] = {
147 /* left_quote = right_quote = "" */
148 { { "", "\\0001\\0", 7, "simple",
149 " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
150 LQ_ENC RQ_ENC, LQ RQ },
151 { "", "\\0001\\0", 7, "simple",
152 " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
153 LQ_ENC RQ_ENC, LQ RQ },
154 { "", "\\0001\\0", 7, "simple",
155 " \\t\\n'\"\\033?""?/\\\\", "a\\:b", "a\\\\b",
156 LQ_ENC RQ_ENC, LQ RQ } },
158 /* left_quote = right_quote = "'" */
159 { { "''", "'\\0001\\0'", 9, "'simple'",
160 "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
161 "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
162 { "''", "'\\0001\\0'", 9, "'simple'",
163 "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
164 "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
165 { "''", "'\\0001\\0'", 9, "'simple'",
166 "' \\t\\n\\'\"\\033?""?/\\\\'", "'a\\:b'", "'a\\\\b'",
167 "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" } },
169 /* left_quote = "(" and right_quote = ")" */
170 { { "()", "(\\0001\\0)", 9, "(simple)",
171 "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
172 "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" },
173 { "()", "(\\0001\\0)", 9, "(simple)",
174 "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
175 "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" },
176 { "()", "(\\0001\\0)", 9, "(simple)",
177 "( \\t\\n'\"\\033?""?/\\\\)", "(a\\:b)", "(a\\\\b)",
178 "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" } },
180 /* left_quote = ":" and right_quote = " " */
181 { { ": ", ":\\0001\\0 ", 9, ":simple ",
182 ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
183 ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " },
184 { ": ", ":\\0001\\0 ", 9, ":simple ",
185 ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
186 ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " },
187 { ": ", ":\\0001\\0 ", 9, ":simple ",
188 ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a\\:b ", ":a\\\\b ",
189 ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " } },
191 /* left_quote = " " and right_quote = ":" */
192 { { " :", " \\0001\\0:", 9, " simple:",
193 " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
194 " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" },
195 { " :", " \\0001\\0:", 9, " simple:",
196 " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
197 " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" },
198 { " :", " \\0001\\0:", 9, " simple:",
199 " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
200 " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" } },
202 /* left_quote = "# " and right_quote = "\n" */
203 { { "# \n", "# \\0001\\0\n", 10, "# simple\n",
204 "# \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
205 "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" },
206 { "# \n", "# \\0001\\0\n", 10, "# simple\n",
207 "# \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
208 "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" },
209 { "# \n", "# \\0001\\0\n", 10, "# simple\n",
210 "# \\t\\n'\"\\033?""?/\\\\\n", "# a\\:b\n", "# a\\\\b\n",
211 "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" } },
213 /* left_quote = "\"'" and right_quote = "'\"" */
214 { { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
215 "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
216 "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" },
217 { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
218 "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
219 "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" },
220 { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
221 "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a\\:b'\"", "\"'a\\\\b'\"",
222 "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" } }
226 main (int argc _GL_UNUSED, char *argv[])
229 bool ascii_only = MB_CUR_MAX == 1 && !isprint ((unsigned char) LQ[0]);
231 set_program_name (argv[0]);
233 /* This part of the program is hard-wired to the C locale since it
234 does not call setlocale. However, according to POSIX, the use of
235 8-bit bytes in a character context in the C locale gives
236 unspecified results (that is, the C locale charset is allowed to
237 be unibyte with 8-bit bytes rejected [ASCII], unibyte with 8-bit
238 bytes being characters [often ISO-8859-1], or multibyte [often
239 UTF-8]). We assume that the latter two cases will be
240 indistinguishable in this test - that is, the LQ and RQ sequences
241 will pass through unchanged in either type of charset. So when
242 testing for quoting of str7, use the ascii_only flag to decide
243 what to expect for the 8-bit data being quoted. */
244 ASSERT (!isprint ('\033'));
245 for (i = literal_quoting_style; i <= clocale_quoting_style; i++)
247 set_quoting_style (NULL, (enum quoting_style) i);
248 if (!(i == locale_quoting_style || i == clocale_quoting_style)
249 || (strcmp (locale_charset (), "ASCII") == 0
250 || strcmp (locale_charset (), "ANSI_X3.4-1968") == 0))
252 compare_strings (use_quotearg_buffer, &results_g[i].group1,
254 compare_strings (use_quotearg, &results_g[i].group2,
256 if (i == c_quoting_style)
257 compare_strings (use_quote_double_quotes, &results_g[i].group2,
259 compare_strings (use_quotearg_colon, &results_g[i].group3,
264 set_quoting_style (NULL, literal_quoting_style);
265 ASSERT (set_quoting_flags (NULL, QA_ELIDE_NULL_BYTES) == 0);
266 compare_strings (use_quotearg_buffer, &flag_results[0].group1, ascii_only);
267 compare_strings (use_quotearg, &flag_results[0].group2, ascii_only);
268 compare_strings (use_quotearg_colon, &flag_results[0].group3, ascii_only);
270 set_quoting_style (NULL, c_quoting_style);
271 ASSERT (set_quoting_flags (NULL, QA_ELIDE_OUTER_QUOTES)
272 == QA_ELIDE_NULL_BYTES);
273 compare_strings (use_quotearg_buffer, &flag_results[1].group1, ascii_only);
274 compare_strings (use_quotearg, &flag_results[1].group2, ascii_only);
275 compare_strings (use_quote_double_quotes, &flag_results[1].group2,
277 compare_strings (use_quotearg_colon, &flag_results[1].group3, ascii_only);
279 ASSERT (set_quoting_flags (NULL, QA_SPLIT_TRIGRAPHS)
280 == QA_ELIDE_OUTER_QUOTES);
281 compare_strings (use_quotearg_buffer, &flag_results[2].group1, ascii_only);
282 compare_strings (use_quotearg, &flag_results[2].group2, ascii_only);
283 compare_strings (use_quote_double_quotes, &flag_results[2].group2,
285 compare_strings (use_quotearg_colon, &flag_results[2].group3, ascii_only);
287 ASSERT (set_quoting_flags (NULL, 0) == QA_SPLIT_TRIGRAPHS);
289 for (i = 0; i < sizeof custom_quotes / sizeof *custom_quotes; ++i)
291 set_custom_quoting (NULL,
292 custom_quotes[i][0], custom_quotes[i][1]);
293 compare_strings (use_quotearg_buffer, &custom_results[i].group1,
295 compare_strings (use_quotearg, &custom_results[i].group2, ascii_only);
296 compare_strings (use_quotearg_colon, &custom_results[i].group3,