Improve IMAP I/O module. Add testcase.
* libmailutils/imapio/getline.c (initial_parse): New function. (mu_imapio_getline): Use initial_parse. * libmailutils/tests/imapio.c (main): Do not set progname. * libmailutils/tests/imapio.at: New file. * libmailutils/tests/Makefile.am: Add imapio.at. * libmailutils/tests/testsuite.at: Include imapio.at
Showing
5 changed files
with
155 additions
and
31 deletions
... | @@ -96,45 +96,30 @@ get_response_code (struct _mu_imapio *io) | ... | @@ -96,45 +96,30 @@ get_response_code (struct _mu_imapio *io) |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | int | 99 | #define IMAPIO_OK 0 |
100 | mu_imapio_getline (struct _mu_imapio *io) | 100 | #define IMAPIO_RESP 1 |
101 | { | 101 | #define IMAPIO_ERR 2 |
102 | int rc; | ||
103 | char *last_arg; | ||
104 | int type; | ||
105 | 102 | ||
106 | if (io->_imap_reply_ready) | 103 | static int |
107 | { | 104 | initial_parse (struct _mu_imapio *io) |
108 | mu_wordsplit_free_words (&io->_imap_ws); | 105 | { |
109 | io->_imap_reply_ready = 0; | 106 | int rc, type; |
110 | } | ||
111 | 107 | ||
112 | for (;;) | ||
113 | { | ||
114 | rc = mu_stream_getline (io->_imap_stream, | ||
115 | &io->_imap_buf_base, &io->_imap_buf_size, | ||
116 | &io->_imap_buf_level); | ||
117 | if (rc) | ||
118 | return rc; | ||
119 | if (io->_imap_buf_level == 0) | ||
120 | break; | ||
121 | io->_imap_buf_level = mu_rtrim_class (io->_imap_buf_base, | ||
122 | MU_CTYPE_ENDLN); | ||
123 | if ((rc = mu_wordsplit_len (io->_imap_buf_base, io->_imap_buf_level, | 108 | if ((rc = mu_wordsplit_len (io->_imap_buf_base, io->_imap_buf_level, |
124 | &io->_imap_ws, | 109 | &io->_imap_ws, |
125 | io->_imap_ws_flags | MU_WRDSF_INCREMENTAL))) | 110 | io->_imap_ws_flags | MU_WRDSF_INCREMENTAL))) |
126 | { | 111 | { |
127 | if (rc == MU_WRDSE_NOINPUT) | 112 | if (rc == MU_WRDSE_NOINPUT) |
128 | break; | 113 | return IMAPIO_OK; |
129 | return MU_ERR_PARSE; | 114 | return IMAPIO_ERR; |
130 | } | 115 | } |
131 | io->_imap_ws_flags |= MU_WRDSF_REUSE; | 116 | io->_imap_ws_flags |= MU_WRDSF_REUSE; |
132 | 117 | ||
133 | if ((rc = mu_wordsplit (NULL, &io->_imap_ws, MU_WRDSF_INCREMENTAL))) | 118 | if ((rc = mu_wordsplit (NULL, &io->_imap_ws, MU_WRDSF_INCREMENTAL))) |
134 | { | 119 | { |
135 | if (rc == MU_WRDSE_NOINPUT) | 120 | if (rc == MU_WRDSE_NOINPUT) |
136 | break; | 121 | return IMAPIO_OK; |
137 | return MU_ERR_PARSE; | 122 | return IMAPIO_ERR; |
138 | } | 123 | } |
139 | 124 | ||
140 | if ((type = is_status_response (io->_imap_ws.ws_wordv[1])) | 125 | if ((type = is_status_response (io->_imap_ws.ws_wordv[1])) |
... | @@ -143,7 +128,7 @@ mu_imapio_getline (struct _mu_imapio *io) | ... | @@ -143,7 +128,7 @@ mu_imapio_getline (struct _mu_imapio *io) |
143 | { | 128 | { |
144 | rc = get_response_code (io); | 129 | rc = get_response_code (io); |
145 | if (rc) | 130 | if (rc) |
146 | return MU_ERR_PARSE; | 131 | return IMAPIO_ERR; |
147 | while (io->_imap_ws.ws_endp < io->_imap_ws.ws_len && | 132 | while (io->_imap_ws.ws_endp < io->_imap_ws.ws_len && |
148 | mu_isblank (io->_imap_ws.ws_input[io->_imap_ws.ws_endp])) | 133 | mu_isblank (io->_imap_ws.ws_input[io->_imap_ws.ws_endp])) |
149 | io->_imap_ws.ws_endp++; | 134 | io->_imap_ws.ws_endp++; |
... | @@ -152,20 +137,59 @@ mu_imapio_getline (struct _mu_imapio *io) | ... | @@ -152,20 +137,59 @@ mu_imapio_getline (struct _mu_imapio *io) |
152 | io->_imap_ws.ws_flags &= ~MU_WRDSF_NOSPLIT; | 137 | io->_imap_ws.ws_flags &= ~MU_WRDSF_NOSPLIT; |
153 | if (rc) | 138 | if (rc) |
154 | { | 139 | { |
155 | if (rc == MU_WRDSE_NOINPUT) | 140 | if (rc != MU_WRDSE_NOINPUT) |
141 | return IMAPIO_ERR; | ||
142 | } | ||
143 | return IMAPIO_RESP; | ||
144 | } | ||
145 | return IMAPIO_OK; | ||
146 | } | ||
147 | |||
148 | int | ||
149 | mu_imapio_getline (struct _mu_imapio *io) | ||
150 | { | ||
151 | int rc; | ||
152 | char *last_arg; | ||
153 | |||
154 | if (io->_imap_reply_ready) | ||
155 | { | ||
156 | mu_wordsplit_free_words (&io->_imap_ws); | ||
157 | io->_imap_reply_ready = 0; | ||
158 | } | ||
159 | |||
160 | for (;;) | ||
161 | { | ||
162 | rc = mu_stream_getline (io->_imap_stream, | ||
163 | &io->_imap_buf_base, &io->_imap_buf_size, | ||
164 | &io->_imap_buf_level); | ||
165 | if (rc) | ||
166 | return rc; | ||
167 | if (io->_imap_buf_level == 0) | ||
168 | break; | ||
169 | io->_imap_buf_level = mu_rtrim_class (io->_imap_buf_base, | ||
170 | MU_CTYPE_ENDLN); | ||
171 | |||
172 | rc = initial_parse (io); | ||
173 | if (rc == IMAPIO_ERR) | ||
174 | { | ||
175 | rc = MU_ERR_PARSE; | ||
156 | break; | 176 | break; |
157 | return MU_ERR_PARSE; | ||
158 | } | 177 | } |
178 | else if (rc == IMAPIO_RESP) | ||
179 | { | ||
180 | rc = 0; | ||
159 | break; | 181 | break; |
160 | } | 182 | } |
161 | 183 | ||
162 | |||
163 | rc = mu_wordsplit_len (io->_imap_buf_base + io->_imap_ws.ws_endp, | 184 | rc = mu_wordsplit_len (io->_imap_buf_base + io->_imap_ws.ws_endp, |
164 | io->_imap_buf_level - io->_imap_ws.ws_endp, | 185 | io->_imap_buf_level - io->_imap_ws.ws_endp, |
165 | &io->_imap_ws, io->_imap_ws_flags); | 186 | &io->_imap_ws, io->_imap_ws_flags); |
166 | if (rc) | 187 | if (rc) |
167 | return MU_ERR_PARSE; | 188 | return MU_ERR_PARSE; |
168 | 189 | ||
190 | if (io->_imap_ws.ws_wordc == 0) | ||
191 | break; | ||
192 | |||
169 | last_arg = io->_imap_ws.ws_wordv[io->_imap_ws.ws_wordc - 1]; | 193 | last_arg = io->_imap_ws.ws_wordv[io->_imap_ws.ws_wordc - 1]; |
170 | if (last_arg[0] == '{' && last_arg[strlen (last_arg)-1] == '}') | 194 | if (last_arg[0] == '{' && last_arg[strlen (last_arg)-1] == '}') |
171 | { | 195 | { | ... | ... |
libmailutils/tests/imapio.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2011 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_BANNER(IMAP IO) | ||
18 | |||
19 | dnl ------------------------------------------------------------ | ||
20 | dnl IMAPIO([NAME], [KW = `'], [INPUT], [STDOUT = `'], | ||
21 | dnl [STDERR = `']) | ||
22 | dnl | ||
23 | m4_pushdef([IMAPIO],[ | ||
24 | m4_pushdef([MU_TEST_GROUP],[imapio]) | ||
25 | m4_pushdef([MU_TEST_KEYWORDS],[imapio]) | ||
26 | m4_pushdef([MU_TEST_COMMAND],[imapio]) | ||
27 | MU_GENERIC_TEST([$1],[$2],[$3],[],[$4],[$5]) | ||
28 | m4_popdef([MU_TEST_COMMAND]) | ||
29 | m4_popdef([MU_TEST_KEYWORDS]) | ||
30 | m4_popdef([MU_TEST_GROUP]) | ||
31 | ]) | ||
32 | |||
33 | dnl ------------------------------------------------------------ | ||
34 | dnl Tests | ||
35 | dnl ------------------------------------------------------------ | ||
36 | |||
37 | IMAPIO([simple string],[], | ||
38 | [1 select INBOX | ||
39 | ], | ||
40 | [], | ||
41 | [3 | ||
42 | 0: '1' | ||
43 | 1: 'select' | ||
44 | 2: 'INBOX' | ||
45 | ]) | ||
46 | |||
47 | IMAPIO([quoted string],[], | ||
48 | [1 select "Test mailbox" | ||
49 | ], | ||
50 | [], | ||
51 | [3 | ||
52 | 0: '1' | ||
53 | 1: 'select' | ||
54 | 2: 'Test mailbox' | ||
55 | ]) | ||
56 | |||
57 | IMAPIO([server response],[], | ||
58 | [1 OK That's OK | ||
59 | ], | ||
60 | [], | ||
61 | [3 | ||
62 | 0: '1' | ||
63 | 1: 'OK' | ||
64 | 2: 'That's OK' | ||
65 | ]) | ||
66 | |||
67 | IMAPIO([server response with code],[], | ||
68 | [* OK [[UIDNEXT 61]] Predicted next uid | ||
69 | ], | ||
70 | [], | ||
71 | [7 | ||
72 | 0: '*' | ||
73 | 1: 'OK' | ||
74 | [2: '[' | ||
75 | 3: 'UIDNEXT' | ||
76 | 4: '61' | ||
77 | 5: ']'] | ||
78 | 6: 'Predicted next uid' | ||
79 | ]) | ||
80 | |||
81 | IMAPIO([literals],[literal], | ||
82 | [A001 LOGIN {11} | ||
83 | FRED FOOBAR {7} | ||
84 | fat man | ||
85 | ], | ||
86 | [+ GO AHEAD | ||
87 | + GO AHEAD | ||
88 | ], | ||
89 | [4 | ||
90 | 0: 'A001' | ||
91 | 1: 'LOGIN' | ||
92 | 2: 'FRED FOOBAR' | ||
93 | 3: 'fat man' | ||
94 | ]) | ||
95 | |||
96 | dnl ------------------------------------------------------------ | ||
97 | m4_popdef([IMAPIO]) |
... | @@ -42,7 +42,6 @@ main (int argc, char **argv) | ... | @@ -42,7 +42,6 @@ main (int argc, char **argv) |
42 | mu_imapio_t io; | 42 | mu_imapio_t io; |
43 | mu_stream_t str; | 43 | mu_stream_t str; |
44 | 44 | ||
45 | mu_set_program_name (argv[0]); | ||
46 | mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); | 45 | mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); |
47 | 46 | ||
48 | for (i = 1; i < argc; i++) | 47 | for (i = 1; i < argc; i++) | ... | ... |
... | @@ -80,4 +80,7 @@ m4_include([linecon.at]) | ... | @@ -80,4 +80,7 @@ m4_include([linecon.at]) |
80 | AT_BANNER(Debug Specification) | 80 | AT_BANNER(Debug Specification) |
81 | m4_include([debugspec.at]) | 81 | m4_include([debugspec.at]) |
82 | 82 | ||
83 | AT_BANNER([IMAP IO]) | ||
84 | m4_include([imapio.at]) | ||
85 | |||
83 | m4_include([fsaf.at]) | 86 | m4_include([fsaf.at]) |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment