From 2a51c8682d44ee71a3c0411e2e30ef8ff29d6f67 Mon Sep 17 00:00:00 2001 From: Rick Olson Date: Tue, 6 Nov 2007 14:24:32 +0000 Subject: Update TMail to v1.1.0. Use an updated version of TMail if available. [mikel] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8084 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/action_mailer/vendor/tmail/parser.y | 381 +++++++++++++++++++++ 1 file changed, 381 insertions(+) create mode 100644 actionmailer/lib/action_mailer/vendor/tmail/parser.y (limited to 'actionmailer/lib/action_mailer/vendor/tmail/parser.y') diff --git a/actionmailer/lib/action_mailer/vendor/tmail/parser.y b/actionmailer/lib/action_mailer/vendor/tmail/parser.y new file mode 100644 index 0000000000..77a1457794 --- /dev/null +++ b/actionmailer/lib/action_mailer/vendor/tmail/parser.y @@ -0,0 +1,381 @@ +# +# parser.y +# +# Copyright (c) 1998-2007 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the terms of +# the GNU Lesser General Public License version 2.1. +# + +class TMail::Parser + + options no_result_var + +rule + + content : DATETIME datetime { val[1] } + | RECEIVED received { val[1] } + | MADDRESS addrs_TOP { val[1] } + | RETPATH retpath { val[1] } + | KEYWORDS keys { val[1] } + | ENCRYPTED enc { val[1] } + | MIMEVERSION version { val[1] } + | CTYPE ctype { val[1] } + | CENCODING cencode { val[1] } + | CDISPOSITION cdisp { val[1] } + | ADDRESS addr_TOP { val[1] } + | MAILBOX mbox { val[1] } + + datetime : day DIGIT ATOM DIGIT hour zone + # 0 1 2 3 4 5 + # date month year + { + t = Time.gm(val[3].to_i, val[2], val[1].to_i, 0, 0, 0) + (t + val[4] - val[5]).localtime + } + + day : /* none */ + | ATOM ',' + + hour : DIGIT ':' DIGIT + { + (val[0].to_i * 60 * 60) + + (val[2].to_i * 60) + } + | DIGIT ':' DIGIT ':' DIGIT + { + (val[0].to_i * 60 * 60) + + (val[2].to_i * 60) + + (val[4].to_i) + } + + zone : ATOM + { + timezone_string_to_unixtime(val[0]) + } + + received : from by via with id for received_datetime + { + val + } + + from : /* none */ + | FROM received_domain + { + val[1] + } + + by : /* none */ + | BY received_domain + { + val[1] + } + + received_domain + : domain + { + join_domain(val[0]) + } + | domain '@' domain + { + join_domain(val[2]) + } + | domain DOMLIT + { + join_domain(val[0]) + } + + via : /* none */ + | VIA ATOM + { + val[1] + } + + with : /* none */ + { + [] + } + | with WITH ATOM + { + val[0].push val[2] + val[0] + } + + id : /* none */ + | ID msgid + { + val[1] + } + | ID ATOM + { + val[1] + } + + for : /* none */ + | FOR received_addrspec + { + val[1] + } + + received_addrspec + : routeaddr + { + val[0].spec + } + | spec + { + val[0].spec + } + + received_datetime + : /* none */ + | ';' datetime + { + val[1] + } + + addrs_TOP : addrs + | group_bare + | addrs commas group_bare + + addr_TOP : mbox + | group + | group_bare + + retpath : addrs_TOP + | '<' '>' { [ Address.new(nil, nil) ] } + + addrs : addr + { + val + } + | addrs commas addr + { + val[0].push val[2] + val[0] + } + + addr : mbox + | group + + mboxes : mbox + { + val + } + | mboxes commas mbox + { + val[0].push val[2] + val[0] + } + + mbox : spec + | routeaddr + | addr_phrase routeaddr + { + val[1].phrase = Decoder.decode(val[0]) + val[1] + } + + group : group_bare ';' + + group_bare: addr_phrase ':' mboxes + { + AddressGroup.new(val[0], val[2]) + } + | addr_phrase ':' { AddressGroup.new(val[0], []) } + + addr_phrase + : local_head { val[0].join('.') } + | addr_phrase local_head { val[0] << ' ' << val[1].join('.') } + + routeaddr : '<' routes spec '>' + { + val[2].routes.replace val[1] + val[2] + } + | '<' spec '>' + { + val[1] + } + + routes : at_domains ':' + + at_domains: '@' domain { [ val[1].join('.') ] } + | at_domains ',' '@' domain { val[0].push val[3].join('.'); val[0] } + + spec : local '@' domain { Address.new( val[0], val[2] ) } + | local { Address.new( val[0], nil ) } + + local: local_head + | local_head '.' { val[0].push ''; val[0] } + + local_head: word + { val } + | local_head dots word + { + val[1].times do + val[0].push '' + end + val[0].push val[2] + val[0] + } + + domain : domword + { val } + | domain dots domword + { + val[1].times do + val[0].push '' + end + val[0].push val[2] + val[0] + } + + dots : '.' { 0 } + | '.' '.' { 1 } + + word : atom + | QUOTED + | DIGIT + + domword : atom + | DOMLIT + | DIGIT + + commas : ',' + | commas ',' + + msgid : '<' spec '>' + { + val[1] = val[1].spec + val.join('') + } + + keys : phrase { val } + | keys ',' phrase { val[0].push val[2]; val[0] } + + phrase : word + | phrase word { val[0] << ' ' << val[1] } + + enc : word + { + val.push nil + val + } + | word word + { + val + } + + version : DIGIT '.' DIGIT + { + [ val[0].to_i, val[2].to_i ] + } + + ctype : TOKEN '/' TOKEN params opt_semicolon + { + [ val[0].downcase, val[2].downcase, decode_params(val[3]) ] + } + | TOKEN params opt_semicolon + { + [ val[0].downcase, nil, decode_params(val[1]) ] + } + + params : /* none */ + { + {} + } + | params ';' TOKEN '=' QUOTED + { + val[0][ val[2].downcase ] = ('"' + val[4].to_s + '"') + val[0] + } + | params ';' TOKEN '=' TOKEN + { + val[0][ val[2].downcase ] = val[4] + val[0] + } + + cencode : TOKEN + { + val[0].downcase + } + + cdisp : TOKEN params opt_semicolon + { + [ val[0].downcase, decode_params(val[1]) ] + } + + opt_semicolon + : + | ';' + + atom : ATOM + | FROM + | BY + | VIA + | WITH + | ID + | FOR + +end + + +---- header +# +# parser.rb +# +# Copyright (c) 1998-2007 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the terms of +# the GNU Lesser General Public License version 2.1. +# + +require 'tmail/scanner' +require 'tmail/utils' + +---- inner + + include TextUtils + + def self.parse( ident, str, cmt = nil ) + new.parse(ident, str, cmt) + end + + MAILP_DEBUG = false + + def initialize + self.debug = MAILP_DEBUG + end + + def debug=( flag ) + @yydebug = flag && Racc_debug_parser + @scanner_debug = flag + end + + def debug + @yydebug + end + + def parse( ident, str, comments = nil ) + @scanner = Scanner.new(str, ident, comments) + @scanner.debug = @scanner_debug + @first = [ident, ident] + result = yyparse(self, :parse_in) + comments.map! {|c| to_kcode(c) } if comments + result + end + + private + + def parse_in( &block ) + yield @first + @scanner.scan(&block) + end + + def on_error( t, val, vstack ) + raise SyntaxError, "parse error on token #{racc_token2str t}" + end + -- cgit v1.2.3