Commit 0138b981 0138b981d9d05173a88898085afda109fd47089d by Sergey Poznyakoff

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
1 parent f88a8d05
...@@ -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 {
......
...@@ -29,6 +29,7 @@ libfilter_la_SOURCES =\ ...@@ -29,6 +29,7 @@ libfilter_la_SOURCES =\
29 fromflt.c\ 29 fromflt.c\
30 header.c\ 30 header.c\
31 inline-comment.c\ 31 inline-comment.c\
32 linecon.c\
32 linelenflt.c\ 33 linelenflt.c\
33 qpflt.c 34 qpflt.c
34 35
......
...@@ -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;
......
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;
...@@ -69,6 +69,7 @@ TESTSUITE_AT = \ ...@@ -69,6 +69,7 @@ TESTSUITE_AT = \
69 fromflt.at\ 69 fromflt.at\
70 hdrflt.at\ 70 hdrflt.at\
71 inline-comment.at\ 71 inline-comment.at\
72 linecon.at\
72 list.at\ 73 list.at\
73 mailcap.at\ 74 mailcap.at\
74 prop.at\ 75 prop.at\
......
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
......