source: openpam/trunk/t/t_openpam_readword.c

Last change on this file was 837, checked in by des, 7 weeks ago

Oops - the line count is incremented by the line continuation, not by
the word that precedes it.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 22.8 KB
Line 
1/*-
2 * Copyright (c) 2012 Dag-Erling Smørgrav
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 *    products derived from this software without specific prior written
15 *    permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Id$
30 */
31
32#ifdef HAVE_CONFIG_H
33# include "config.h"
34#endif
35
36#include <err.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <unistd.h>
41
42#include <security/pam_appl.h>
43#include <security/openpam.h>
44
45#include "t.h"
46
47/*
48 * Read a word from the temp file and verify that the result matches our
49 * expectations: whether a word was read at all, how many lines were read
50 * (in case of quoted or escaped newlines), whether we reached the end of
51 * the file and whether we reached the end of the line.
52 */
53static int
54orw_expect(struct t_file *tf, const char *expected, int lines, int eof, int eol)
55{
56        int ch, lineno = 0;
57        char *got;
58        size_t len;
59
60        got = openpam_readword(tf->file, &lineno, &len);
61        if (t_ferror(tf))
62                err(1, "%s(): %s", __func__, tf->name);
63        if (expected != NULL && got == NULL) {
64                t_verbose("expected <<%s>>, got nothing\n", expected);
65                return (0);
66        }
67        if (expected == NULL && got != NULL) {
68                t_verbose("expected nothing, got <<%s>>\n", got);
69                return (0);
70        }
71        if (expected != NULL && got != NULL && strcmp(expected, got) != 0) {
72                t_verbose("expected <<%s>>, got <<%s>>\n", expected, got);
73                return (0);
74        }
75        if (lineno != lines) {
76                t_verbose("expected to advance %d lines, advanced %d lines\n",
77                    lines, lineno);
78                return (0);
79        }
80        if (eof && !t_feof(tf)) {
81                t_verbose("expected EOF, but didn't get it\n");
82                return (0);
83        }
84        if (!eof && t_feof(tf)) {
85                t_verbose("didn't expect EOF, but got it anyway\n");
86                return (0);
87        }
88        ch = fgetc(tf->file);
89        if (t_ferror(tf))
90                err(1, "%s(): %s", __func__, tf->name);
91        if (eol && ch != '\n') {
92                t_verbose("expected EOL, but didn't get it\n");
93                return (0);
94        }
95        if (!eol && ch == '\n') {
96                t_verbose("didn't expect EOL, but got it anyway\n");
97                return (0);
98        }
99        if (ch != EOF)
100                ungetc(ch, tf->file);
101        return (1);
102}
103
104
105/***************************************************************************
106 * Lines without words
107 */
108
109T_FUNC(empty_input, "empty input")
110{
111        struct t_file *tf;
112        int ret;
113
114        tf = t_fopen(NULL);
115        ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
116        t_fclose(tf);
117        return (ret);
118}
119
120T_FUNC(empty_line, "empty line")
121{
122        struct t_file *tf;
123        int ret;
124
125        tf = t_fopen(NULL);
126        t_fprintf(tf, "\n");
127        t_frewind(tf);
128        ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
129        t_fclose(tf);
130        return (ret);
131}
132
133T_FUNC(unterminated_line, "unterminated line")
134{
135        struct t_file *tf;
136        int ret;
137
138        tf = t_fopen(NULL);
139        t_fprintf(tf, " ");
140        t_frewind(tf);
141        ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
142        t_fclose(tf);
143        return (ret);
144}
145
146T_FUNC(single_whitespace, "single whitespace")
147{
148        struct t_file *tf;
149        int ret;
150
151        tf = t_fopen(NULL);
152        t_fprintf(tf, " \n");
153        t_frewind(tf);
154        ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
155        t_fclose(tf);
156        return (ret);
157}
158
159T_FUNC(multiple_whitespace, "multiple whitespace")
160{
161        struct t_file *tf;
162        int ret;
163
164        tf = t_fopen(NULL);
165        t_fprintf(tf, " \t\r\n");
166        t_frewind(tf);
167        ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
168        t_fclose(tf);
169        return (ret);
170}
171
172T_FUNC(comment, "comment")
173{
174        struct t_file *tf;
175        int ret;
176
177        tf = t_fopen(NULL);
178        t_fprintf(tf, "# comment\n");
179        t_frewind(tf);
180        ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
181        t_fclose(tf);
182        return (ret);
183}
184
185T_FUNC(whitespace_before_comment, "whitespace before comment")
186{
187        struct t_file *tf;
188        int ret;
189
190        tf = t_fopen(NULL);
191        t_fprintf(tf, " # comment\n");
192        t_frewind(tf);
193        ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
194        t_fclose(tf);
195        return (ret);
196}
197
198T_FUNC(single_quoted_comment, "single-quoted comment")
199{
200        struct t_file *tf;
201        int ret;
202
203        tf = t_fopen(NULL);
204        t_fprintf(tf, " '# comment'\n");
205        t_frewind(tf);
206        ret = orw_expect(tf, "# comment", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
207        t_fclose(tf);
208        return (ret);
209}
210
211T_FUNC(double_quoted_comment, "double-quoted comment")
212{
213        struct t_file *tf;
214        int ret;
215
216        tf = t_fopen(NULL);
217        t_fprintf(tf, " \"# comment\"\n");
218        t_frewind(tf);
219        ret = orw_expect(tf, "# comment", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
220        t_fclose(tf);
221        return (ret);
222}
223
224T_FUNC(comment_at_eof, "comment at end of file")
225{
226        struct t_file *tf;
227        int ret;
228
229        tf = t_fopen(NULL);
230        t_fprintf(tf, "# comment");
231        t_frewind(tf);
232        ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
233        t_fclose(tf);
234        return (ret);
235}
236
237
238/***************************************************************************
239 * Simple cases - no quotes or escapes
240 */
241
242T_FUNC(single_word, "single word")
243{
244        const char *word = "hello";
245        struct t_file *tf;
246        int ret;
247
248        tf = t_fopen(NULL);
249        t_fprintf(tf, "%s\n", word);
250        t_frewind(tf);
251        ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
252        t_fclose(tf);
253        return (ret);
254}
255
256T_FUNC(single_whitespace_before_word, "single whitespace before word")
257{
258        const char *word = "hello";
259        struct t_file *tf;
260        int ret;
261
262        tf = t_fopen(NULL);
263        t_fprintf(tf, " %s\n", word);
264        t_frewind(tf);
265        ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
266        t_fclose(tf);
267        return (ret);
268}
269
270T_FUNC(double_whitespace_before_word, "double whitespace before word")
271{
272        const char *word = "hello";
273        struct t_file *tf;
274        int ret;
275
276        tf = t_fopen(NULL);
277        t_fprintf(tf, "  %s\n", word);
278        t_frewind(tf);
279        ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
280        t_fclose(tf);
281        return (ret);
282}
283
284T_FUNC(single_whitespace_after_word, "single whitespace after word")
285{
286        const char *word = "hello";
287        struct t_file *tf;
288        int ret;
289
290        tf = t_fopen(NULL);
291        t_fprintf(tf, "%s \n", word);
292        t_frewind(tf);
293        ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
294        t_fclose(tf);
295        return (ret);
296}
297
298T_FUNC(double_whitespace_after_word, "double whitespace after word")
299{
300        const char *word = "hello";
301        struct t_file *tf;
302        int ret;
303
304        tf = t_fopen(NULL);
305        t_fprintf(tf, "%s  \n", word);
306        t_frewind(tf);
307        ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
308        t_fclose(tf);
309        return (ret);
310}
311
312T_FUNC(comment_after_word, "comment after word")
313{
314        const char *word = "hello";
315        struct t_file *tf;
316        int ret;
317
318        tf = t_fopen(NULL);
319        t_fprintf(tf, "%s # comment\n", word);
320        t_frewind(tf);
321        ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
322            orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
323        t_fclose(tf);
324        return (ret);
325}
326
327T_FUNC(word_containing_hash, "word containing hash")
328{
329        const char *word = "hello#world";
330        struct t_file *tf;
331        int ret;
332
333        tf = t_fopen(NULL);
334        t_fprintf(tf, "%s\n", word);
335        t_frewind(tf);
336        ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
337        t_fclose(tf);
338        return (ret);
339}
340
341T_FUNC(two_words, "two words")
342{
343        const char *word[] = { "hello", "world" };
344        struct t_file *tf;
345        int ret;
346
347        tf = t_fopen(NULL);
348        t_fprintf(tf, "%s %s\n", word[0], word[1]);
349        t_frewind(tf);
350        ret = orw_expect(tf, word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
351            orw_expect(tf, word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
352        t_fclose(tf);
353        return (ret);
354}
355
356
357/***************************************************************************
358 * Escapes
359 */
360
361T_FUNC(naked_escape, "naked escape")
362{
363        struct t_file *tf;
364        int ret;
365
366        tf = t_fopen(NULL);
367        t_fprintf(tf, "\\");
368        t_frewind(tf);
369        ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
370        t_fclose(tf);
371        return (ret);
372}
373
374T_FUNC(escaped_escape, "escaped escape")
375{
376        struct t_file *tf;
377        int ret;
378
379        tf = t_fopen(NULL);
380        t_fprintf(tf, "\\\\\n");
381        t_frewind(tf);
382        ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
383        t_fclose(tf);
384        return (ret);
385}
386
387T_FUNC(escaped_whitespace, "escaped whitespace")
388{
389        struct t_file *tf;
390        int ret;
391
392        tf = t_fopen(NULL);
393        t_fprintf(tf, "\\  \\\t \\\r \\\n\n");
394        t_frewind(tf);
395        ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
396            orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
397            orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
398            /* this last one is a line continuation */
399            orw_expect(tf, NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
400        t_fclose(tf);
401        return (ret);
402}
403
404T_FUNC(escaped_newline_before_word, "escaped newline before word")
405{
406        struct t_file *tf;
407        int ret;
408
409        tf = t_fopen(NULL);
410        t_fprintf(tf, "\\\nhello world\n");
411        t_frewind(tf);
412        ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
413        t_fclose(tf);
414        return (ret);
415}
416
417T_FUNC(escaped_newline_within_word, "escaped newline within word")
418{
419        struct t_file *tf;
420        int ret;
421
422        tf = t_fopen(NULL);
423        t_fprintf(tf, "hello\\\nworld\n");
424        t_frewind(tf);
425        ret = orw_expect(tf, "helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
426        t_fclose(tf);
427        return (ret);
428}
429
430T_FUNC(escaped_newline_after_word, "escaped newline after word")
431{
432        struct t_file *tf;
433        int ret;
434
435        tf = t_fopen(NULL);
436        t_fprintf(tf, "hello\\\n world\n");
437        t_frewind(tf);
438        ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
439        t_fclose(tf);
440        return (ret);
441}
442
443T_FUNC(escaped_letter, "escaped letter")
444{
445        struct t_file *tf;
446        int ret;
447
448        tf = t_fopen(NULL);
449        t_fprintf(tf, "\\z\n");
450        t_frewind(tf);
451        ret = orw_expect(tf, "z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
452        t_fclose(tf);
453        return (ret);
454}
455
456T_FUNC(escaped_comment, "escaped comment")
457{
458        struct t_file *tf;
459        int ret;
460
461        tf = t_fopen(NULL);
462        t_fprintf(tf, " \\# comment\n");
463        t_frewind(tf);
464        ret = orw_expect(tf, "#", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
465            orw_expect(tf, "comment", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
466        t_fclose(tf);
467        return (ret);
468}
469
470T_FUNC(escape_at_eof, "escape at end of file")
471{
472        struct t_file *tf;
473        int ret;
474
475        tf = t_fopen(NULL);
476        t_fprintf(tf, "z\\");
477        t_frewind(tf);
478        ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
479        t_fclose(tf);
480        return (ret);
481}
482
483
484/***************************************************************************
485 * Quotes
486 */
487
488T_FUNC(naked_single_quote, "naked single quote")
489{
490        struct t_file *tf;
491        int ret;
492
493        tf = t_fopen(NULL);
494        t_fprintf(tf, "'");
495        t_frewind(tf);
496        ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
497        t_fclose(tf);
498        return (ret);
499}
500
501T_FUNC(naked_double_quote, "naked double quote")
502{
503        struct t_file *tf;
504        int ret;
505
506        tf = t_fopen(NULL);
507        t_fprintf(tf, "\"");
508        t_frewind(tf);
509        ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
510        t_fclose(tf);
511        return (ret);
512}
513
514T_FUNC(empty_single_quotes, "empty single quotes")
515{
516        struct t_file *tf;
517        int ret;
518
519        tf = t_fopen(NULL);
520        t_fprintf(tf, "''\n");
521        t_frewind(tf);
522        ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
523        t_fclose(tf);
524        return (ret);
525}
526
527T_FUNC(empty_double_quotes, "empty double quotes")
528{
529        struct t_file *tf;
530        int ret;
531
532        tf = t_fopen(NULL);
533        t_fprintf(tf, "\"\"\n");
534        t_frewind(tf);
535        ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
536        t_fclose(tf);
537        return (ret);
538}
539
540T_FUNC(single_quotes_within_double_quotes, "single quotes within double quotes")
541{
542        struct t_file *tf;
543        int ret;
544
545        tf = t_fopen(NULL);
546        t_fprintf(tf, "\"' '\"\n");
547        t_frewind(tf);
548        ret = orw_expect(tf, "' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
549        t_fclose(tf);
550        return (ret);
551}
552
553T_FUNC(double_quotes_within_single_quotes, "double quotes within single quotes")
554{
555        struct t_file *tf;
556        int ret;
557
558        tf = t_fopen(NULL);
559        t_fprintf(tf, "'\" \"'\n");
560        t_frewind(tf);
561        ret = orw_expect(tf, "\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
562        t_fclose(tf);
563        return (ret);
564}
565
566T_FUNC(single_quoted_whitespace, "single-quoted whitespace")
567{
568        struct t_file *tf;
569        int ret;
570
571        tf = t_fopen(NULL);
572        t_fprintf(tf, "' ' '\t' '\r' '\n'\n");
573        t_frewind(tf);
574        ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
575            orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
576            orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
577            orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
578        t_fclose(tf);
579        return (ret);
580}
581
582T_FUNC(double_quoted_whitespace, "double-quoted whitespace")
583{
584        struct t_file *tf;
585        int ret;
586
587        tf = t_fopen(NULL);
588        t_fprintf(tf, "\" \" \"\t\" \"\r\" \"\n\"\n");
589        t_frewind(tf);
590        ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
591            orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
592            orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
593            orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
594        t_fclose(tf);
595        return (ret);
596}
597
598T_FUNC(single_quoted_words, "single-quoted words")
599{
600        struct t_file *tf;
601        int ret;
602
603        tf = t_fopen(NULL);
604        t_fprintf(tf, "'hello world'\n");
605        t_frewind(tf);
606        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
607        t_fclose(tf);
608        return (ret);
609}
610
611T_FUNC(double_quoted_words, "double-quoted words")
612{
613        struct t_file *tf;
614        int ret;
615
616        tf = t_fopen(NULL);
617        t_fprintf(tf, "\"hello world\"\n");
618        t_frewind(tf);
619        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
620        t_fclose(tf);
621        return (ret);
622}
623
624
625/***************************************************************************
626 * Combinations of quoted and unquoted text
627 */
628
629T_FUNC(single_quote_before_word, "single quote before word")
630{
631        struct t_file *tf;
632        int ret;
633
634        tf = t_fopen(NULL);
635        t_fprintf(tf, "'hello 'world\n");
636        t_frewind(tf);
637        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
638        t_fclose(tf);
639        return (ret);
640}
641
642T_FUNC(double_quote_before_word, "double quote before word")
643{
644        struct t_file *tf;
645        int ret;
646
647        tf = t_fopen(NULL);
648        t_fprintf(tf, "\"hello \"world\n");
649        t_frewind(tf);
650        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
651        t_fclose(tf);
652        return (ret);
653}
654
655T_FUNC(single_quote_within_word, "single quote within word")
656{
657        struct t_file *tf;
658        int ret;
659
660        tf = t_fopen(NULL);
661        t_fprintf(tf, "hello' 'world\n");
662        t_frewind(tf);
663        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
664        t_fclose(tf);
665        return (ret);
666}
667
668T_FUNC(double_quote_within_word, "double quote within word")
669{
670        struct t_file *tf;
671        int ret;
672
673        tf = t_fopen(NULL);
674        t_fprintf(tf, "hello\" \"world\n");
675        t_frewind(tf);
676        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
677        t_fclose(tf);
678        return (ret);
679}
680
681T_FUNC(single_quote_after_word, "single quote after word")
682{
683        struct t_file *tf;
684        int ret;
685
686        tf = t_fopen(NULL);
687        t_fprintf(tf, "hello' world'\n");
688        t_frewind(tf);
689        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
690        t_fclose(tf);
691        return (ret);
692}
693
694T_FUNC(double_quote_after_word, "double quote after word")
695{
696        struct t_file *tf;
697        int ret;
698
699        tf = t_fopen(NULL);
700        t_fprintf(tf, "hello\" world\"\n");
701        t_frewind(tf);
702        ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
703        t_fclose(tf);
704        return (ret);
705}
706
707
708/***************************************************************************
709 * Combinations of escape and quotes
710 */
711
712T_FUNC(escaped_single_quote,
713    "escaped single quote")
714{
715        struct t_file *tf;
716        int ret;
717
718        tf = t_fopen(NULL);
719        t_fprintf(tf, "\\'\n");
720        t_frewind(tf);
721        ret = orw_expect(tf, "'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
722        t_fclose(tf);
723        return (ret);
724}
725
726T_FUNC(escaped_double_quote,
727    "escaped double quote")
728{
729        struct t_file *tf;
730        int ret;
731
732        tf = t_fopen(NULL);
733        t_fprintf(tf, "\\\"\n");
734        t_frewind(tf);
735        ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
736        t_fclose(tf);
737        return (ret);
738}
739
740T_FUNC(escaped_whitespace_within_single_quotes,
741    "escaped whitespace within single quotes")
742{
743        struct t_file *tf;
744        int ret;
745
746        tf = t_fopen(NULL);
747        t_fprintf(tf, "'\\ ' '\\\t' '\\\r' '\\\n'\n");
748        t_frewind(tf);
749        ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
750            orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
751            orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
752            orw_expect(tf, "\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
753        t_fclose(tf);
754        return (ret);
755}
756
757T_FUNC(escaped_whitespace_within_double_quotes,
758    "escaped whitespace within double quotes")
759{
760        struct t_file *tf;
761        int ret;
762
763        tf = t_fopen(NULL);
764        t_fprintf(tf, "\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n");
765        t_frewind(tf);
766        ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
767            orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
768            orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
769            /* this last one is a line continuation */
770            orw_expect(tf, "", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
771        t_fclose(tf);
772        return (ret);
773}
774
775T_FUNC(escaped_letter_within_single_quotes,
776    "escaped letter within single quotes")
777{
778        struct t_file *tf;
779        int ret;
780
781        tf = t_fopen(NULL);
782        t_fprintf(tf, "'\\z'\n");
783        t_frewind(tf);
784        ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
785        t_fclose(tf);
786        return (ret);
787}
788
789T_FUNC(escaped_letter_within_double_quotes,
790    "escaped letter within double quotes")
791{
792        struct t_file *tf;
793        int ret;
794
795        tf = t_fopen(NULL);
796        t_fprintf(tf, "\"\\z\"\n");
797        t_frewind(tf);
798        ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
799        t_fclose(tf);
800        return (ret);
801}
802
803T_FUNC(escaped_escape_within_single_quotes,
804    "escaped escape within single quotes")
805{
806        struct t_file *tf;
807        int ret;
808
809        tf = t_fopen(NULL);
810        t_fprintf(tf, "'\\\\'\n");
811        t_frewind(tf);
812        ret = orw_expect(tf, "\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
813        t_fclose(tf);
814        return (ret);
815}
816
817T_FUNC(escaped_escape_within_double_quotes,
818    "escaped escape within double quotes")
819{
820        struct t_file *tf;
821        int ret;
822
823        tf = t_fopen(NULL);
824        t_fprintf(tf, "\"\\\\\"\n");
825        t_frewind(tf);
826        ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
827        t_fclose(tf);
828        return (ret);
829}
830
831T_FUNC(escaped_single_quote_within_single_quotes,
832    "escaped single quote within single quotes")
833{
834        struct t_file *tf;
835        int ret;
836
837        tf = t_fopen(NULL);
838        t_fprintf(tf, "'\\''\n");
839        t_frewind(tf);
840        ret = orw_expect(tf, NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/);
841        t_fclose(tf);
842        return (ret);
843}
844
845T_FUNC(escaped_double_quote_within_single_quotes,
846    "escaped double quote within single quotes")
847{
848        struct t_file *tf;
849        int ret;
850
851        tf = t_fopen(NULL);
852        t_fprintf(tf, "'\\\"'\n");
853        t_frewind(tf);
854        ret = orw_expect(tf, "\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
855        t_fclose(tf);
856        return (ret);
857}
858
859T_FUNC(escaped_single_quote_within_double_quotes,
860    "escaped single quote within double quotes")
861{
862        struct t_file *tf;
863        int ret;
864
865        tf = t_fopen(NULL);
866        t_fprintf(tf, "\"\\'\"\n");
867        t_frewind(tf);
868        ret = orw_expect(tf, "\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
869        t_fclose(tf);
870        return (ret);
871}
872
873T_FUNC(escaped_double_quote_within_double_quotes,
874    "escaped double quote within double quotes")
875{
876        struct t_file *tf;
877        int ret;
878
879        tf = t_fopen(NULL);
880        t_fprintf(tf, "\"\\\"\"\n");
881        t_frewind(tf);
882        ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
883        t_fclose(tf);
884        return (ret);
885}
886
887
888/***************************************************************************
889 * Line continuation
890 */
891
892T_FUNC(line_continuation_within_whitespace, "line continuation within whitespace")
893{
894        struct t_file *tf;
895        int ret;
896
897        tf = t_fopen(NULL);
898        t_fprintf(tf, "hello \\\n world\n");
899        t_frewind(tf);
900        ret = orw_expect(tf, "hello", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
901            orw_expect(tf, "world", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
902        t_fclose(tf);
903        return (ret);
904}
905
906T_FUNC(line_continuation_before_whitespace, "line continuation before whitespace")
907{
908        struct t_file *tf;
909        int ret;
910
911        tf = t_fopen(NULL);
912        t_fprintf(tf, "hello\\\n world\n");
913        t_frewind(tf);
914        ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
915            orw_expect(tf, "world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
916        t_fclose(tf);
917        return (ret);
918}
919
920T_FUNC(line_continuation_after_whitespace, "line continuation after whitespace")
921{
922        struct t_file *tf;
923        int ret;
924
925        tf = t_fopen(NULL);
926        t_fprintf(tf, "hello \\\nworld\n");
927        t_frewind(tf);
928        ret = orw_expect(tf, "hello", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
929            orw_expect(tf, "world", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
930        t_fclose(tf);
931        return (ret);
932}
933
934T_FUNC(line_continuation_within_word, "line continuation within word")
935{
936        struct t_file *tf;
937        int ret;
938
939        tf = t_fopen(NULL);
940        t_fprintf(tf, "hello\\\nworld\n");
941        t_frewind(tf);
942        ret = orw_expect(tf, "helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
943        t_fclose(tf);
944        return (ret);
945}
946
947
948/***************************************************************************
949 * Boilerplate
950 */
951
952static const struct t_test *t_plan[] = {
953        T(empty_input),
954        T(empty_line),
955        T(unterminated_line),
956        T(single_whitespace),
957        T(multiple_whitespace),
958        T(comment),
959        T(whitespace_before_comment),
960        T(single_quoted_comment),
961        T(double_quoted_comment),
962        T(comment_at_eof),
963
964        T(single_word),
965        T(single_whitespace_before_word),
966        T(double_whitespace_before_word),
967        T(single_whitespace_after_word),
968        T(double_whitespace_after_word),
969        T(comment_after_word),
970        T(word_containing_hash),
971        T(two_words),
972
973        T(naked_escape),
974        T(escaped_escape),
975        T(escaped_whitespace),
976        T(escaped_newline_before_word),
977        T(escaped_newline_within_word),
978        T(escaped_newline_after_word),
979        T(escaped_letter),
980        T(escaped_comment),
981        T(escape_at_eof),
982
983        T(naked_single_quote),
984        T(naked_double_quote),
985        T(empty_single_quotes),
986        T(empty_double_quotes),
987        T(single_quotes_within_double_quotes),
988        T(double_quotes_within_single_quotes),
989        T(single_quoted_whitespace),
990        T(double_quoted_whitespace),
991        T(single_quoted_words),
992        T(double_quoted_words),
993
994        T(single_quote_before_word),
995        T(double_quote_before_word),
996        T(single_quote_within_word),
997        T(double_quote_within_word),
998        T(single_quote_after_word),
999        T(double_quote_after_word),
1000
1001        T(escaped_single_quote),
1002        T(escaped_double_quote),
1003        T(escaped_whitespace_within_single_quotes),
1004        T(escaped_whitespace_within_double_quotes),
1005        T(escaped_letter_within_single_quotes),
1006        T(escaped_letter_within_double_quotes),
1007        T(escaped_escape_within_single_quotes),
1008        T(escaped_escape_within_double_quotes),
1009        T(escaped_single_quote_within_single_quotes),
1010        T(escaped_double_quote_within_single_quotes),
1011        T(escaped_single_quote_within_double_quotes),
1012        T(escaped_double_quote_within_double_quotes),
1013
1014        T(line_continuation_within_whitespace),
1015        T(line_continuation_before_whitespace),
1016        T(line_continuation_after_whitespace),
1017        T(line_continuation_within_word),
1018
1019        NULL
1020};
1021
1022const struct t_test **
1023t_prepare(int argc, char *argv[])
1024{
1025
1026        (void)argc;
1027        (void)argv;
1028        return (t_plan);
1029}
1030
1031void
1032t_cleanup(void)
1033{
1034}
Note: See TracBrowser for help on using the repository browser.