xref: /netbsd-src/external/bsd/openpam/dist/t/t_openpam_readword.c (revision 0d9d0fd8a30be9a1924e715bbcf67a4a83efd262)
123e44a77Schristos /*-
2*4cb4af11Schristos  * Copyright (c) 2012-2017 Dag-Erling Smørgrav
323e44a77Schristos  * All rights reserved.
423e44a77Schristos  *
523e44a77Schristos  * Redistribution and use in source and binary forms, with or without
623e44a77Schristos  * modification, are permitted provided that the following conditions
723e44a77Schristos  * are met:
823e44a77Schristos  * 1. Redistributions of source code must retain the above copyright
90bbc3b9fSchristos  *    notice, this list of conditions and the following disclaimer.
1023e44a77Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1123e44a77Schristos  *    notice, this list of conditions and the following disclaimer in the
1223e44a77Schristos  *    documentation and/or other materials provided with the distribution.
1323e44a77Schristos  * 3. The name of the author may not be used to endorse or promote
1423e44a77Schristos  *    products derived from this software without specific prior written
1523e44a77Schristos  *    permission.
1623e44a77Schristos  *
1723e44a77Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1823e44a77Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1923e44a77Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2023e44a77Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2123e44a77Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2223e44a77Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2323e44a77Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2423e44a77Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2523e44a77Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2623e44a77Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2723e44a77Schristos  * SUCH DAMAGE.
2823e44a77Schristos  */
2923e44a77Schristos 
3023e44a77Schristos #ifdef HAVE_CONFIG_H
3123e44a77Schristos # include "config.h"
3223e44a77Schristos #endif
3323e44a77Schristos 
3423e44a77Schristos #include <err.h>
35*4cb4af11Schristos #include <stdint.h>
3623e44a77Schristos #include <stdio.h>
3723e44a77Schristos #include <stdlib.h>
3823e44a77Schristos #include <string.h>
3923e44a77Schristos #include <unistd.h>
4023e44a77Schristos 
41*4cb4af11Schristos #include <cryb/test.h>
42*4cb4af11Schristos 
4323e44a77Schristos #include <security/pam_appl.h>
4423e44a77Schristos #include <security/openpam.h>
4523e44a77Schristos 
46*4cb4af11Schristos #define T_FUNC(n, d)							\
47*4cb4af11Schristos 	static const char *t_ ## n ## _desc = d;			\
48*4cb4af11Schristos 	static int t_ ## n ## _func(OPENPAM_UNUSED(char **desc),	\
49*4cb4af11Schristos 	    OPENPAM_UNUSED(void *arg))
50*4cb4af11Schristos 
51*4cb4af11Schristos #define T(n)								\
52*4cb4af11Schristos 	t_add_test(&t_ ## n ## _func, NULL, "%s", t_ ## n ## _desc)
5323e44a77Schristos 
5423e44a77Schristos /*
5523e44a77Schristos  * Read a word from the temp file and verify that the result matches our
5623e44a77Schristos  * expectations: whether a word was read at all, how many lines were read
5723e44a77Schristos  * (in case of quoted or escaped newlines), whether we reached the end of
5823e44a77Schristos  * the file and whether we reached the end of the line.
5923e44a77Schristos  */
6023e44a77Schristos static int
orw_expect(struct t_file * tf,const char * expected,int lines,int eof,int eol)610bbc3b9fSchristos orw_expect(struct t_file *tf, const char *expected, int lines, int eof, int eol)
6223e44a77Schristos {
6323e44a77Schristos 	int ch, lineno = 0;
6423e44a77Schristos 	char *got;
6523e44a77Schristos 	size_t len;
66*4cb4af11Schristos 	int ret;
6723e44a77Schristos 
680bbc3b9fSchristos 	got = openpam_readword(tf->file, &lineno, &len);
69*4cb4af11Schristos 	ret = 1;
700bbc3b9fSchristos 	if (t_ferror(tf))
710bbc3b9fSchristos 		err(1, "%s(): %s", __func__, tf->name);
7223e44a77Schristos 	if (expected != NULL && got == NULL) {
73*4cb4af11Schristos 		t_printv("expected <<%s>>, got nothing\n", expected);
74*4cb4af11Schristos 		ret = 0;
75*4cb4af11Schristos 	} else if (expected == NULL && got != NULL) {
76*4cb4af11Schristos 		t_printv("expected nothing, got <<%s>>\n", got);
77*4cb4af11Schristos 		ret = 0;
78*4cb4af11Schristos 	} else if (expected != NULL && got != NULL && strcmp(expected, got) != 0) {
79*4cb4af11Schristos 		t_printv("expected <<%s>>, got <<%s>>\n", expected, got);
80*4cb4af11Schristos 		ret = 0;
8123e44a77Schristos 	}
82*4cb4af11Schristos 	free(got);
8323e44a77Schristos 	if (lineno != lines) {
84*4cb4af11Schristos 		t_printv("expected to advance %d lines, advanced %d lines\n",
8523e44a77Schristos 		    lines, lineno);
86*4cb4af11Schristos 		ret = 0;
8723e44a77Schristos 	}
880bbc3b9fSchristos 	if (eof && !t_feof(tf)) {
89*4cb4af11Schristos 		t_printv("expected EOF, but didn't get it\n");
90*4cb4af11Schristos 		ret = 0;
9123e44a77Schristos 	}
920bbc3b9fSchristos 	if (!eof && t_feof(tf)) {
93*4cb4af11Schristos 		t_printv("didn't expect EOF, but got it anyway\n");
94*4cb4af11Schristos 		ret = 0;
9523e44a77Schristos 	}
960bbc3b9fSchristos 	ch = fgetc(tf->file);
970bbc3b9fSchristos 	if (t_ferror(tf))
980bbc3b9fSchristos 		err(1, "%s(): %s", __func__, tf->name);
9923e44a77Schristos 	if (eol && ch != '\n') {
100*4cb4af11Schristos 		t_printv("expected EOL, but didn't get it\n");
101*4cb4af11Schristos 		ret = 0;
102*4cb4af11Schristos 	} else if (!eol && ch == '\n') {
103*4cb4af11Schristos 		t_printv("didn't expect EOL, but got it anyway\n");
104*4cb4af11Schristos 		ret = 0;
10523e44a77Schristos 	}
10623e44a77Schristos 	if (ch != EOF)
1070bbc3b9fSchristos 		ungetc(ch, tf->file);
108*4cb4af11Schristos 	return (ret);
10923e44a77Schristos }
11023e44a77Schristos 
11123e44a77Schristos 
11223e44a77Schristos /***************************************************************************
11323e44a77Schristos  * Lines without words
11423e44a77Schristos  */
11523e44a77Schristos 
11623e44a77Schristos T_FUNC(empty_input, "empty input")
11723e44a77Schristos {
1180bbc3b9fSchristos 	struct t_file *tf;
11923e44a77Schristos 	int ret;
12023e44a77Schristos 
1210bbc3b9fSchristos 	tf = t_fopen(NULL);
1220bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
1230bbc3b9fSchristos 	t_fclose(tf);
12423e44a77Schristos 	return (ret);
12523e44a77Schristos }
12623e44a77Schristos 
12723e44a77Schristos T_FUNC(empty_line, "empty line")
12823e44a77Schristos {
1290bbc3b9fSchristos 	struct t_file *tf;
13023e44a77Schristos 	int ret;
13123e44a77Schristos 
1320bbc3b9fSchristos 	tf = t_fopen(NULL);
1330bbc3b9fSchristos 	t_fprintf(tf, "\n");
1340bbc3b9fSchristos 	t_frewind(tf);
1350bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
1360bbc3b9fSchristos 	t_fclose(tf);
13723e44a77Schristos 	return (ret);
13823e44a77Schristos }
13923e44a77Schristos 
14023e44a77Schristos T_FUNC(unterminated_line, "unterminated line")
14123e44a77Schristos {
1420bbc3b9fSchristos 	struct t_file *tf;
14323e44a77Schristos 	int ret;
14423e44a77Schristos 
1450bbc3b9fSchristos 	tf = t_fopen(NULL);
1460bbc3b9fSchristos 	t_fprintf(tf, " ");
1470bbc3b9fSchristos 	t_frewind(tf);
1480bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
1490bbc3b9fSchristos 	t_fclose(tf);
15023e44a77Schristos 	return (ret);
15123e44a77Schristos }
15223e44a77Schristos 
15323e44a77Schristos T_FUNC(single_whitespace, "single whitespace")
15423e44a77Schristos {
1550bbc3b9fSchristos 	struct t_file *tf;
15623e44a77Schristos 	int ret;
15723e44a77Schristos 
1580bbc3b9fSchristos 	tf = t_fopen(NULL);
1590bbc3b9fSchristos 	t_fprintf(tf, " \n");
1600bbc3b9fSchristos 	t_frewind(tf);
1610bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
1620bbc3b9fSchristos 	t_fclose(tf);
16323e44a77Schristos 	return (ret);
16423e44a77Schristos }
16523e44a77Schristos 
16623e44a77Schristos T_FUNC(multiple_whitespace, "multiple whitespace")
16723e44a77Schristos {
1680bbc3b9fSchristos 	struct t_file *tf;
16923e44a77Schristos 	int ret;
17023e44a77Schristos 
1710bbc3b9fSchristos 	tf = t_fopen(NULL);
1720bbc3b9fSchristos 	t_fprintf(tf, " \t\r\n");
1730bbc3b9fSchristos 	t_frewind(tf);
1740bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
1750bbc3b9fSchristos 	t_fclose(tf);
17623e44a77Schristos 	return (ret);
17723e44a77Schristos }
17823e44a77Schristos 
179201780c4Schristos T_FUNC(line_continuation_in_whitespace, "line continuation in whitespace")
180201780c4Schristos {
181201780c4Schristos 	struct t_file *tf;
182201780c4Schristos 	int ret;
183201780c4Schristos 
184201780c4Schristos 	tf = t_fopen(NULL);
185201780c4Schristos 	t_fprintf(tf, " \\\n \n");
186201780c4Schristos 	t_frewind(tf);
187201780c4Schristos 	ret = orw_expect(tf, NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
188201780c4Schristos 	t_fclose(tf);
189201780c4Schristos 	return (ret);
190201780c4Schristos }
191201780c4Schristos 
19223e44a77Schristos T_FUNC(comment, "comment")
19323e44a77Schristos {
1940bbc3b9fSchristos 	struct t_file *tf;
19523e44a77Schristos 	int ret;
19623e44a77Schristos 
1970bbc3b9fSchristos 	tf = t_fopen(NULL);
1980bbc3b9fSchristos 	t_fprintf(tf, "# comment\n");
1990bbc3b9fSchristos 	t_frewind(tf);
2000bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
2010bbc3b9fSchristos 	t_fclose(tf);
20223e44a77Schristos 	return (ret);
20323e44a77Schristos }
20423e44a77Schristos 
20523e44a77Schristos T_FUNC(whitespace_before_comment, "whitespace before comment")
20623e44a77Schristos {
2070bbc3b9fSchristos 	struct t_file *tf;
20823e44a77Schristos 	int ret;
20923e44a77Schristos 
2100bbc3b9fSchristos 	tf = t_fopen(NULL);
2110bbc3b9fSchristos 	t_fprintf(tf, " # comment\n");
2120bbc3b9fSchristos 	t_frewind(tf);
2130bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
2140bbc3b9fSchristos 	t_fclose(tf);
21523e44a77Schristos 	return (ret);
21623e44a77Schristos }
21723e44a77Schristos 
218201780c4Schristos T_FUNC(single_quoted_comment, "single-quoted comment")
219201780c4Schristos {
220201780c4Schristos 	struct t_file *tf;
221201780c4Schristos 	int ret;
222201780c4Schristos 
223201780c4Schristos 	tf = t_fopen(NULL);
224201780c4Schristos 	t_fprintf(tf, " '# comment'\n");
225201780c4Schristos 	t_frewind(tf);
226201780c4Schristos 	ret = orw_expect(tf, "# comment", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
227201780c4Schristos 	t_fclose(tf);
228201780c4Schristos 	return (ret);
229201780c4Schristos }
230201780c4Schristos 
231201780c4Schristos T_FUNC(double_quoted_comment, "double-quoted comment")
232201780c4Schristos {
233201780c4Schristos 	struct t_file *tf;
234201780c4Schristos 	int ret;
235201780c4Schristos 
236201780c4Schristos 	tf = t_fopen(NULL);
237201780c4Schristos 	t_fprintf(tf, " \"# comment\"\n");
238201780c4Schristos 	t_frewind(tf);
239201780c4Schristos 	ret = orw_expect(tf, "# comment", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
240201780c4Schristos 	t_fclose(tf);
241201780c4Schristos 	return (ret);
242201780c4Schristos }
243201780c4Schristos 
244201780c4Schristos T_FUNC(comment_at_eof, "comment at end of file")
245201780c4Schristos {
246201780c4Schristos 	struct t_file *tf;
247201780c4Schristos 	int ret;
248201780c4Schristos 
249201780c4Schristos 	tf = t_fopen(NULL);
250201780c4Schristos 	t_fprintf(tf, "# comment");
251201780c4Schristos 	t_frewind(tf);
252201780c4Schristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
253201780c4Schristos 	t_fclose(tf);
254201780c4Schristos 	return (ret);
255201780c4Schristos }
256201780c4Schristos 
25723e44a77Schristos 
25823e44a77Schristos /***************************************************************************
25923e44a77Schristos  * Simple cases - no quotes or escapes
26023e44a77Schristos  */
26123e44a77Schristos 
26223e44a77Schristos T_FUNC(single_word, "single word")
26323e44a77Schristos {
26423e44a77Schristos 	const char *word = "hello";
2650bbc3b9fSchristos 	struct t_file *tf;
26623e44a77Schristos 	int ret;
26723e44a77Schristos 
2680bbc3b9fSchristos 	tf = t_fopen(NULL);
2690bbc3b9fSchristos 	t_fprintf(tf, "%s\n", word);
2700bbc3b9fSchristos 	t_frewind(tf);
2710bbc3b9fSchristos 	ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
2720bbc3b9fSchristos 	t_fclose(tf);
27323e44a77Schristos 	return (ret);
27423e44a77Schristos }
27523e44a77Schristos 
27623e44a77Schristos T_FUNC(single_whitespace_before_word, "single whitespace before word")
27723e44a77Schristos {
27823e44a77Schristos 	const char *word = "hello";
2790bbc3b9fSchristos 	struct t_file *tf;
28023e44a77Schristos 	int ret;
28123e44a77Schristos 
2820bbc3b9fSchristos 	tf = t_fopen(NULL);
2830bbc3b9fSchristos 	t_fprintf(tf, " %s\n", word);
2840bbc3b9fSchristos 	t_frewind(tf);
2850bbc3b9fSchristos 	ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
2860bbc3b9fSchristos 	t_fclose(tf);
28723e44a77Schristos 	return (ret);
28823e44a77Schristos }
28923e44a77Schristos 
29023e44a77Schristos T_FUNC(double_whitespace_before_word, "double whitespace before word")
29123e44a77Schristos {
29223e44a77Schristos 	const char *word = "hello";
2930bbc3b9fSchristos 	struct t_file *tf;
29423e44a77Schristos 	int ret;
29523e44a77Schristos 
2960bbc3b9fSchristos 	tf = t_fopen(NULL);
2970bbc3b9fSchristos 	t_fprintf(tf, "  %s\n", word);
2980bbc3b9fSchristos 	t_frewind(tf);
2990bbc3b9fSchristos 	ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
3000bbc3b9fSchristos 	t_fclose(tf);
30123e44a77Schristos 	return (ret);
30223e44a77Schristos }
30323e44a77Schristos 
30423e44a77Schristos T_FUNC(single_whitespace_after_word, "single whitespace after word")
30523e44a77Schristos {
30623e44a77Schristos 	const char *word = "hello";
3070bbc3b9fSchristos 	struct t_file *tf;
30823e44a77Schristos 	int ret;
30923e44a77Schristos 
3100bbc3b9fSchristos 	tf = t_fopen(NULL);
3110bbc3b9fSchristos 	t_fprintf(tf, "%s \n", word);
3120bbc3b9fSchristos 	t_frewind(tf);
3130bbc3b9fSchristos 	ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
3140bbc3b9fSchristos 	t_fclose(tf);
31523e44a77Schristos 	return (ret);
31623e44a77Schristos }
31723e44a77Schristos 
31823e44a77Schristos T_FUNC(double_whitespace_after_word, "double whitespace after word")
31923e44a77Schristos {
32023e44a77Schristos 	const char *word = "hello";
3210bbc3b9fSchristos 	struct t_file *tf;
32223e44a77Schristos 	int ret;
32323e44a77Schristos 
3240bbc3b9fSchristos 	tf = t_fopen(NULL);
3250bbc3b9fSchristos 	t_fprintf(tf, "%s  \n", word);
3260bbc3b9fSchristos 	t_frewind(tf);
3270bbc3b9fSchristos 	ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
3280bbc3b9fSchristos 	t_fclose(tf);
32923e44a77Schristos 	return (ret);
33023e44a77Schristos }
33123e44a77Schristos 
33223e44a77Schristos T_FUNC(comment_after_word, "comment after word")
33323e44a77Schristos {
33423e44a77Schristos 	const char *word = "hello";
3350bbc3b9fSchristos 	struct t_file *tf;
33623e44a77Schristos 	int ret;
33723e44a77Schristos 
3380bbc3b9fSchristos 	tf = t_fopen(NULL);
3390bbc3b9fSchristos 	t_fprintf(tf, "%s # comment\n", word);
3400bbc3b9fSchristos 	t_frewind(tf);
3410bbc3b9fSchristos 	ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
3420bbc3b9fSchristos 	    orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
3430bbc3b9fSchristos 	t_fclose(tf);
34423e44a77Schristos 	return (ret);
34523e44a77Schristos }
34623e44a77Schristos 
34723e44a77Schristos T_FUNC(word_containing_hash, "word containing hash")
34823e44a77Schristos {
34923e44a77Schristos 	const char *word = "hello#world";
3500bbc3b9fSchristos 	struct t_file *tf;
35123e44a77Schristos 	int ret;
35223e44a77Schristos 
3530bbc3b9fSchristos 	tf = t_fopen(NULL);
3540bbc3b9fSchristos 	t_fprintf(tf, "%s\n", word);
3550bbc3b9fSchristos 	t_frewind(tf);
3560bbc3b9fSchristos 	ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
3570bbc3b9fSchristos 	t_fclose(tf);
35823e44a77Schristos 	return (ret);
35923e44a77Schristos }
36023e44a77Schristos 
36123e44a77Schristos T_FUNC(two_words, "two words")
36223e44a77Schristos {
36323e44a77Schristos 	const char *word[] = { "hello", "world" };
3640bbc3b9fSchristos 	struct t_file *tf;
36523e44a77Schristos 	int ret;
36623e44a77Schristos 
3670bbc3b9fSchristos 	tf = t_fopen(NULL);
3680bbc3b9fSchristos 	t_fprintf(tf, "%s %s\n", word[0], word[1]);
3690bbc3b9fSchristos 	t_frewind(tf);
3700bbc3b9fSchristos 	ret = orw_expect(tf, word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
3710bbc3b9fSchristos 	    orw_expect(tf, word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
3720bbc3b9fSchristos 	t_fclose(tf);
37323e44a77Schristos 	return (ret);
37423e44a77Schristos }
37523e44a77Schristos 
37623e44a77Schristos 
37723e44a77Schristos /***************************************************************************
37823e44a77Schristos  * Escapes
37923e44a77Schristos  */
38023e44a77Schristos 
38123e44a77Schristos T_FUNC(naked_escape, "naked escape")
38223e44a77Schristos {
3830bbc3b9fSchristos 	struct t_file *tf;
38423e44a77Schristos 	int ret;
38523e44a77Schristos 
3860bbc3b9fSchristos 	tf = t_fopen(NULL);
3870bbc3b9fSchristos 	t_fprintf(tf, "\\");
3880bbc3b9fSchristos 	t_frewind(tf);
3890bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
3900bbc3b9fSchristos 	t_fclose(tf);
39123e44a77Schristos 	return (ret);
39223e44a77Schristos }
39323e44a77Schristos 
39423e44a77Schristos T_FUNC(escaped_escape, "escaped escape")
39523e44a77Schristos {
3960bbc3b9fSchristos 	struct t_file *tf;
39723e44a77Schristos 	int ret;
39823e44a77Schristos 
3990bbc3b9fSchristos 	tf = t_fopen(NULL);
4000bbc3b9fSchristos 	t_fprintf(tf, "\\\\\n");
4010bbc3b9fSchristos 	t_frewind(tf);
4020bbc3b9fSchristos 	ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
4030bbc3b9fSchristos 	t_fclose(tf);
40423e44a77Schristos 	return (ret);
40523e44a77Schristos }
40623e44a77Schristos 
40723e44a77Schristos T_FUNC(escaped_whitespace, "escaped whitespace")
40823e44a77Schristos {
4090bbc3b9fSchristos 	struct t_file *tf;
41023e44a77Schristos 	int ret;
41123e44a77Schristos 
4120bbc3b9fSchristos 	tf = t_fopen(NULL);
4130bbc3b9fSchristos 	t_fprintf(tf, "\\  \\\t \\\r \\\n\n");
4140bbc3b9fSchristos 	t_frewind(tf);
4150bbc3b9fSchristos 	ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
4160bbc3b9fSchristos 	    orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
4170bbc3b9fSchristos 	    orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
41823e44a77Schristos 	    /* this last one is a line continuation */
4190bbc3b9fSchristos 	    orw_expect(tf, NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
4200bbc3b9fSchristos 	t_fclose(tf);
42123e44a77Schristos 	return (ret);
42223e44a77Schristos }
42323e44a77Schristos 
42423e44a77Schristos T_FUNC(escaped_newline_before_word, "escaped newline before word")
42523e44a77Schristos {
4260bbc3b9fSchristos 	struct t_file *tf;
42723e44a77Schristos 	int ret;
42823e44a77Schristos 
4290bbc3b9fSchristos 	tf = t_fopen(NULL);
4300bbc3b9fSchristos 	t_fprintf(tf, "\\\nhello world\n");
4310bbc3b9fSchristos 	t_frewind(tf);
4320bbc3b9fSchristos 	ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
4330bbc3b9fSchristos 	t_fclose(tf);
43423e44a77Schristos 	return (ret);
43523e44a77Schristos }
43623e44a77Schristos 
43723e44a77Schristos T_FUNC(escaped_newline_within_word, "escaped newline within word")
43823e44a77Schristos {
4390bbc3b9fSchristos 	struct t_file *tf;
44023e44a77Schristos 	int ret;
44123e44a77Schristos 
4420bbc3b9fSchristos 	tf = t_fopen(NULL);
4430bbc3b9fSchristos 	t_fprintf(tf, "hello\\\nworld\n");
4440bbc3b9fSchristos 	t_frewind(tf);
4450bbc3b9fSchristos 	ret = orw_expect(tf, "helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
4460bbc3b9fSchristos 	t_fclose(tf);
44723e44a77Schristos 	return (ret);
44823e44a77Schristos }
44923e44a77Schristos 
45023e44a77Schristos T_FUNC(escaped_newline_after_word, "escaped newline after word")
45123e44a77Schristos {
4520bbc3b9fSchristos 	struct t_file *tf;
45323e44a77Schristos 	int ret;
45423e44a77Schristos 
4550bbc3b9fSchristos 	tf = t_fopen(NULL);
4560bbc3b9fSchristos 	t_fprintf(tf, "hello\\\n world\n");
4570bbc3b9fSchristos 	t_frewind(tf);
4580bbc3b9fSchristos 	ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
4590bbc3b9fSchristos 	t_fclose(tf);
46023e44a77Schristos 	return (ret);
46123e44a77Schristos }
46223e44a77Schristos 
46323e44a77Schristos T_FUNC(escaped_letter, "escaped letter")
46423e44a77Schristos {
4650bbc3b9fSchristos 	struct t_file *tf;
46623e44a77Schristos 	int ret;
46723e44a77Schristos 
4680bbc3b9fSchristos 	tf = t_fopen(NULL);
4690bbc3b9fSchristos 	t_fprintf(tf, "\\z\n");
4700bbc3b9fSchristos 	t_frewind(tf);
4710bbc3b9fSchristos 	ret = orw_expect(tf, "z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
4720bbc3b9fSchristos 	t_fclose(tf);
47323e44a77Schristos 	return (ret);
47423e44a77Schristos }
47523e44a77Schristos 
476*4cb4af11Schristos T_FUNC(escaped_comment, "escaped comment")
477*4cb4af11Schristos {
478*4cb4af11Schristos 	struct t_file *tf;
479*4cb4af11Schristos 	int ret;
480*4cb4af11Schristos 
481*4cb4af11Schristos 	tf = t_fopen(NULL);
482*4cb4af11Schristos 	t_fprintf(tf, " \\# comment\n");
483*4cb4af11Schristos 	t_frewind(tf);
484*4cb4af11Schristos 	ret = orw_expect(tf, "#", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
485*4cb4af11Schristos 	    orw_expect(tf, "comment", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
486*4cb4af11Schristos 	t_fclose(tf);
487*4cb4af11Schristos 	return (ret);
488*4cb4af11Schristos }
489*4cb4af11Schristos 
490*4cb4af11Schristos T_FUNC(escape_at_eof, "escape at end of file")
491*4cb4af11Schristos {
492*4cb4af11Schristos 	struct t_file *tf;
493*4cb4af11Schristos 	int ret;
494*4cb4af11Schristos 
495*4cb4af11Schristos 	tf = t_fopen(NULL);
496*4cb4af11Schristos 	t_fprintf(tf, "z\\");
497*4cb4af11Schristos 	t_frewind(tf);
498*4cb4af11Schristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
499*4cb4af11Schristos 	t_fclose(tf);
500*4cb4af11Schristos 	return (ret);
501*4cb4af11Schristos }
502*4cb4af11Schristos 
50323e44a77Schristos 
50423e44a77Schristos /***************************************************************************
505201780c4Schristos T_FUNC(escaped_comment, "escaped comment")
506201780c4Schristos {
507201780c4Schristos 	struct t_file *tf;
508201780c4Schristos 	int ret;
509201780c4Schristos 
510201780c4Schristos 	tf = t_fopen(NULL);
511201780c4Schristos 	t_fprintf(tf, " \\# comment\n");
512201780c4Schristos 	t_frewind(tf);
513201780c4Schristos 	ret = orw_expect(tf, "#", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
514201780c4Schristos 	    orw_expect(tf, "comment", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
515201780c4Schristos 	t_fclose(tf);
516201780c4Schristos 	return (ret);
517201780c4Schristos }
518201780c4Schristos 
519201780c4Schristos T_FUNC(escape_at_eof, "escape at end of file")
520201780c4Schristos {
521201780c4Schristos 	struct t_file *tf;
522201780c4Schristos 	int ret;
523201780c4Schristos 
524201780c4Schristos 	tf = t_fopen(NULL);
525201780c4Schristos 	t_fprintf(tf, "z\\");
526201780c4Schristos 	t_frewind(tf);
527201780c4Schristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
528201780c4Schristos 	t_fclose(tf);
529201780c4Schristos 	return (ret);
530201780c4Schristos }
531201780c4Schristos 
53223e44a77Schristos  * Quotes
53323e44a77Schristos  */
53423e44a77Schristos 
53523e44a77Schristos T_FUNC(naked_single_quote, "naked single quote")
53623e44a77Schristos {
5370bbc3b9fSchristos 	struct t_file *tf;
53823e44a77Schristos 	int ret;
53923e44a77Schristos 
5400bbc3b9fSchristos 	tf = t_fopen(NULL);
5410bbc3b9fSchristos 	t_fprintf(tf, "'");
5420bbc3b9fSchristos 	t_frewind(tf);
5430bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
5440bbc3b9fSchristos 	t_fclose(tf);
54523e44a77Schristos 	return (ret);
54623e44a77Schristos }
54723e44a77Schristos 
54823e44a77Schristos T_FUNC(naked_double_quote, "naked double quote")
54923e44a77Schristos {
5500bbc3b9fSchristos 	struct t_file *tf;
55123e44a77Schristos 	int ret;
55223e44a77Schristos 
5530bbc3b9fSchristos 	tf = t_fopen(NULL);
5540bbc3b9fSchristos 	t_fprintf(tf, "\"");
5550bbc3b9fSchristos 	t_frewind(tf);
5560bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
5570bbc3b9fSchristos 	t_fclose(tf);
55823e44a77Schristos 	return (ret);
55923e44a77Schristos }
56023e44a77Schristos 
56123e44a77Schristos T_FUNC(empty_single_quotes, "empty single quotes")
56223e44a77Schristos {
5630bbc3b9fSchristos 	struct t_file *tf;
56423e44a77Schristos 	int ret;
56523e44a77Schristos 
5660bbc3b9fSchristos 	tf = t_fopen(NULL);
5670bbc3b9fSchristos 	t_fprintf(tf, "''\n");
5680bbc3b9fSchristos 	t_frewind(tf);
5690bbc3b9fSchristos 	ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
5700bbc3b9fSchristos 	t_fclose(tf);
57123e44a77Schristos 	return (ret);
57223e44a77Schristos }
57323e44a77Schristos 
57423e44a77Schristos T_FUNC(empty_double_quotes, "empty double quotes")
57523e44a77Schristos {
5760bbc3b9fSchristos 	struct t_file *tf;
57723e44a77Schristos 	int ret;
57823e44a77Schristos 
5790bbc3b9fSchristos 	tf = t_fopen(NULL);
5800bbc3b9fSchristos 	t_fprintf(tf, "\"\"\n");
5810bbc3b9fSchristos 	t_frewind(tf);
5820bbc3b9fSchristos 	ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
5830bbc3b9fSchristos 	t_fclose(tf);
58423e44a77Schristos 	return (ret);
58523e44a77Schristos }
58623e44a77Schristos 
58723e44a77Schristos T_FUNC(single_quotes_within_double_quotes, "single quotes within double quotes")
58823e44a77Schristos {
5890bbc3b9fSchristos 	struct t_file *tf;
59023e44a77Schristos 	int ret;
59123e44a77Schristos 
5920bbc3b9fSchristos 	tf = t_fopen(NULL);
5930bbc3b9fSchristos 	t_fprintf(tf, "\"' '\"\n");
5940bbc3b9fSchristos 	t_frewind(tf);
5950bbc3b9fSchristos 	ret = orw_expect(tf, "' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
5960bbc3b9fSchristos 	t_fclose(tf);
59723e44a77Schristos 	return (ret);
59823e44a77Schristos }
59923e44a77Schristos 
60023e44a77Schristos T_FUNC(double_quotes_within_single_quotes, "double quotes within single quotes")
60123e44a77Schristos {
6020bbc3b9fSchristos 	struct t_file *tf;
60323e44a77Schristos 	int ret;
60423e44a77Schristos 
6050bbc3b9fSchristos 	tf = t_fopen(NULL);
6060bbc3b9fSchristos 	t_fprintf(tf, "'\" \"'\n");
6070bbc3b9fSchristos 	t_frewind(tf);
6080bbc3b9fSchristos 	ret = orw_expect(tf, "\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
6090bbc3b9fSchristos 	t_fclose(tf);
61023e44a77Schristos 	return (ret);
61123e44a77Schristos }
61223e44a77Schristos 
61323e44a77Schristos T_FUNC(single_quoted_whitespace, "single-quoted whitespace")
61423e44a77Schristos {
6150bbc3b9fSchristos 	struct t_file *tf;
61623e44a77Schristos 	int ret;
61723e44a77Schristos 
6180bbc3b9fSchristos 	tf = t_fopen(NULL);
6190bbc3b9fSchristos 	t_fprintf(tf, "' ' '\t' '\r' '\n'\n");
6200bbc3b9fSchristos 	t_frewind(tf);
6210bbc3b9fSchristos 	ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
6220bbc3b9fSchristos 	    orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
6230bbc3b9fSchristos 	    orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
6240bbc3b9fSchristos 	    orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
6250bbc3b9fSchristos 	t_fclose(tf);
62623e44a77Schristos 	return (ret);
62723e44a77Schristos }
62823e44a77Schristos 
62923e44a77Schristos T_FUNC(double_quoted_whitespace, "double-quoted whitespace")
63023e44a77Schristos {
6310bbc3b9fSchristos 	struct t_file *tf;
63223e44a77Schristos 	int ret;
63323e44a77Schristos 
6340bbc3b9fSchristos 	tf = t_fopen(NULL);
6350bbc3b9fSchristos 	t_fprintf(tf, "\" \" \"\t\" \"\r\" \"\n\"\n");
6360bbc3b9fSchristos 	t_frewind(tf);
6370bbc3b9fSchristos 	ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
6380bbc3b9fSchristos 	    orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
6390bbc3b9fSchristos 	    orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
6400bbc3b9fSchristos 	    orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
6410bbc3b9fSchristos 	t_fclose(tf);
64223e44a77Schristos 	return (ret);
64323e44a77Schristos }
64423e44a77Schristos 
64523e44a77Schristos T_FUNC(single_quoted_words, "single-quoted words")
64623e44a77Schristos {
6470bbc3b9fSchristos 	struct t_file *tf;
64823e44a77Schristos 	int ret;
64923e44a77Schristos 
6500bbc3b9fSchristos 	tf = t_fopen(NULL);
6510bbc3b9fSchristos 	t_fprintf(tf, "'hello world'\n");
6520bbc3b9fSchristos 	t_frewind(tf);
6530bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
6540bbc3b9fSchristos 	t_fclose(tf);
65523e44a77Schristos 	return (ret);
65623e44a77Schristos }
65723e44a77Schristos 
65823e44a77Schristos T_FUNC(double_quoted_words, "double-quoted words")
65923e44a77Schristos {
6600bbc3b9fSchristos 	struct t_file *tf;
66123e44a77Schristos 	int ret;
66223e44a77Schristos 
6630bbc3b9fSchristos 	tf = t_fopen(NULL);
6640bbc3b9fSchristos 	t_fprintf(tf, "\"hello world\"\n");
6650bbc3b9fSchristos 	t_frewind(tf);
6660bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
6670bbc3b9fSchristos 	t_fclose(tf);
6680bbc3b9fSchristos 	return (ret);
6690bbc3b9fSchristos }
6700bbc3b9fSchristos 
6710bbc3b9fSchristos 
6720bbc3b9fSchristos /***************************************************************************
6730bbc3b9fSchristos  * Combinations of quoted and unquoted text
6740bbc3b9fSchristos  */
6750bbc3b9fSchristos 
6760bbc3b9fSchristos T_FUNC(single_quote_before_word, "single quote before word")
6770bbc3b9fSchristos {
6780bbc3b9fSchristos 	struct t_file *tf;
6790bbc3b9fSchristos 	int ret;
6800bbc3b9fSchristos 
6810bbc3b9fSchristos 	tf = t_fopen(NULL);
6820bbc3b9fSchristos 	t_fprintf(tf, "'hello 'world\n");
6830bbc3b9fSchristos 	t_frewind(tf);
6840bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
6850bbc3b9fSchristos 	t_fclose(tf);
6860bbc3b9fSchristos 	return (ret);
6870bbc3b9fSchristos }
6880bbc3b9fSchristos 
6890bbc3b9fSchristos T_FUNC(double_quote_before_word, "double quote before word")
6900bbc3b9fSchristos {
6910bbc3b9fSchristos 	struct t_file *tf;
6920bbc3b9fSchristos 	int ret;
6930bbc3b9fSchristos 
6940bbc3b9fSchristos 	tf = t_fopen(NULL);
6950bbc3b9fSchristos 	t_fprintf(tf, "\"hello \"world\n");
6960bbc3b9fSchristos 	t_frewind(tf);
6970bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
6980bbc3b9fSchristos 	t_fclose(tf);
6990bbc3b9fSchristos 	return (ret);
7000bbc3b9fSchristos }
7010bbc3b9fSchristos 
7020bbc3b9fSchristos T_FUNC(single_quote_within_word, "single quote within word")
7030bbc3b9fSchristos {
7040bbc3b9fSchristos 	struct t_file *tf;
7050bbc3b9fSchristos 	int ret;
7060bbc3b9fSchristos 
7070bbc3b9fSchristos 	tf = t_fopen(NULL);
7080bbc3b9fSchristos 	t_fprintf(tf, "hello' 'world\n");
7090bbc3b9fSchristos 	t_frewind(tf);
7100bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
7110bbc3b9fSchristos 	t_fclose(tf);
7120bbc3b9fSchristos 	return (ret);
7130bbc3b9fSchristos }
7140bbc3b9fSchristos 
7150bbc3b9fSchristos T_FUNC(double_quote_within_word, "double quote within word")
7160bbc3b9fSchristos {
7170bbc3b9fSchristos 	struct t_file *tf;
7180bbc3b9fSchristos 	int ret;
7190bbc3b9fSchristos 
7200bbc3b9fSchristos 	tf = t_fopen(NULL);
7210bbc3b9fSchristos 	t_fprintf(tf, "hello\" \"world\n");
7220bbc3b9fSchristos 	t_frewind(tf);
7230bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
7240bbc3b9fSchristos 	t_fclose(tf);
7250bbc3b9fSchristos 	return (ret);
7260bbc3b9fSchristos }
7270bbc3b9fSchristos 
7280bbc3b9fSchristos T_FUNC(single_quote_after_word, "single quote after word")
7290bbc3b9fSchristos {
7300bbc3b9fSchristos 	struct t_file *tf;
7310bbc3b9fSchristos 	int ret;
7320bbc3b9fSchristos 
7330bbc3b9fSchristos 	tf = t_fopen(NULL);
7340bbc3b9fSchristos 	t_fprintf(tf, "hello' world'\n");
7350bbc3b9fSchristos 	t_frewind(tf);
7360bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
7370bbc3b9fSchristos 	t_fclose(tf);
7380bbc3b9fSchristos 	return (ret);
7390bbc3b9fSchristos }
7400bbc3b9fSchristos 
7410bbc3b9fSchristos T_FUNC(double_quote_after_word, "double quote after word")
7420bbc3b9fSchristos {
7430bbc3b9fSchristos 	struct t_file *tf;
7440bbc3b9fSchristos 	int ret;
7450bbc3b9fSchristos 
7460bbc3b9fSchristos 	tf = t_fopen(NULL);
7470bbc3b9fSchristos 	t_fprintf(tf, "hello\" world\"\n");
7480bbc3b9fSchristos 	t_frewind(tf);
7490bbc3b9fSchristos 	ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
7500bbc3b9fSchristos 	t_fclose(tf);
75123e44a77Schristos 	return (ret);
75223e44a77Schristos }
75323e44a77Schristos 
75423e44a77Schristos 
75523e44a77Schristos /***************************************************************************
75623e44a77Schristos  * Combinations of escape and quotes
75723e44a77Schristos  */
75823e44a77Schristos 
75923e44a77Schristos T_FUNC(escaped_single_quote,
76023e44a77Schristos     "escaped single quote")
76123e44a77Schristos {
7620bbc3b9fSchristos 	struct t_file *tf;
76323e44a77Schristos 	int ret;
76423e44a77Schristos 
7650bbc3b9fSchristos 	tf = t_fopen(NULL);
7660bbc3b9fSchristos 	t_fprintf(tf, "\\'\n");
7670bbc3b9fSchristos 	t_frewind(tf);
7680bbc3b9fSchristos 	ret = orw_expect(tf, "'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
7690bbc3b9fSchristos 	t_fclose(tf);
77023e44a77Schristos 	return (ret);
77123e44a77Schristos }
77223e44a77Schristos 
77323e44a77Schristos T_FUNC(escaped_double_quote,
77423e44a77Schristos     "escaped double quote")
77523e44a77Schristos {
7760bbc3b9fSchristos 	struct t_file *tf;
77723e44a77Schristos 	int ret;
77823e44a77Schristos 
7790bbc3b9fSchristos 	tf = t_fopen(NULL);
7800bbc3b9fSchristos 	t_fprintf(tf, "\\\"\n");
7810bbc3b9fSchristos 	t_frewind(tf);
7820bbc3b9fSchristos 	ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
7830bbc3b9fSchristos 	t_fclose(tf);
78423e44a77Schristos 	return (ret);
78523e44a77Schristos }
78623e44a77Schristos 
78723e44a77Schristos T_FUNC(escaped_whitespace_within_single_quotes,
78823e44a77Schristos     "escaped whitespace within single quotes")
78923e44a77Schristos {
7900bbc3b9fSchristos 	struct t_file *tf;
79123e44a77Schristos 	int ret;
79223e44a77Schristos 
7930bbc3b9fSchristos 	tf = t_fopen(NULL);
7940bbc3b9fSchristos 	t_fprintf(tf, "'\\ ' '\\\t' '\\\r' '\\\n'\n");
7950bbc3b9fSchristos 	t_frewind(tf);
7960bbc3b9fSchristos 	ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
7970bbc3b9fSchristos 	    orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
7980bbc3b9fSchristos 	    orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
7990bbc3b9fSchristos 	    orw_expect(tf, "\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
8000bbc3b9fSchristos 	t_fclose(tf);
80123e44a77Schristos 	return (ret);
80223e44a77Schristos }
80323e44a77Schristos 
80423e44a77Schristos T_FUNC(escaped_whitespace_within_double_quotes,
80523e44a77Schristos     "escaped whitespace within double quotes")
80623e44a77Schristos {
8070bbc3b9fSchristos 	struct t_file *tf;
80823e44a77Schristos 	int ret;
80923e44a77Schristos 
8100bbc3b9fSchristos 	tf = t_fopen(NULL);
8110bbc3b9fSchristos 	t_fprintf(tf, "\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n");
8120bbc3b9fSchristos 	t_frewind(tf);
8130bbc3b9fSchristos 	ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
8140bbc3b9fSchristos 	    orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
8150bbc3b9fSchristos 	    orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
81623e44a77Schristos 	    /* this last one is a line continuation */
8170bbc3b9fSchristos 	    orw_expect(tf, "", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
8180bbc3b9fSchristos 	t_fclose(tf);
81923e44a77Schristos 	return (ret);
82023e44a77Schristos }
82123e44a77Schristos 
82223e44a77Schristos T_FUNC(escaped_letter_within_single_quotes,
82323e44a77Schristos     "escaped letter within single quotes")
82423e44a77Schristos {
8250bbc3b9fSchristos 	struct t_file *tf;
82623e44a77Schristos 	int ret;
82723e44a77Schristos 
8280bbc3b9fSchristos 	tf = t_fopen(NULL);
8290bbc3b9fSchristos 	t_fprintf(tf, "'\\z'\n");
8300bbc3b9fSchristos 	t_frewind(tf);
8310bbc3b9fSchristos 	ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
8320bbc3b9fSchristos 	t_fclose(tf);
83323e44a77Schristos 	return (ret);
83423e44a77Schristos }
83523e44a77Schristos 
83623e44a77Schristos T_FUNC(escaped_letter_within_double_quotes,
83723e44a77Schristos     "escaped letter within double quotes")
83823e44a77Schristos {
8390bbc3b9fSchristos 	struct t_file *tf;
84023e44a77Schristos 	int ret;
84123e44a77Schristos 
8420bbc3b9fSchristos 	tf = t_fopen(NULL);
8430bbc3b9fSchristos 	t_fprintf(tf, "\"\\z\"\n");
8440bbc3b9fSchristos 	t_frewind(tf);
8450bbc3b9fSchristos 	ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
8460bbc3b9fSchristos 	t_fclose(tf);
84723e44a77Schristos 	return (ret);
84823e44a77Schristos }
84923e44a77Schristos 
85023e44a77Schristos T_FUNC(escaped_escape_within_single_quotes,
85123e44a77Schristos     "escaped escape within single quotes")
85223e44a77Schristos {
8530bbc3b9fSchristos 	struct t_file *tf;
85423e44a77Schristos 	int ret;
85523e44a77Schristos 
8560bbc3b9fSchristos 	tf = t_fopen(NULL);
8570bbc3b9fSchristos 	t_fprintf(tf, "'\\\\'\n");
8580bbc3b9fSchristos 	t_frewind(tf);
8590bbc3b9fSchristos 	ret = orw_expect(tf, "\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
8600bbc3b9fSchristos 	t_fclose(tf);
86123e44a77Schristos 	return (ret);
86223e44a77Schristos }
86323e44a77Schristos 
86423e44a77Schristos T_FUNC(escaped_escape_within_double_quotes,
86523e44a77Schristos     "escaped escape within double quotes")
86623e44a77Schristos {
8670bbc3b9fSchristos 	struct t_file *tf;
86823e44a77Schristos 	int ret;
86923e44a77Schristos 
8700bbc3b9fSchristos 	tf = t_fopen(NULL);
8710bbc3b9fSchristos 	t_fprintf(tf, "\"\\\\\"\n");
8720bbc3b9fSchristos 	t_frewind(tf);
8730bbc3b9fSchristos 	ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
8740bbc3b9fSchristos 	t_fclose(tf);
87523e44a77Schristos 	return (ret);
87623e44a77Schristos }
87723e44a77Schristos 
87823e44a77Schristos T_FUNC(escaped_single_quote_within_single_quotes,
87923e44a77Schristos     "escaped single quote within single quotes")
88023e44a77Schristos {
8810bbc3b9fSchristos 	struct t_file *tf;
88223e44a77Schristos 	int ret;
88323e44a77Schristos 
8840bbc3b9fSchristos 	tf = t_fopen(NULL);
8850bbc3b9fSchristos 	t_fprintf(tf, "'\\''\n");
8860bbc3b9fSchristos 	t_frewind(tf);
8870bbc3b9fSchristos 	ret = orw_expect(tf, NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/);
8880bbc3b9fSchristos 	t_fclose(tf);
88923e44a77Schristos 	return (ret);
89023e44a77Schristos }
89123e44a77Schristos 
89223e44a77Schristos T_FUNC(escaped_double_quote_within_single_quotes,
89323e44a77Schristos     "escaped double quote within single quotes")
89423e44a77Schristos {
8950bbc3b9fSchristos 	struct t_file *tf;
89623e44a77Schristos 	int ret;
89723e44a77Schristos 
8980bbc3b9fSchristos 	tf = t_fopen(NULL);
8990bbc3b9fSchristos 	t_fprintf(tf, "'\\\"'\n");
9000bbc3b9fSchristos 	t_frewind(tf);
9010bbc3b9fSchristos 	ret = orw_expect(tf, "\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
9020bbc3b9fSchristos 	t_fclose(tf);
90323e44a77Schristos 	return (ret);
90423e44a77Schristos }
90523e44a77Schristos 
90623e44a77Schristos T_FUNC(escaped_single_quote_within_double_quotes,
90723e44a77Schristos     "escaped single quote within double quotes")
90823e44a77Schristos {
9090bbc3b9fSchristos 	struct t_file *tf;
91023e44a77Schristos 	int ret;
91123e44a77Schristos 
9120bbc3b9fSchristos 	tf = t_fopen(NULL);
9130bbc3b9fSchristos 	t_fprintf(tf, "\"\\'\"\n");
9140bbc3b9fSchristos 	t_frewind(tf);
9150bbc3b9fSchristos 	ret = orw_expect(tf, "\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
9160bbc3b9fSchristos 	t_fclose(tf);
91723e44a77Schristos 	return (ret);
91823e44a77Schristos }
91923e44a77Schristos 
92023e44a77Schristos T_FUNC(escaped_double_quote_within_double_quotes,
92123e44a77Schristos     "escaped double quote within double quotes")
92223e44a77Schristos {
9230bbc3b9fSchristos 	struct t_file *tf;
92423e44a77Schristos 	int ret;
92523e44a77Schristos 
9260bbc3b9fSchristos 	tf = t_fopen(NULL);
9270bbc3b9fSchristos 	t_fprintf(tf, "\"\\\"\"\n");
9280bbc3b9fSchristos 	t_frewind(tf);
9290bbc3b9fSchristos 	ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
9300bbc3b9fSchristos 	t_fclose(tf);
93123e44a77Schristos 	return (ret);
93223e44a77Schristos }
93323e44a77Schristos 
93423e44a77Schristos 
93523e44a77Schristos /***************************************************************************
936*4cb4af11Schristos  * Line continuation
937*4cb4af11Schristos  */
938*4cb4af11Schristos 
939*4cb4af11Schristos T_FUNC(line_continuation_within_whitespace, "line continuation within whitespace")
940*4cb4af11Schristos {
941*4cb4af11Schristos 	struct t_file *tf;
942*4cb4af11Schristos 	int ret;
943*4cb4af11Schristos 
944*4cb4af11Schristos 	tf = t_fopen(NULL);
945*4cb4af11Schristos 	t_fprintf(tf, "hello \\\n world\n");
946*4cb4af11Schristos 	t_frewind(tf);
947*4cb4af11Schristos 	ret = orw_expect(tf, "hello", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
948*4cb4af11Schristos 	    orw_expect(tf, "world", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
949*4cb4af11Schristos 	t_fclose(tf);
950*4cb4af11Schristos 	return (ret);
951*4cb4af11Schristos }
952*4cb4af11Schristos 
953*4cb4af11Schristos T_FUNC(line_continuation_before_whitespace, "line continuation before whitespace")
954*4cb4af11Schristos {
955*4cb4af11Schristos 	struct t_file *tf;
956*4cb4af11Schristos 	int ret;
957*4cb4af11Schristos 
958*4cb4af11Schristos 	tf = t_fopen(NULL);
959*4cb4af11Schristos 	t_fprintf(tf, "hello\\\n world\n");
960*4cb4af11Schristos 	t_frewind(tf);
961*4cb4af11Schristos 	ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
962*4cb4af11Schristos 	    orw_expect(tf, "world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
963*4cb4af11Schristos 	t_fclose(tf);
964*4cb4af11Schristos 	return (ret);
965*4cb4af11Schristos }
966*4cb4af11Schristos 
967*4cb4af11Schristos T_FUNC(line_continuation_after_whitespace, "line continuation after whitespace")
968*4cb4af11Schristos {
969*4cb4af11Schristos 	struct t_file *tf;
970*4cb4af11Schristos 	int ret;
971*4cb4af11Schristos 
972*4cb4af11Schristos 	tf = t_fopen(NULL);
973*4cb4af11Schristos 	t_fprintf(tf, "hello \\\nworld\n");
974*4cb4af11Schristos 	t_frewind(tf);
975*4cb4af11Schristos 	ret = orw_expect(tf, "hello", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
976*4cb4af11Schristos 	    orw_expect(tf, "world", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
977*4cb4af11Schristos 	t_fclose(tf);
978*4cb4af11Schristos 	return (ret);
979*4cb4af11Schristos }
980*4cb4af11Schristos 
981*4cb4af11Schristos T_FUNC(line_continuation_within_word, "line continuation within word")
982*4cb4af11Schristos {
983*4cb4af11Schristos 	struct t_file *tf;
984*4cb4af11Schristos 	int ret;
985*4cb4af11Schristos 
986*4cb4af11Schristos 	tf = t_fopen(NULL);
987*4cb4af11Schristos 	t_fprintf(tf, "hello\\\nworld\n");
988*4cb4af11Schristos 	t_frewind(tf);
989*4cb4af11Schristos 	ret = orw_expect(tf, "helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
990*4cb4af11Schristos 	t_fclose(tf);
991*4cb4af11Schristos 	return (ret);
992*4cb4af11Schristos }
993*4cb4af11Schristos 
994*4cb4af11Schristos 
995*4cb4af11Schristos /***************************************************************************
99623e44a77Schristos  * Boilerplate
99723e44a77Schristos  */
99823e44a77Schristos 
999*4cb4af11Schristos static int
100023e44a77Schristos t_prepare(int argc, char *argv[])
100123e44a77Schristos {
100223e44a77Schristos 
100323e44a77Schristos 	(void)argc;
100423e44a77Schristos 	(void)argv;
1005*4cb4af11Schristos 
1006*4cb4af11Schristos 	T(empty_input);
1007*4cb4af11Schristos 	T(empty_line);
1008*4cb4af11Schristos 	T(unterminated_line);
1009*4cb4af11Schristos 	T(single_whitespace);
1010*4cb4af11Schristos 	T(multiple_whitespace);
1011*4cb4af11Schristos 	T(comment);
1012*4cb4af11Schristos 	T(whitespace_before_comment);
1013*4cb4af11Schristos 	T(single_quoted_comment);
1014*4cb4af11Schristos 	T(double_quoted_comment);
1015*4cb4af11Schristos 	T(comment_at_eof);
1016*4cb4af11Schristos 
1017*4cb4af11Schristos 	T(single_word);
1018*4cb4af11Schristos 	T(single_whitespace_before_word);
1019*4cb4af11Schristos 	T(double_whitespace_before_word);
1020*4cb4af11Schristos 	T(single_whitespace_after_word);
1021*4cb4af11Schristos 	T(double_whitespace_after_word);
1022*4cb4af11Schristos 	T(comment_after_word);
1023*4cb4af11Schristos 	T(word_containing_hash);
1024*4cb4af11Schristos 	T(two_words);
1025*4cb4af11Schristos 
1026*4cb4af11Schristos 	T(naked_escape);
1027*4cb4af11Schristos 	T(escaped_escape);
1028*4cb4af11Schristos 	T(escaped_whitespace);
1029*4cb4af11Schristos 	T(escaped_newline_before_word);
1030*4cb4af11Schristos 	T(escaped_newline_within_word);
1031*4cb4af11Schristos 	T(escaped_newline_after_word);
1032*4cb4af11Schristos 	T(escaped_letter);
1033*4cb4af11Schristos 	T(escaped_comment);
1034*4cb4af11Schristos 	T(escape_at_eof);
1035*4cb4af11Schristos 
1036*4cb4af11Schristos 	T(naked_single_quote);
1037*4cb4af11Schristos 	T(naked_double_quote);
1038*4cb4af11Schristos 	T(empty_single_quotes);
1039*4cb4af11Schristos 	T(empty_double_quotes);
1040*4cb4af11Schristos 	T(single_quotes_within_double_quotes);
1041*4cb4af11Schristos 	T(double_quotes_within_single_quotes);
1042*4cb4af11Schristos 	T(single_quoted_whitespace);
1043*4cb4af11Schristos 	T(double_quoted_whitespace);
1044*4cb4af11Schristos 	T(single_quoted_words);
1045*4cb4af11Schristos 	T(double_quoted_words);
1046*4cb4af11Schristos 
1047*4cb4af11Schristos 	T(single_quote_before_word);
1048*4cb4af11Schristos 	T(double_quote_before_word);
1049*4cb4af11Schristos 	T(single_quote_within_word);
1050*4cb4af11Schristos 	T(double_quote_within_word);
1051*4cb4af11Schristos 	T(single_quote_after_word);
1052*4cb4af11Schristos 	T(double_quote_after_word);
1053*4cb4af11Schristos 
1054*4cb4af11Schristos 	T(escaped_single_quote);
1055*4cb4af11Schristos 	T(escaped_double_quote);
1056*4cb4af11Schristos 	T(escaped_whitespace_within_single_quotes);
1057*4cb4af11Schristos 	T(escaped_whitespace_within_double_quotes);
1058*4cb4af11Schristos 	T(escaped_letter_within_single_quotes);
1059*4cb4af11Schristos 	T(escaped_letter_within_double_quotes);
1060*4cb4af11Schristos 	T(escaped_escape_within_single_quotes);
1061*4cb4af11Schristos 	T(escaped_escape_within_double_quotes);
1062*4cb4af11Schristos 	T(escaped_single_quote_within_single_quotes);
1063*4cb4af11Schristos 	T(escaped_double_quote_within_single_quotes);
1064*4cb4af11Schristos 	T(escaped_single_quote_within_double_quotes);
1065*4cb4af11Schristos 	T(escaped_double_quote_within_double_quotes);
1066*4cb4af11Schristos 
1067*4cb4af11Schristos 	T(line_continuation_within_whitespace);
1068*4cb4af11Schristos 	T(line_continuation_before_whitespace);
1069*4cb4af11Schristos 	T(line_continuation_after_whitespace);
1070*4cb4af11Schristos 	T(line_continuation_within_word);
1071*4cb4af11Schristos 
1072*4cb4af11Schristos 	return (0);
107323e44a77Schristos }
107423e44a77Schristos 
1075*4cb4af11Schristos int
1076*4cb4af11Schristos main(int argc, char *argv[])
107723e44a77Schristos {
1078*4cb4af11Schristos 
1079*4cb4af11Schristos 	t_main(t_prepare, NULL, argc, argv);
108023e44a77Schristos }
1081