source: openpam/trunk/t/t_openpam_readword.c

Last change on this file was 938, checked in by Dag-Erling Smørgrav, 3 months ago

Switch from $Id$ to $OpenPAM$.

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