/src/mozilla-central/modules/libpref/test/gtest/Parser.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "gtest/gtest.h" |
8 | | #include "mozilla/ArrayUtils.h" |
9 | | #include "Preferences.h" |
10 | | |
11 | | using namespace mozilla; |
12 | | |
13 | | // Keep this in sync with the declaration in Preferences.cpp. |
14 | | // |
15 | | // It's declared here to avoid polluting Preferences.h with test-only stuff. |
16 | | void |
17 | | TestParseError(PrefValueKind aKind, const char* aText, nsCString& aErrorMsg); |
18 | | |
19 | | TEST(PrefsParser, Errors) |
20 | 0 | { |
21 | 0 | nsAutoCStringN<128> actualErrorMsg; |
22 | 0 |
|
23 | 0 | // Use a macro rather than a function so that the line number reported by |
24 | 0 | // gtest on failure is useful. |
25 | 0 | #define P(kind_, text_, expectedErrorMsg_) \ |
26 | 0 | do { \ |
27 | 0 | TestParseError(kind_, text_, actualErrorMsg); \ |
28 | 0 | ASSERT_STREQ(expectedErrorMsg_, actualErrorMsg.get()); \ |
29 | 0 | } while (0) |
30 | 0 |
|
31 | 0 | #define DEFAULT(text_, expectedErrorMsg_) \ |
32 | 0 | P(PrefValueKind::Default, text_, expectedErrorMsg_) |
33 | 0 |
|
34 | 0 | #define USER(text_, expectedErrorMsg_) \ |
35 | 0 | P(PrefValueKind::User, text_, expectedErrorMsg_) |
36 | 0 |
|
37 | 0 | // clang-format off |
38 | 0 |
|
39 | 0 | //------------------------------------------------------------------------- |
40 | 0 | // Valid syntax. (Other testing of more typical valid syntax and semantics is |
41 | 0 | // done in modules/libpref/test/unit/test_parser.js.) |
42 | 0 | //------------------------------------------------------------------------- |
43 | 0 |
|
44 | 0 | // Normal prefs. |
45 | 0 | DEFAULT(R"( |
46 | 0 | pref("bool", true); |
47 | 0 | sticky_pref("int", 123); |
48 | 0 | user_pref("string", "value"); |
49 | 0 | )", |
50 | 0 | "" |
51 | 0 | ); |
52 | 0 |
|
53 | 0 | // Totally empty input. |
54 | 0 | DEFAULT("", ""); |
55 | 0 |
|
56 | 0 | // Whitespace-only input. |
57 | 0 | DEFAULT(R"( |
58 | 0 |
|
59 | 0 | )" "\v \t \v \f", |
60 | 0 | "" |
61 | 0 | ); |
62 | 0 |
|
63 | 0 | // Comment-only inputs. |
64 | 0 | DEFAULT(R"(// blah)", ""); |
65 | 0 | DEFAULT(R"(# blah)", ""); |
66 | 0 | DEFAULT(R"(/* blah */)", ""); |
67 | 0 |
|
68 | 0 | //------------------------------------------------------------------------- |
69 | 0 | // All the lexing errors. (To be pedantic, some of the integer literal |
70 | 0 | // overflows are triggered in the parser, but put them all here so they're all |
71 | 0 | // in the one spot.) |
72 | 0 | //------------------------------------------------------------------------- |
73 | 0 |
|
74 | 0 | // Integer overflow errors. |
75 | 0 | DEFAULT(R"( |
76 | 0 | pref("int.ok", 2147483647); |
77 | 0 | pref("int.overflow", 2147483648); |
78 | 0 | pref("int.ok", +2147483647); |
79 | 0 | pref("int.overflow", +2147483648); |
80 | 0 | pref("int.ok", -2147483648); |
81 | 0 | pref("int.overflow", -2147483649); |
82 | 0 | pref("int.overflow", 4294967296); |
83 | 0 | pref("int.overflow", +4294967296); |
84 | 0 | pref("int.overflow", -4294967296); |
85 | 0 | pref("int.overflow", 4294967297); |
86 | 0 | pref("int.overflow", 1234567890987654321); |
87 | 0 | )", |
88 | 0 | "test:3: prefs parse error: integer literal overflowed\n" |
89 | 0 | "test:5: prefs parse error: integer literal overflowed\n" |
90 | 0 | "test:7: prefs parse error: integer literal overflowed\n" |
91 | 0 | "test:8: prefs parse error: integer literal overflowed\n" |
92 | 0 | "test:9: prefs parse error: integer literal overflowed\n" |
93 | 0 | "test:10: prefs parse error: integer literal overflowed\n" |
94 | 0 | "test:11: prefs parse error: integer literal overflowed\n" |
95 | 0 | "test:12: prefs parse error: integer literal overflowed\n" |
96 | 0 | ); |
97 | 0 |
|
98 | 0 | // Other integer errors. |
99 | 0 | DEFAULT(R"( |
100 | 0 | pref("int.unexpected", 100foo); |
101 | 0 | pref("int.ok", 0); |
102 | 0 | )", |
103 | 0 | "test:2: prefs parse error: unexpected character in integer literal\n" |
104 | 0 | ); |
105 | 0 |
|
106 | 0 | // \x00 is not allowed. |
107 | 0 | DEFAULT(R"( |
108 | 0 | pref("string.bad-x-escape", "foo\x00bar"); |
109 | 0 | pref("int.ok", 0); |
110 | 0 | )", |
111 | 0 | "test:2: prefs parse error: \\x00 is not allowed\n" |
112 | 0 | ); |
113 | 0 |
|
114 | 0 | // Various bad things after \x: end of string, punctuation, space, newline, |
115 | 0 | // EOF. |
116 | 0 | DEFAULT(R"( |
117 | 0 | pref("string.bad-x-escape", "foo\x"); |
118 | 0 | pref("string.bad-x-escape", "foo\x,bar"); |
119 | 0 | pref("string.bad-x-escape", "foo\x 12"); |
120 | 0 | pref("string.bad-x-escape", "foo\x |
121 | 0 | 12"); |
122 | 0 | pref("string.bad-x-escape", "foo\x)", |
123 | 0 | "test:2: prefs parse error: malformed \\x escape sequence\n" |
124 | 0 | "test:3: prefs parse error: malformed \\x escape sequence\n" |
125 | 0 | "test:4: prefs parse error: malformed \\x escape sequence\n" |
126 | 0 | "test:5: prefs parse error: malformed \\x escape sequence\n" |
127 | 0 | "test:7: prefs parse error: malformed \\x escape sequence\n" |
128 | 0 | ); |
129 | 0 |
|
130 | 0 | // Not enough hex digits. |
131 | 0 | DEFAULT(R"( |
132 | 0 | pref("string.bad-x-escape", "foo\x1"); |
133 | 0 | pref("int.ok", 0); |
134 | 0 | )", |
135 | 0 | "test:2: prefs parse error: malformed \\x escape sequence\n" |
136 | 0 | ); |
137 | 0 |
|
138 | 0 | // Invalid hex digit. |
139 | 0 | DEFAULT(R"( |
140 | 0 | pref("string.bad-x-escape", "foo\x1G"); |
141 | 0 | pref("int.ok", 0); |
142 | 0 | )", |
143 | 0 | "test:2: prefs parse error: malformed \\x escape sequence\n" |
144 | 0 | ); |
145 | 0 |
|
146 | 0 | // \u0000 is not allowed. |
147 | 0 | // (The string literal is broken in two so that MSVC doesn't complain about |
148 | 0 | // an invalid universal-character-name.) |
149 | 0 | DEFAULT(R"( |
150 | 0 | pref("string.bad-u-escape", "foo\)" R"(u0000 bar"); |
151 | 0 | pref("int.ok", 0); |
152 | 0 | )", |
153 | 0 | "test:2: prefs parse error: \\u0000 is not allowed\n" |
154 | 0 | ); |
155 | 0 |
|
156 | 0 | // Various bad things after \u: end of string, punctuation, space, newline, |
157 | 0 | // EOF. |
158 | 0 | DEFAULT(R"( |
159 | 0 | pref("string.bad-u-escape", "foo\u"); |
160 | 0 | pref("string.bad-u-escape", "foo\u,bar"); |
161 | 0 | pref("string.bad-u-escape", "foo\u 1234"); |
162 | 0 | pref("string.bad-u-escape", "foo\u |
163 | 0 | 1234"); |
164 | 0 | pref("string.bad-u-escape", "foo\u)", |
165 | 0 | "test:2: prefs parse error: malformed \\u escape sequence\n" |
166 | 0 | "test:3: prefs parse error: malformed \\u escape sequence\n" |
167 | 0 | "test:4: prefs parse error: malformed \\u escape sequence\n" |
168 | 0 | "test:5: prefs parse error: malformed \\u escape sequence\n" |
169 | 0 | "test:7: prefs parse error: malformed \\u escape sequence\n" |
170 | 0 | ); |
171 | 0 |
|
172 | 0 | // Not enough hex digits. |
173 | 0 | DEFAULT(R"( |
174 | 0 | pref("string.bad-u-escape", "foo\u1"); |
175 | 0 | pref("string.bad-u-escape", "foo\u12"); |
176 | 0 | pref("string.bad-u-escape", "foo\u123"); |
177 | 0 | pref("int.ok", 0); |
178 | 0 | )", |
179 | 0 | "test:2: prefs parse error: malformed \\u escape sequence\n" |
180 | 0 | "test:3: prefs parse error: malformed \\u escape sequence\n" |
181 | 0 | "test:4: prefs parse error: malformed \\u escape sequence\n" |
182 | 0 | ); |
183 | 0 |
|
184 | 0 | // Invalid hex digit. |
185 | 0 | DEFAULT(R"( |
186 | 0 | pref("string.bad-u-escape", "foo\u1G34"); |
187 | 0 | pref("int.ok", 0); |
188 | 0 | )", |
189 | 0 | "test:2: prefs parse error: malformed \\u escape sequence\n" |
190 | 0 | ); |
191 | 0 |
|
192 | 0 | // High surrogate not followed by low surrogate. |
193 | 0 | // (The string literal is broken in two so that MSVC doesn't complain about |
194 | 0 | // an invalid universal-character-name.) |
195 | 0 | DEFAULT(R"( |
196 | 0 | pref("string.bad-u-surrogate", "foo\)" R"(ud83c,blah"); |
197 | 0 | pref("int.ok", 0); |
198 | 0 | )", |
199 | 0 | "test:2: prefs parse error: expected low surrogate after high surrogate\n" |
200 | 0 | ); |
201 | 0 |
|
202 | 0 | // High surrogate followed by invalid low surrogate. |
203 | 0 | // (The string literal is broken in two so that MSVC doesn't complain about |
204 | 0 | // an invalid universal-character-name.) |
205 | 0 | DEFAULT(R"( |
206 | 0 | pref("string.bad-u-surrogate", "foo\)" R"(ud83c\u1234"); |
207 | 0 | pref("int.ok", 0); |
208 | 0 | )", |
209 | 0 | "test:2: prefs parse error: invalid low surrogate after high surrogate\n" |
210 | 0 | ); |
211 | 0 |
|
212 | 0 | // Low surrogate not preceded by high surrogate. |
213 | 0 | // (The string literal is broken in two so that MSVC doesn't complain about |
214 | 0 | // an invalid universal-character-name.) |
215 | 0 | DEFAULT(R"( |
216 | 0 | pref("string.bad-u-surrogate", "foo\)" R"(udc00"); |
217 | 0 | pref("int.ok", 0); |
218 | 0 | )", |
219 | 0 | "test:2: prefs parse error: expected high surrogate before low surrogate\n" |
220 | 0 | ); |
221 | 0 |
|
222 | 0 | // Unlike in JavaScript, \b, \f, \t, \v aren't allowed. |
223 | 0 | DEFAULT(R"( |
224 | 0 | pref("string.bad-escape", "foo\b"); |
225 | 0 | pref("string.bad-escape", "foo\f"); |
226 | 0 | pref("string.bad-escape", "foo\t"); |
227 | 0 | pref("string.bad-escape", "foo\v"); |
228 | 0 | pref("int.ok", 0); |
229 | 0 | )", |
230 | 0 | "test:2: prefs parse error: unexpected escape sequence character after '\\'\n" |
231 | 0 | "test:3: prefs parse error: unexpected escape sequence character after '\\'\n" |
232 | 0 | "test:4: prefs parse error: unexpected escape sequence character after '\\'\n" |
233 | 0 | "test:5: prefs parse error: unexpected escape sequence character after '\\'\n" |
234 | 0 | ); |
235 | 0 |
|
236 | 0 | // Various bad things after \: non-special letter, number, punctuation, |
237 | 0 | // space, newline, EOF. |
238 | 0 | DEFAULT(R"( |
239 | 0 | pref("string.bad-escape", "foo\Q"); |
240 | 0 | pref("string.bad-escape", "foo\1"); |
241 | 0 | pref("string.bad-escape", "foo\,"); |
242 | 0 | pref("string.bad-escape", "foo\ n"); |
243 | 0 | pref("string.bad-escape", "foo\ |
244 | 0 | n"); |
245 | 0 | pref("string.bad-escape", "foo\)", |
246 | 0 | "test:2: prefs parse error: unexpected escape sequence character after '\\'\n" |
247 | 0 | "test:3: prefs parse error: unexpected escape sequence character after '\\'\n" |
248 | 0 | "test:4: prefs parse error: unexpected escape sequence character after '\\'\n" |
249 | 0 | "test:5: prefs parse error: unexpected escape sequence character after '\\'\n" |
250 | 0 | "test:6: prefs parse error: unexpected escape sequence character after '\\'\n" |
251 | 0 | "test:8: prefs parse error: unexpected escape sequence character after '\\'\n" |
252 | 0 | ); |
253 | 0 |
|
254 | 0 | // Unterminated string literals. |
255 | 0 |
|
256 | 0 | // Simple case. |
257 | 0 | DEFAULT(R"( |
258 | 0 | pref("string.unterminated-string", "foo |
259 | 0 | )", |
260 | 0 | "test:3: prefs parse error: unterminated string literal\n" |
261 | 0 | ); |
262 | 0 |
|
263 | 0 | // Alternative case; `int` comes after the string and is seen as a keyword. |
264 | 0 | // The parser then skips to the ';', so no error about the unterminated |
265 | 0 | // string is issued. |
266 | 0 | DEFAULT(R"( |
267 | 0 | pref("string.unterminated-string", "foo); |
268 | 0 | pref("int.ok", 0); |
269 | 0 | )", |
270 | 0 | "test:3: prefs parse error: unknown keyword\n" |
271 | 0 | ); |
272 | 0 |
|
273 | 0 | // Mismatched quotes (1). |
274 | 0 | DEFAULT(R"( |
275 | 0 | pref("string.unterminated-string", "foo'); |
276 | 0 | )", |
277 | 0 | "test:3: prefs parse error: unterminated string literal\n" |
278 | 0 | ); |
279 | 0 |
|
280 | 0 | // Mismatched quotes (2). |
281 | 0 | DEFAULT(R"( |
282 | 0 | pref("string.unterminated-string", 'foo"); |
283 | 0 | )", |
284 | 0 | "test:3: prefs parse error: unterminated string literal\n" |
285 | 0 | ); |
286 | 0 |
|
287 | 0 | // Unknown keywords. |
288 | 0 | DEFAULT(R"( |
289 | 0 | foo; |
290 | 0 | preff("string.bad-keyword", true); |
291 | 0 | ticky_pref("string.bad-keyword", true); |
292 | 0 | User_pref("string.bad-keyword", true); |
293 | 0 | pref("string.bad-keyword", TRUE); |
294 | 0 | )", |
295 | 0 | "test:2: prefs parse error: unknown keyword\n" |
296 | 0 | "test:3: prefs parse error: unknown keyword\n" |
297 | 0 | "test:4: prefs parse error: unknown keyword\n" |
298 | 0 | "test:5: prefs parse error: unknown keyword\n" |
299 | 0 | "test:6: prefs parse error: unknown keyword\n" |
300 | 0 | ); |
301 | 0 |
|
302 | 0 | // Unterminated C-style comment. |
303 | 0 | DEFAULT(R"( |
304 | 0 | /* comment |
305 | 0 | )", |
306 | 0 | "test:3: prefs parse error: unterminated /* comment\n" |
307 | 0 | ); |
308 | 0 |
|
309 | 0 | // Malformed comments (single slashes), followed by whitespace, newline, EOF. |
310 | 0 | DEFAULT(R"( |
311 | 0 | / comment; |
312 | 0 | / |
313 | 0 | ; /)", |
314 | 0 | "test:2: prefs parse error: expected '/' or '*' after '/'\n" |
315 | 0 | "test:3: prefs parse error: expected '/' or '*' after '/'\n" |
316 | 0 | "test:4: prefs parse error: expected '/' or '*' after '/'\n" |
317 | 0 | ); |
318 | 0 |
|
319 | 0 | // C++-style comment ending in EOF (1). |
320 | 0 | DEFAULT(R"( |
321 | 0 | // comment)", |
322 | 0 | "" |
323 | 0 | ); |
324 | 0 |
|
325 | 0 | // C++-style comment ending in EOF (2). |
326 | 0 | DEFAULT(R"( |
327 | 0 | //)", |
328 | 0 | "" |
329 | 0 | ); |
330 | 0 |
|
331 | 0 | // Various unexpected characters. |
332 | 0 | DEFAULT(R"( |
333 | 0 | pref("unexpected.chars", &true); |
334 | 0 | pref("unexpected.chars" : true); |
335 | 0 | @pref("unexpected.chars", true); |
336 | 0 | pref["unexpected.chars": true]; |
337 | 0 | )", |
338 | 0 | "test:2: prefs parse error: unexpected character\n" |
339 | 0 | "test:3: prefs parse error: unexpected character\n" |
340 | 0 | "test:4: prefs parse error: unexpected character\n" |
341 | 0 | "test:5: prefs parse error: unexpected character\n" |
342 | 0 | ); |
343 | 0 |
|
344 | 0 | //------------------------------------------------------------------------- |
345 | 0 | // All the parsing errors. |
346 | 0 | //------------------------------------------------------------------------- |
347 | 0 |
|
348 | 0 | DEFAULT(R"( |
349 | 0 | "pref"("parse.error": true); |
350 | 0 | pref1("parse.error": true); |
351 | 0 | pref(123: true); |
352 | 0 | pref("parse.error" true); |
353 | 0 | pref("parse.error", pref); |
354 | 0 | pref("parse.error", -true); |
355 | 0 | pref("parse.error", +"value"); |
356 | 0 | pref("parse.error", true,); |
357 | 0 | pref("parse.error", true; |
358 | 0 | pref("parse.error", true, sticky, locked; |
359 | 0 | pref("parse.error", true) |
360 | 0 | pref("int.ok", 1); |
361 | 0 | pref("parse.error", true))", |
362 | 0 | "test:2: prefs parse error: expected pref specifier at start of pref definition\n" |
363 | 0 | "test:3: prefs parse error: expected '(' after pref specifier\n" |
364 | 0 | "test:4: prefs parse error: expected pref name after '('\n" |
365 | 0 | "test:5: prefs parse error: expected ',' after pref name\n" |
366 | 0 | "test:6: prefs parse error: expected pref value after ','\n" |
367 | 0 | "test:7: prefs parse error: expected integer literal after '-'\n" |
368 | 0 | "test:8: prefs parse error: expected integer literal after '+'\n" |
369 | 0 | "test:9: prefs parse error: expected pref attribute after ','\n" |
370 | 0 | "test:10: prefs parse error: expected ',' or ')' after pref value\n" |
371 | 0 | "test:11: prefs parse error: expected ',' or ')' after pref attribute\n" |
372 | 0 | "test:13: prefs parse error: expected ';' after ')'\n" |
373 | 0 | "test:14: prefs parse error: expected ';' after ')'\n" |
374 | 0 | ); |
375 | 0 |
|
376 | 0 | USER(R"( |
377 | 0 | pref("parse.error", true; |
378 | 0 | pref("int.ok", 1); |
379 | 0 | )", |
380 | 0 | "test:2: prefs parse error: expected ')' after pref value\n" |
381 | 0 | ); |
382 | 0 |
|
383 | 0 | // Parse errors involving unexpected EOF. |
384 | 0 |
|
385 | 0 | DEFAULT(R"( |
386 | 0 | pref)", |
387 | 0 | "test:2: prefs parse error: expected '(' after pref specifier\n" |
388 | 0 | ); |
389 | 0 |
|
390 | 0 | DEFAULT(R"( |
391 | 0 | pref()", |
392 | 0 | "test:2: prefs parse error: expected pref name after '('\n" |
393 | 0 | ); |
394 | 0 |
|
395 | 0 | DEFAULT(R"( |
396 | 0 | pref("parse.error")", |
397 | 0 | "test:2: prefs parse error: expected ',' after pref name\n" |
398 | 0 | ); |
399 | 0 |
|
400 | 0 | DEFAULT(R"( |
401 | 0 | pref("parse.error",)", |
402 | 0 | "test:2: prefs parse error: expected pref value after ','\n" |
403 | 0 | ); |
404 | 0 |
|
405 | 0 | DEFAULT(R"( |
406 | 0 | pref("parse.error", -)", |
407 | 0 | "test:2: prefs parse error: expected integer literal after '-'\n" |
408 | 0 | ); |
409 | 0 |
|
410 | 0 | DEFAULT(R"( |
411 | 0 | pref("parse.error", +)", |
412 | 0 | "test:2: prefs parse error: expected integer literal after '+'\n" |
413 | 0 | ); |
414 | 0 |
|
415 | 0 | DEFAULT(R"( |
416 | 0 | pref("parse.error", true)", |
417 | 0 | "test:2: prefs parse error: expected ',' or ')' after pref value\n" |
418 | 0 | ); |
419 | 0 |
|
420 | 0 | USER(R"( |
421 | 0 | pref("parse.error", true)", |
422 | 0 | "test:2: prefs parse error: expected ')' after pref value\n" |
423 | 0 | ); |
424 | 0 |
|
425 | 0 | DEFAULT(R"( |
426 | 0 | pref("parse.error", true,)", |
427 | 0 | "test:2: prefs parse error: expected pref attribute after ','\n" |
428 | 0 | ); |
429 | 0 |
|
430 | 0 | DEFAULT(R"( |
431 | 0 | pref("parse.error", true, sticky)", |
432 | 0 | "test:2: prefs parse error: expected ',' or ')' after pref attribute\n" |
433 | 0 | ); |
434 | 0 |
|
435 | 0 | DEFAULT(R"( |
436 | 0 | pref("parse.error", true))", |
437 | 0 | "test:2: prefs parse error: expected ';' after ')'\n" |
438 | 0 | ); |
439 | 0 |
|
440 | 0 | // This is something we saw in practice with the old parser, which allowed |
441 | 0 | // repeated semicolons. |
442 | 0 | DEFAULT(R"( |
443 | 0 | pref("parse.error", true);; |
444 | 0 | pref("parse.error", true, locked);;; |
445 | 0 | pref("parse.error", true, sticky, locked);;;; |
446 | 0 | pref("int.ok", 0); |
447 | 0 | )", |
448 | 0 | "test:2: prefs parse error: expected pref specifier at start of pref definition\n" |
449 | 0 | "test:3: prefs parse error: expected pref specifier at start of pref definition\n" |
450 | 0 | "test:3: prefs parse error: expected pref specifier at start of pref definition\n" |
451 | 0 | "test:4: prefs parse error: expected pref specifier at start of pref definition\n" |
452 | 0 | "test:4: prefs parse error: expected pref specifier at start of pref definition\n" |
453 | 0 | "test:4: prefs parse error: expected pref specifier at start of pref definition\n" |
454 | 0 | ); |
455 | 0 |
|
456 | 0 | //------------------------------------------------------------------------- |
457 | 0 | // Invalid syntax after various newline combinations, for the purpose of |
458 | 0 | // testing that line numbers are correct. |
459 | 0 | //------------------------------------------------------------------------- |
460 | 0 |
|
461 | 0 | // In all of the following we have a \n, a \r, a \r\n, and then an error, so |
462 | 0 | // the error is on line 4. (Note: these ones don't use raw string literals |
463 | 0 | // because MSVC somehow swallows any \r that appears in them.) |
464 | 0 |
|
465 | 0 | DEFAULT("\n \r \r\n bad", |
466 | 0 | "test:4: prefs parse error: unknown keyword\n" |
467 | 0 | ); |
468 | 0 |
|
469 | 0 | DEFAULT("#\n#\r#\r\n bad", |
470 | 0 | "test:4: prefs parse error: unknown keyword\n" |
471 | 0 | ); |
472 | 0 |
|
473 | 0 | DEFAULT("//\n//\r//\r\n bad", |
474 | 0 | "test:4: prefs parse error: unknown keyword\n" |
475 | 0 | ); |
476 | 0 |
|
477 | 0 | DEFAULT("/*\n \r \r\n*/ bad", |
478 | 0 | "test:4: prefs parse error: unknown keyword\n" |
479 | 0 | ); |
480 | 0 |
|
481 | 0 | // Note: the escape sequences do *not* affect the line number. |
482 | 0 | DEFAULT("pref(\"foo\\n\n foo\\r\r foo\\r\\n\r\n foo\", bad);", |
483 | 0 | "test:4: prefs parse error: unknown keyword\n" |
484 | 0 | ); |
485 | 0 |
|
486 | 0 | // clang-format on |
487 | 0 | } |