Skip to content

Commit

Permalink
Merge pull request #495 from sisimai/reduce-regexp-7e75
Browse files Browse the repository at this point in the history
Reduce Regular Expressions 7e75
  • Loading branch information
azumakuniyuki committed May 16, 2023
2 parents 92b4dd1 + 9eb4336 commit 27445ca
Show file tree
Hide file tree
Showing 25 changed files with 247 additions and 317 deletions.
86 changes: 4 additions & 82 deletions lib/Sisimai/DateTime.pm
Original file line number Diff line number Diff line change
Expand Up @@ -148,59 +148,6 @@ use constant TimeZones => {
#'YEKT' => '+0500', # Yekaterinburg Time UTC+05:00
};

sub to_second {
# Convert to second
# @param [String] value Digit and a unit of time
# @return [Integer] n: seconds
# 0: 0 or invalid unit of time
# @example Get the value of seconds
# to_second('1d') #=> 86400
# to_second('2h') #=> 7200
my $class = shift;
my $value = shift || return 0;

state $timeunit = {
'o' => ( BASE_D * BASE_Y * 4 ), # Olympiad, 4 years
'y' => ( BASE_D * BASE_Y ), # Year, Gregorian Calendar
'q' => ( BASE_D * BASE_Y / 4 ), # Quarter, year/4
'l' => ( BASE_D * BASE_L ), # Lunar month
'f' => ( BASE_D * 14 ), # Fortnight, 2 weeks
'w' => ( BASE_D * 7 ), # Week, 604800 seconds
'd' => BASE_D, # Day
'h' => 3600, # Hour
'b' => 86.4, # Beat, Swatch internet time: 1000b = 1d
'm' => 60, # Minute,
's' => 1, # Second
};
state $mathematicalconstant = {
'e' => CONST_E,
'p' => CONST_P,
'g' => CONST_E ** CONST_P,
};

my $getseconds = 0;
my $unitoftime = [keys %$timeunit];
my $mathconsts = [keys %$mathematicalconstant];

if( $value =~ /\A(\d+|\d+[.]\d+)([@$unitoftime])?\z/o ) {
# 1d, 1.5w
my $n = $1;
my $u = $2 // 'd';
$getseconds = $n * $timeunit->{ $u };

} elsif( $value =~ /\A(\d+|\d+[.]\d+)?([@$mathconsts])([@$unitoftime])?\z/o ) {
# 1pd, 1.5pw
my $n = $1 // 1;
my $m = $mathematicalconstant->{ $2 } // 0;
my $u = $3 // 'd';
$getseconds = $n * $m * $timeunit->{ $u };

} else {
$getseconds = 0;
}
return $getseconds;
}

