summaryrefslogtreecommitdiff
path: root/examples/mailbox.rl
diff options
context:
space:
mode:
Diffstat (limited to 'examples/mailbox.rl')
-rw-r--r--examples/mailbox.rl207
1 files changed, 0 insertions, 207 deletions
diff --git a/examples/mailbox.rl b/examples/mailbox.rl
deleted file mode 100644
index 94590fdd..00000000
--- a/examples/mailbox.rl
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Parses unix mail boxes into headers and bodies.
- */
-
-#include <iostream>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-using namespace std;
-
-#define BUFSIZE 2048
-
-/* A growable buffer for collecting headers. */
-struct Buffer
-{
- Buffer() : data(0), allocated(0), length(0) { }
- ~Buffer() { empty(); }
-
- void append( char p ) {
- if ( ++length > allocated )
- upAllocate( length*2 );
- data[length-1] = p;
- }
-
- void clear() { length = 0; }
- void upAllocate( int len );
- void empty();
-
- char *data;
- int allocated;
- int length;
-};
-
-
-struct MailboxScanner
-{
- Buffer headName;
- Buffer headContent;
-
- int cs, top, stack[1];
-
- int init( );
- int execute( const char *data, int len, bool isEof );
- int finish( );
-};
-
-%%{
- machine MailboxScanner;
-
- # Buffer the header names.
- action bufHeadName { headName.append(fc); }
-
- # Prints a blank line after the end of the headers of each message.
- action blankLine { cout << endl; }
-
- # Helpers we will use in matching the date section of the from line.
- day = /[A-Z][a-z][a-z]/;
- month = /[A-Z][a-z][a-z]/;
- year = /[0-9][0-9][0-9][0-9]/;
- time = /[0-9][0-9]:[0-9][0-9]/ . ( /:[0-9][0-9]/ | '' );
- letterZone = /[A-Z][A-Z][A-Z]/;
- numZone = /[+\-][0-9][0-9][0-9][0-9]/;
- zone = letterZone | numZone;
- dayNum = /[0-9 ][0-9]/;
-
- # These are the different formats of the date minus an obscure
- # type that has a funny string 'remote from xxx' on the end. Taken
- # from c-client in the imap-2000 distribution.
- date = day . ' ' . month . ' ' . dayNum . ' ' . time . ' ' .
- ( year | year . ' ' . zone | zone . ' ' . year );
-
- # From lines separate messages. We will exclude fromLine from a message
- # body line. This will cause us to stay in message line up until an
- # entirely correct from line is matched.
- fromLine = 'From ' . (any-'\n')* . ' ' . date . '\n';
-
- # The types of characters that can be used as a header name.
- hchar = print - [ :];
-
- # Simply eat up an uninteresting header. Return at the first non-ws
- # character following a newline.
- consumeHeader := (
- [^\n] |
- '\n' [ \t] |
- '\n' [^ \t] @{fhold; fret;}
- )*;
-
- action hchar {headContent.append(fc);}
- action hspace {headContent.append(' ');}
-
- action hfinish {
- headContent.append(0);
- cout << headContent.data << endl;
- headContent.clear();
- fhold;
- fret;
- }
-
- # Display the contents of a header as it is consumed. Collapses line
- # continuations to a single space.
- printHeader := (
- [^\n] @hchar |
- ( '\n' ( [ \t]+ '\n' )* [ \t]+ ) %hspace
- )** $!hfinish;
-
- action onHeader
- {
- headName.append(0);
- if ( strcmp( headName.data, "From" ) == 0 ||
- strcmp( headName.data, "To" ) == 0 ||
- strcmp( headName.data, "Subject" ) == 0 )
- {
- /* Print the header name, then jump to a machine the will display
- * the contents. */
- cout << headName.data << ":";
- headName.clear();
- fcall printHeader;
- }
-
- headName.clear();
- fcall consumeHeader;
- }
-
- header = hchar+ $bufHeadName ':' @onHeader;
-
- # Exclude fromLine from a messageLine, otherwise when encountering a
- # fromLine we will be simultaneously matching the old message and a new
- # message.
- messageLine = ( [^\n]* '\n' - fromLine );
-
- # An entire message.
- message = ( fromLine . header* . '\n' @blankLine . messageLine* );
-
- # File is a series of messages.
- main := message*;
-}%%
-
-%% write data;
-
-int MailboxScanner::init( )
-{
- %% write init;
- return 1;
-}
-
-int MailboxScanner::execute( const char *data, int len, bool isEof )
-{
- const char *p = data;
- const char *pe = data + len;
- const char *eof = isEof ? pe : 0;
-
- %% write exec;
-
- if ( cs == MailboxScanner_error )
- return -1;
- if ( cs >= MailboxScanner_first_final )
- return 1;
- return 0;
-}
-
-int MailboxScanner::finish( )
-{
- if ( cs == MailboxScanner_error )
- return -1;
- if ( cs >= MailboxScanner_first_final )
- return 1;
- return 0;
-}
-
-
-void Buffer::empty()
-{
- if ( data != 0 ) {
- free( data );
-
- data = 0;
- length = 0;
- allocated = 0;
- }
-}
-
-void Buffer::upAllocate( int len )
-{
- if ( data == 0 )
- data = (char*) malloc( len );
- else
- data = (char*) realloc( data, len );
- allocated = len;
-}
-
-MailboxScanner mailbox;
-char buf[BUFSIZE];
-
-int main()
-{
- mailbox.init();
- while ( 1 ) {
- int len = fread( buf, 1, BUFSIZE, stdin );
- mailbox.execute( buf, len, len != BUFSIZE );
- if ( len != BUFSIZE )
- break;
- }
- if ( mailbox.finish() <= 0 )
- cerr << "mailbox: error parsing input" << endl;
- return 0;
-}