A fix to the documentation makefile from John D. Mitchell.
[ragel.git] / test / mailbox1.rl
blobea231735a7c07831ab22ac2c4307fc4d9fb8841a
1 /*
2  * @LANG: c++
3  * @CFLAGS: -I../aapl
4  *
5  * Test works with split code gen.
6  */
8 /*
9  * Parses unix mail boxes into headers and bodies.
10  */
12 #include "mailbox1.h"
14 %%{
15         machine MBox;
17         # Buffer the header names.
18         action bufHeadName { fsm->headName.append(fc); }
20         # Buffer the header content.
21         action bufHeadContent { fsm->headContent.append(fc); }
23         # Terminate a header. If it is an interesting header then prints it.
24         action finBufHeadContent {
25                 /* Terminate the buffers. */
26                 fsm->headName.append(0);
27                 fsm->headContent.append(0);
29                 /* Print the header. Interesting headers. */
30                 printf("%s:%s\n", fsm->headName.data, fsm->headContent.data);
31                 
32                 /* Clear for the next time we use them. */
33                 fsm->headName.empty();
34                 fsm->headContent.empty();
35         }
37         action msgstart{
38                 printf("NEW MESSAGE\n");
39         }
41         # Prints a blank line after the end of the headers of each message.
42         action blankLine {
43                 printf("\n");
44         }
45         
46         # Helpers we will use in matching the date section of the from line.
47         day = /[A-Z][a-z][a-z]/;
48         month = /[A-Z][a-z][a-z]/;
49         year = /[0-9][0-9][0-9][0-9]/;
50         time = /[0-9][0-9]:[0-9][0-9]/ . ( /:[0-9][0-9]/ | '' );
51         letterZone = /[A-Z][A-Z][A-Z]/;
52         numZone = /[+\-][0-9][0-9][0-9][0-9]/;
53         zone = letterZone | numZone;
54         dayNum = /[0-9 ][0-9]/;
56         # These are the different formats of the date minus an obscure
57         # type that has a funny string 'remote from xxx' on the end. Taken
58         # from c-client in the imap-2000 distribution.
59         date = day . ' ' . month . ' ' . dayNum . ' ' . time . ' ' .
60                 ( year | year . ' ' . zone | zone . ' ' . year );
62         # Note the priority assignment on the end of the from line. While we
63         # matching the body of a message we may enter into this machine. We will
64         # not leave the body of the previous message until this entire from line is
65         # matched. 
66         fromLine = 'From ' . /[^\n]/* . ' ' . date . '\n' @(new_msg,1) @msgstart;
68         # The types of characters that can be used as a header name.
69         hchar = print - [ :];
71         header =
72                 # The name of the header.
73                 hchar+ $bufHeadName . ':' 
74                 # The content of the header. Look out for continuations.
75                 . ( (extend - '\n') $bufHeadContent | '\n'. [ \t] @bufHeadContent )*
76                 # Buffer must end with a newline that does not continue.
77                 . '\n' %finBufHeadContent;
79         messageLine = ( extend - '\n' )* . '\n' @(new_msg, 0);
81         # When we get to the last newline we are still matching messageLine
82         # so on the last newline it will think we are still in the message.
83         # We need this because we can't assume that every newline means
84         # the end of the current message, whereas at the same time we requre
85         # that there be a newline before the fromLine of the next message.
86         message = ( fromLine .  header* .  '\n' @blankLine .  messageLine* . '\n' );
88         # Its important that the priority in the fromLine gets bumped up
89         # so that we are able to move to new messages. Otherwise we
90         # will always stay in the message body of the first message.
91         main := message*;
92 }%%
94 %% write data;
96 void MBox::init( )
98         MBox *fsm = this;
99         %% write init;
102 void MBox::execute( const char *data, int len )
104         MBox *fsm = this;
105         const char *p = data;
106         const char *pe = data + len;
107         %%{
108                 access fsm->;
109                 write exec;
110         }%%
113 int MBox::finish( )
115         if ( cs == MBox_error )
116                 return -1;
117         if ( cs >= MBox_first_final )
118                 return 1;
119         return 0;
122 MBox mbox;
124 void test( const char *buf )
126         int len = strlen( buf );
127         mbox.init();
128         mbox.execute( buf, len );
129         if ( mbox.finish() > 0 )
130                 printf("ACCEPT\n");
131         else
132                 printf("FAIL\n");
136 int main()
138         test(
139                 "From email address goes here Wed Nov 28 13:30:05 2001 -0500\n"
140                 "Header1: this is the header contents\n"
141                 " there is more on the second line\n"
142                 "       and more on the third line.\n"
143                 "Header2: slkdj\n"
144                 "\n"
145                 "This is the message data\n"
146                 "\n"
147                 "From email Wed Nov 28 13:30:05 2001 -0500\n"
148                 "Header: \n"
149                 "\n"
150                 "mail message\n"
151                 "\n"
152         );
154         test(
155                 "From user@host.dom Wed Nov 28 13:30:05 2001\n"
156                 "\n"
157                 "There are no headers. \n"
158                 "\n"
159                 "From email Wed Nov 28 13:30:05 EST 2000\n"
160                 "\n"
161                 "There are no headers.\n"
162                 "\n"
163         );
165         test(
166                 "From user@host.dom Wed Nov 28 13:30:05 2001\n"
167                 "Header:alsdj\n"
168                 "\n"
169                 "Header:\n"
170                 "salkfj\n"
171                 "\n"
172                 "There are no headers. \n"
173                 "\n"
174         );
176         test(
177                 "From user@host.dom Wed Nov 28 13:30:05 2001\n"
178                 "Header:alsdj\n"
179                 "\n"
180                 "Header:\n"
181                 "salkfj\n"
182                 "\n"
183                 "There are no headers. \n"
184                 "\n"
185                 ">From user@host.dom Wed Nov 28 13:30:05 2001\n"
186                 "\n"
187         );
189         test(
190                 "From user@host.dom Wed Nov 28 13:30:05 2001\n"
191                 "Header:alsdj\n"
192                 "\n"
193                 "Header:\n"
194                 "salkfj\n"
195                 "\n"
196                 "There are no headers. \n"
197                 "\n"
198                 "From user@host.dom Wed Nov 28 13:30:05 2001\n"
199                 "\n"
200         );
202         test(
203                 "From user@host.dom Wed Nov 28 13:30:05 2001\n"
204                 "Header:alsdj\n"
205                 "\n"
206                 "Header:\n"
207                 "salkfj\n"
208                 "\n"
209                 "There are no headers. \n"
210                 "\n"
211                 "From user@host.dom Wed Nov 28 13:30:05 2001\n"
212                 "\n"
213                 "\n"
214         );
216         return 0;
219 #ifdef _____OUTPUT_____
220 NEW MESSAGE
221 Header1: this is the header contents there is more on the second line   and more on the third line.
222 Header2: slkdj
224 NEW MESSAGE
225 Header: 
227 ACCEPT
228 NEW MESSAGE
230 NEW MESSAGE
232 ACCEPT
233 NEW MESSAGE
234 Header:alsdj
236 ACCEPT
237 NEW MESSAGE
238 Header:alsdj
240 ACCEPT
241 NEW MESSAGE
242 Header:alsdj
244 NEW MESSAGE
246 FAIL
247 NEW MESSAGE
248 Header:alsdj
250 NEW MESSAGE
252 ACCEPT
253 #endif