sub monthname {
# Month name list
# @param [Integer] argv1 Require full name or not
Expand All @@ -216,21 +163,6 @@ sub monthname {
return MonthName->{ $value };
}

sub dayofweek {
# List of day of week
# @param [Integer] argv1 Require full name
# @return [Array, String] List of day of week or day of week
# @example Get the names of each day of week
# dayofweek() #=> ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
# dayofweek(1) #=> ['Sunday', 'Monday', 'Tuesday', ...]
my $class = shift;
my $argv1 = shift // 0;
my $value = $argv1 ? 'full' : 'abbr';

return DayOfWeek->{ $value }->@* if wantarray;
return DayOfWeek->{ $value };
}

sub parse {
# Parse date string; strptime() wrapper
# @param [String] argv1 Date string
Expand Down Expand Up @@ -258,13 +190,12 @@ sub parse {
'z' => undef, # [Integer] Timezone offset
};


for my $p ( @timetokens ) {
# Parse each piece of time
if( $p =~ /\A[A-Z][a-z]{2,}[,]?\z/ ) {
# Day of week or Day of week; Thu, Apr, ...
$p =~ s/,\z//g if substr($p, -1, 1) eq ','; # "Thu," => "Thu"
$p = substr($p, 0, 3) if length $p > 3;
substr($p, -1, 1, '') if substr($p, -1, 1) eq ','; # "Thu," => "Thu"
$p = substr($p, 0, 3) if length $p > 3;

if( grep { $p eq $_ } DayOfWeek->{'abbr'}->@* ) {
# Day of week; Mon, Thu, Sun,...
Expand Down Expand Up @@ -309,7 +240,7 @@ sub parse {
# Time: 1:4 => 01:04:00
$v->{'T'} = sprintf("%02d:%02d:00", $1, $2);

} elsif( $p =~ /\A[APap][Mm]\z/ ) {
} elsif( lc $p eq 'am' || lc $p eq 'pm' ) {
# AM or PM
$afternoon1 = 1;

Expand Down Expand Up @@ -498,15 +429,6 @@ C<parse()> convert various date format string.
print Sisimai::DateTime->parse($x); # Fri, 9 Apr 2004 04:01:03 +0000
print Sisimai::DateTime->parse($y); # Thu, 27 Apr 2009 08:08:54 +0900
=head2 C<B<to_second(I<String>)>>
C<to_string()> convert a string to the value of seconds like followings:
print Sisimai::DateTime->to_second('1m'); # 60, 1 minute
print Sisimai::DateTime->to_second('2h'); # 7200, 2 hours
print Sisimai::DateTime->to_second('1d'); # 86400, 1 day
print Sisimai::DateTime->to_second('1w'); # 604800, 1 week
=head2 C<B<abbr2tz(I<Abbr>)>>
C<abbr2tz()> convert a time zone abbreviation to 4 digit string of time zone.
Expand All @@ -521,7 +443,7 @@ azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2022 azumakuniyuki, All rights reserved.
Copyright (C) 2014-2023 azumakuniyuki, All rights reserved.
=head1 LICENSE
Expand Down
24 changes: 14 additions & 10 deletions lib/Sisimai/Lhost/AmazonSES.pm
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,19 @@ sub inquire {
$v->{'action'} = $e->{'action'};
$v->{'status'} = $e->{'status'};

if( $e->{'diagnosticCode'} =~ /\A(.+?);[ ](.+)\z/ ) {
my $p0 = index($e->{'diagnosticCode'}, '; ');
if( $p0 > 3 ) {
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
$v->{'spec'} = uc $1;
$v->{'diagnosis'} = $2;
$v->{'spec'} = uc substr($e->{'diagnosticCode'}, 0, $p0);
$v->{'diagnosis'} = substr($e->{'diagnosticCode'}, $p0 + 2,);

} else {
$v->{'diagnosis'} = $e->{'diagnosticCode'};
}

# 'reportingMTA' => 'dsn; a27-23.smtp-out.us-west-2.amazonses.com',
$v->{'lhost'} = $1 if $o->{'reportingMTA'} =~ /\Adsn;[ ](.+)\z/;
$p0 = index($o->{'reportingMTA'}, 'dsn; ');
$v->{'lhost'} = Sisimai::String->sweep(substr($o->{'reportingMTA'}, $p0 + 5,)) if $p0 == 0;

if( exists $bouncetype->{ $o->{'bounceType'} } &&
exists $bouncetype->{ $o->{'bounceType'} }->{ $o->{'bounceSubType'} } ) {
Expand Down Expand Up @@ -189,7 +191,7 @@ sub inquire {
# "headers":[ { ...
for my $e ( $p->{'mail'}->{'headers'}->@* ) {
# 'headers' => [ { 'name' => 'From', 'value' => 'neko@nyaan.jp' }, ... ],
next unless $e->{'name'} =~ /\A(?:From|To|Subject|Message-ID|Date)\z/;
next unless grep { $e->{'name'} eq $_ } ('From', 'To', 'Subject', 'Message-ID', 'Date');
$rfc822head->{ lc $e->{'name'} } = $e->{'value'};
}
}
Expand Down Expand Up @@ -275,8 +277,8 @@ sub inquire {
} else {
# Continued line of the value of Diagnostic-Code field
next unless index($p, 'Diagnostic-Code:') == 0;
next unless $e =~ /\A[ ]+(.+)\z/;
$v->{'diagnosis'} .= ' '.$1;
next unless index($e, ' ') == 0;
$v->{'diagnosis'} .= ' '.$e;
}
} continue {
# Save the current line for the next loop
Expand All @@ -287,7 +289,7 @@ sub inquire {
for my $e ( @$dscontents ) {
# Set default values if each value is empty.
$e->{'lhost'} ||= $permessage->{'rhost'};
$e->{ $_ } ||= $permessage->{ $_ } || '' for keys %$permessage;
$e->{ $_ } ||= $permessage->{ $_ } || '' for keys %$permessage;

$e->{'diagnosis'} =~ y/\n/ /;
$e->{'diagnosis'} = Sisimai::String->sweep($e->{'diagnosis'});
Expand All @@ -296,8 +298,10 @@ sub inquire {
# Get other D.S.N. value from the error message
# 5.1.0 - Unknown address error 550-'5.7.1 ...
my $errormessage = $e->{'diagnosis'};
$errormessage = $1 if $e->{'diagnosis'} =~ /["'](\d[.]\d[.]\d.+)['"]/;
$e->{'status'} = Sisimai::SMTP::Status->find($errormessage) || $e->{'status'};
my $p1 = index($e->{'diagnosis'}, "-'"); $p1 = index($e->{'diagnosis'}, '-"') if $p1 < 0;
my $p2 = rindex($e->{'diagnosis'}, "' "); $p2 = rindex($e->{'diagnosis'}, '" ') if $p2 < 0;
$errormessage = substr($e->{'diagnosis'}, $p1 + 2, $p2 - $p1 - 2) if $p1 > -1 && $p2 > -1;
$e->{'status'} = Sisimai::SMTP::Status->find($errormessage) || $e->{'status'};
}
$e->{'replycode'} ||= Sisimai::SMTP::Reply->find($e->{'diagnosis'}, $e->{'status'});

Expand Down
4 changes: 2 additions & 2 deletions lib/Sisimai/Lhost/Aol.pm
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ sub inquire {
} else {
# Continued line of the value of Diagnostic-Code field
next unless index($p, 'Diagnostic-Code:') == 0;
next unless $e =~ /\A[ ]+(.+)\z/;
$v->{'diagnosis'} .= ' '.$1;
next unless index($e, ' ') == 0;
$v->{'diagnosis'} .= ' '.Sisimai::String->sweep($e);
}
} continue {
# Save the current line for the next loop
Expand Down
10 changes: 4 additions & 6 deletions lib/Sisimai/Lhost/Biglobe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,20 @@ sub inquire {
#
$v = $dscontents->[-1];

if( $e =~ /\A([^ ]+[@][^ ]+)\z/ ) {
if( index($e, '@') > 1 && index($e, ' ') == -1 ) {
# ----- The following addresses had delivery problems -----
# ********@***.biglobe.ne.jp
if( $v->{'recipient'} ) {
# There are multiple recipient addresses in the message body.
push @$dscontents, __PACKAGE__->DELIVERYSTATUS;
$v = $dscontents->[-1];
}

my $r = Sisimai::Address->s3s4($1);
next unless Sisimai::Address->is_emailaddress($r);
$v->{'recipient'} = $r;
next unless Sisimai::Address->is_emailaddress($e);
$v->{'recipient'} = $e;
$recipients++;

} else {
next if $e =~ /\A[^\w]/;
next if index($e, '--') > -1;
$v->{'diagnosis'} .= $e.' ';
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Sisimai/Lhost/Courier.pm
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ sub inquire {
} else {
# Continued line of the value of Diagnostic-Code field
next unless index($p, 'Diagnostic-Code:') == 0;
next unless $e =~ /\A[ ]+(.+)\z/;
$v->{'diagnosis'} .= ' '.$1;
next unless index($e, ' ') == 0;
$v->{'diagnosis'} .= ' '.Sisimai::String->sweep($e);
}
}
} continue {
Expand Down
11 changes: 5 additions & 6 deletions lib/Sisimai/Lhost/EZweb.pm
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,17 @@ sub inquire {
# <<< 550 <******@ezweb.ne.jp>: User unknown
$v = $dscontents->[-1];

if( $e =~ /\A[<]([^ ]+[@][^ ]+)[>]\z/ ||
$e =~ /\A[<]([^ ]+[@][^ ]+)[>]:?(.*)\z/ ||
$e =~ /\A[ ]+Recipient: [<]([^ ]+[@][^ ]+)[>]/ ) {
if( Sisimai::String->aligned(\$e, ['<', '@', '>']) && (index($e, 'Recipient: <') > 1 || index($e, '<') == 0) ) {
# Recipient: <******@ezweb.ne.jp> OR <***@ezweb.ne.jp>: 550 user unknown ...
my $p1 = index($e, '<');
my $p2 = index($e, '>');

if( $v->{'recipient'} ) {
# There are multiple recipient addresses in the message body.
push @$dscontents, __PACKAGE__->DELIVERYSTATUS;
$v = $dscontents->[-1];
}

my $r = Sisimai::Address->s3s4($1);
$v->{'recipient'} = $r;
$v->{'recipient'} = Sisimai::Address->s3s4(substr($e, $p1, $p2 - $p1));
$recipients++;

} elsif( my $f = Sisimai::RFC1894->match($e) ) {
Expand Down
7 changes: 5 additions & 2 deletions lib/Sisimai/Lhost/EinsUndEins.pm
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,14 @@ sub inquire {
for my $e ( @$dscontents ) {
$e->{'diagnosis'} ||= $e->{'alterrors'} || '';

if( $e->{'diagnosis'} =~ /host:[ ]+(.+?)[ ]+.+[ ]+reason:.+/ ) {
if( Sisimai::String->aligned(\$e->{'diagnosis'}, ['host: ', ' reason:']) ) {
# SMTP error from remote server for TEXT command,
# host: smtp-in.orange.fr (193.252.22.65)
# reason: 550 5.2.0 Mail rejete. Mail rejected. ofr_506 [506]
$e->{'rhost'} = $1;
my $p1 = index($e->{'diagnosis'}, 'host: ');
my $p2 = index($e->{'diagnosis'}, ' reason:');

$e->{'rhost'} = Sisimai::String->sweep(substr($e->{'diagnosis'}, $p1 + 6, $p2 - $p1 - 6));
$e->{'command'} = 'DATA' if index($e->{'diagnosis'}, 'for TEXT command') > -1;
$e->{'spec'} = 'SMTP' if index($e->{'diagnosis'}, 'SMTP error') > -1;
$e->{'status'} = Sisimai::SMTP::Status->find($e->{'diagnosis'});
Expand Down
8 changes: 5 additions & 3 deletions lib/Sisimai/Lhost/Exchange2003.pm
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,18 @@ sub inquire {
# MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
$v = $dscontents->[-1];

if( $e =~ /\A[ ]*([^ ]+[@][^ ]+) on[ ]*.*\z/ ||
$e =~ /\A[ ]*.+(?:SMTP|smtp)=([^ ]+[@][^ ]+) on[ ]*.*\z/ ) {
if( Sisimai::String->aligned(\$e, ['@', ' on ']) ) {
# kijitora@example.co.jp on Thu, 29 Apr 2007 16:51:51 -0500
# kijitora@example.com on 4/29/99 9:19:59 AM
if( $v->{'recipient'} ) {
# There are multiple recipient addresses in the message body.
push @$dscontents, __PACKAGE__->DELIVERYSTATUS;
$v = $dscontents->[-1];
}
$v->{'recipient'} = $1;

my $p1 = index(lc $e, 'smtp='); $p1 = $p1 == -1 ? 0 : $p1 + 5;
my $p2 = index($e, ' on ') + 1;
$v->{'recipient'} = Sisimai::Address->s3s4(substr($e, $p1, $p2));
$v->{'msexch'} = 0;
$recipients++;

Expand Down
30 changes: 17 additions & 13 deletions lib/Sisimai/Lhost/Exchange2007.pm
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,24 @@ sub inquire {
$v->{'recipient'} = Sisimai::Address->s3s4($e);
$recipients++;

} elsif( $e =~ /([45]\d{2})[ ]([45][.]\d[.]\d+)?[ ]?.+\z/ ) {
# #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
# #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##
# Remote Server returned '550 5.1.1 RESOLVER.ADR.RecipNotFound; not found'
# 3/09/2016 8:05:56 PM - Remote Server at mydomain.com (10.1.1.3) returned '550 4.4.7 QUEUE.Expired; message expired'
$v->{'replycode'} = int $1;
$v->{'status'} = $2;
$v->{'diagnosis'} = $e;

} else {
# Continued line of error messages
next unless $v->{'diagnosis'};
next unless substr($v->{'diagnosis'}, -1, 1) eq '=';
substr($v->{'diagnosis'}, -1, 1, $e);
my $cr = Sisimai::SMTP::Reply->find($e) || '';
my $cs = Sisimai::SMTP::Status->find($e) || '';
if( $cr || $cs ) {
# #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
# #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##
# Remote Server returned '550 5.1.1 RESOLVER.ADR.RecipNotFound; not found'
# 3/09/2016 8:05:56 PM - Remote Server at mydomain.com (10.1.1.3) returned '550 4.4.7 QUEUE.Expired; message expired'
$v->{'replycode'} = $cr;
$v->{'status'} = $cs;
$v->{'diagnosis'} = $e;

} else {
# Continued line of error messages
next unless $v->{'diagnosis'};
next unless substr($v->{'diagnosis'}, -1, 1) eq '=';
substr($v->{'diagnosis'}, -1, 1, $e);
}
}
} else {
# Diagnostic information for administrators:
Expand Down
Loading

0 comments on commit 27445ca

Please sign in to comment.