Implement a "line continuation" filter.
Line continuation filter removes from its input any sequence of '\\\n' (a backslash followed by a newline). It is useful for reading various UNIX configuration files. * include/mailutils/filter.h (mu_linecon_filter): New extern. * libmailutils/filter/linecon.c: New file. * libmailutils/filter/Makefile.am (libfilter_la_SOURCES): Add linecon.c * libmailutils/filter/filter.c (mu_filter_get_list): Register mu_linecon_filter. * libmailutils/tests/linecon.at: New test. * libmailutils/tests/Makefile.am (TESTSUITE_AT): Add linecon.at * libmailutils/tests/testsuite.at: Include linecon.at
Showing
7 changed files
with
166 additions
and
0 deletions
... | @@ -110,6 +110,7 @@ extern mu_filter_record_t mu_rfc_2047_B_filter; | ... | @@ -110,6 +110,7 @@ extern mu_filter_record_t mu_rfc_2047_B_filter; |
110 | extern mu_filter_record_t mu_from_filter; | 110 | extern mu_filter_record_t mu_from_filter; |
111 | extern mu_filter_record_t mu_inline_comment_filter; | 111 | extern mu_filter_record_t mu_inline_comment_filter; |
112 | extern mu_filter_record_t mu_header_filter; | 112 | extern mu_filter_record_t mu_header_filter; |
113 | extern mu_filter_record_t mu_linecon_filter; | ||
113 | 114 | ||
114 | enum mu_iconv_fallback_mode | 115 | enum mu_iconv_fallback_mode |
115 | { | 116 | { | ... | ... |
... | @@ -80,6 +80,7 @@ mu_filter_get_list (mu_list_t *plist) | ... | @@ -80,6 +80,7 @@ mu_filter_get_list (mu_list_t *plist) |
80 | mu_list_append (filter_list, mu_from_filter); | 80 | mu_list_append (filter_list, mu_from_filter); |
81 | mu_list_append (filter_list, mu_inline_comment_filter); | 81 | mu_list_append (filter_list, mu_inline_comment_filter); |
82 | mu_list_append (filter_list, mu_header_filter); | 82 | mu_list_append (filter_list, mu_header_filter); |
83 | mu_list_append (filter_list, mu_linecon_filter); | ||
83 | /* FIXME: add the default encodings? */ | 84 | /* FIXME: add the default encodings? */ |
84 | } | 85 | } |
85 | *plist = filter_list; | 86 | *plist = filter_list; | ... | ... |
libmailutils/filter/linecon.c
0 → 100644
1 | /* Simple inline comment filter for GNU Mailutils. | ||
2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | /* linecon - a line continuation filter. | ||
18 | |||
19 | This filter has only decode mode. It removes from the input | ||
20 | backslashes immediately followed by a newline, thus implementing | ||
21 | a familiar UNIX line-continuation facility. */ | ||
22 | |||
23 | #ifdef HAVE_CONFIG_H | ||
24 | # include <config.h> | ||
25 | #endif | ||
26 | #include <stdlib.h> | ||
27 | #include <mailutils/errno.h> | ||
28 | #include <mailutils/filter.h> | ||
29 | #include <mailutils/cctype.h> | ||
30 | |||
31 | static enum mu_filter_result | ||
32 | _linecon_decoder (void *xd, enum mu_filter_command cmd, | ||
33 | struct mu_filter_io *iobuf) | ||
34 | { | ||
35 | int *escaped = xd; | ||
36 | const unsigned char *iptr, *iend; | ||
37 | char *optr, *oend; | ||
38 | |||
39 | switch (cmd) | ||
40 | { | ||
41 | case mu_filter_init: | ||
42 | *escaped = 0; | ||
43 | return mu_filter_ok; | ||
44 | |||
45 | case mu_filter_done: | ||
46 | return mu_filter_ok; | ||
47 | |||
48 | default: | ||
49 | break; | ||
50 | } | ||
51 | |||
52 | iptr = (const unsigned char *) iobuf->input; | ||
53 | iend = iptr + iobuf->isize; | ||
54 | optr = iobuf->output; | ||
55 | oend = optr + iobuf->osize; | ||
56 | |||
57 | while (iptr < iend && optr < oend) | ||
58 | { | ||
59 | int c = *iptr++; | ||
60 | switch (c) | ||
61 | { | ||
62 | case '\\': | ||
63 | *escaped = 1; | ||
64 | continue; | ||
65 | |||
66 | case '\n': | ||
67 | if (*escaped) | ||
68 | { | ||
69 | *escaped = 0; | ||
70 | continue; | ||
71 | } | ||
72 | *optr++ = c; | ||
73 | break; | ||
74 | |||
75 | default: | ||
76 | if (*escaped) | ||
77 | { | ||
78 | *escaped = 0; | ||
79 | *optr++ = '\\'; | ||
80 | if (optr == oend) | ||
81 | { | ||
82 | iptr--; | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | *optr++ = c; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | iobuf->isize = iptr - (const unsigned char *) iobuf->input; | ||
91 | iobuf->osize = optr - iobuf->output; | ||
92 | return mu_filter_ok; | ||
93 | } | ||
94 | |||
95 | static int | ||
96 | alloc_state (void **pret, int mode MU_ARG_UNUSED, int argc, const char **argv) | ||
97 | { | ||
98 | *pret = malloc (sizeof (int)); | ||
99 | if (!*pret) | ||
100 | return ENOMEM; | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static struct _mu_filter_record _linecon_filter = { | ||
105 | "LINECON", | ||
106 | 0, | ||
107 | alloc_state, | ||
108 | NULL, | ||
109 | _linecon_decoder, | ||
110 | }; | ||
111 | |||
112 | mu_filter_record_t mu_linecon_filter = &_linecon_filter; |
libmailutils/tests/linecon.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([linecon filter]) | ||
18 | AT_KEYWORDS([filter decode linecon]) | ||
19 | sed 's/\$//' > input <<EOT | ||
20 | input line 1 | ||
21 | input line 2 | ||
22 | a very\ | ||
23 | long logical\ | ||
24 | line spl\ | ||
25 | it over several physical\ | ||
26 | ones | ||
27 | a li\ne with \escapes | ||
28 | backslash followed by a space \ $ | ||
29 | EOT | ||
30 | sed 's/\$//' > expout <<EOT | ||
31 | input line 1 | ||
32 | input line 2 | ||
33 | a very long logical line split over several physical ones | ||
34 | a li\ne with \escapes | ||
35 | backslash followed by a space \ $ | ||
36 | EOT | ||
37 | |||
38 | AT_CHECK([fltst linecon decode read < input], | ||
39 | [0], | ||
40 | [expout]) | ||
41 | |||
42 | AT_CHECK([fltst linecon decode write < input], | ||
43 | [0], | ||
44 | [expout]) | ||
45 | |||
46 | AT_CLEANUP | ||
47 | |||
48 | |||
49 |
... | @@ -67,4 +67,5 @@ m4_include([wicket.at]) | ... | @@ -67,4 +67,5 @@ m4_include([wicket.at]) |
67 | m4_include([prop.at]) | 67 | m4_include([prop.at]) |
68 | m4_include([inline-comment.at]) | 68 | m4_include([inline-comment.at]) |
69 | m4_include([hdrflt.at]) | 69 | m4_include([hdrflt.at]) |
70 | m4_include([linecon.at]) | ||
70 | 71 | ... | ... |
-
Please register or sign in to post a comment