send-email: extract email-parsing code into a subroutine

The existing code mixes parsing of email header with regular expression and actual code. Extract the parsing code into a new subroutine "parse_header_line()". This improves the code readability and make parse_header_line reusable in other place. "parsed_header_line()" and "filter_body()" could be used for refactoring the part of code which parses the header to prepare the email and send it. In contrast to the previous version it doesn't keep the header order and strip duplicate headers. Signed-off-by: Nathan Payre <nathan.payre@etu.univ-lyon1.fr> Signed-off-by: Matthieu Moy <matthieu.moy@univ-lyon1.fr> Signed-off-by: Timothee Albertin <timothee.albertin@etu.univ-lyon1.fr> Signed-off-by: Daniel Bensoussan <daniel.bensoussan--bohm@etu.univ-lyon1.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com> Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Reviewed-by: Matthieu Moy <matthieu.moy@univ-lyon1.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nathan Payre committed Dec 15, 2017 at 16:33 UTC b6049542b97e7b135e0e82bf996084d461224d32
1 file changed +77 -38
git-send-email.perl
+77 -38
@@ -703,57 +703,70 @@ EOT3
703 do_edit($compose_filename);
704 }
705
706 - open my $c2, ">", $compose_filename . ".final"
707 - or die sprintf(__("Failed to open %s.final: %s"), $compose_filename, $!);
708 -
706 open $c, "<", $compose_filename
707 or die sprintf(__("Failed to open %s: %s"), $compose_filename, $!);
708
712 - my $need_8bit_cte = file_has_nonascii($compose_filename);
713 - my $in_body = 0;
714 - my $summary_empty = 1;
709 if (!defined $compose_encoding) {
710 $compose_encoding = "UTF-8";
711 }
718 - while(<$c>) {
719 - next if m/^GIT:/;
720 - if ($in_body) {
721 - $summary_empty = 0 unless (/^\n$/);
722 - } elsif (/^\n$/) {
723 - $in_body = 1;
724 - if ($need_8bit_cte) {
725 - print $c2 "MIME-Version: 1.0\n",
726 - "Content-Type: text/plain; ",
727 - "charset=$compose_encoding\n",
728 - "Content-Transfer-Encoding: 8bit\n";
729 - }
730 - } elsif (/^MIME-Version:/i) {
731 - $need_8bit_cte = 0;
732 - } elsif (/^Subject:\s*(.+)\s*$/i) {
733 - $initial_subject = $1;
734 - my $subject = $initial_subject;
735 - $_ = "Subject: " .
736 - quote_subject($subject, $compose_encoding) .
737 - "\n";
738 - } elsif (/^In-Reply-To:\s*(.+)\s*$/i) {
739 - $initial_reply_to = $1;
740 - next;
741 - } elsif (/^From:\s*(.+)\s*$/i) {
742 - $sender = $1;
743 - next;
744 - } elsif (/^(?:To|Cc|Bcc):/i) {
745 - print __("To/Cc/Bcc fields are not interpreted yet, they have been ignored\n");
746 - next;
712 +
713 + my %parsed_email;
714 + while (my $line = <$c>) {
715 + next if $line =~ m/^GIT:/;
716 + parse_header_line($line, \%parsed_email);
717 + if ($line =~ /^$/) {
718 + $parsed_email{'body'} = filter_body($c);
719 }
748 - print $c2 $_;
720 }
721 close $c;
751 - close $c2;
722
753 - if ($summary_empty) {
723 + open my $c2, ">", $compose_filename . ".final"
724 + or die sprintf(__("Failed to open %s.final: %s"), $compose_filename, $!);
725 +
726 +
727 + if ($parsed_email{'From'}) {
728 + $sender = delete($parsed_email{'From'});
729 + }
730 + if ($parsed_email{'In-Reply-To'}) {
731 + $initial_reply_to = delete($parsed_email{'In-Reply-To'});
732 + }
733 + if ($parsed_email{'Subject'}) {
734 + $initial_subject = delete($parsed_email{'Subject'});
735 + print $c2 "Subject: " .
736 + quote_subject($initial_subject, $compose_encoding) .
737 + "\n";
738 + }
739 +
740 + if ($parsed_email{'MIME-Version'}) {
741 + print $c2 "MIME-Version: $parsed_email{'MIME-Version'}\n",
742 + "Content-Type: $parsed_email{'Content-Type'};\n",
743 + "Content-Transfer-Encoding: $parsed_email{'Content-Transfer-Encoding'}\n";
744 + delete($parsed_email{'MIME-Version'});
745 + delete($parsed_email{'Content-Type'});
746 + delete($parsed_email{'Content-Transfer-Encoding'});
747 + } elsif (file_has_nonascii($compose_filename)) {
748 + my $content_type = (delete($parsed_email{'Content-Type'}) or
749 + "text/plain; charset=$compose_encoding");
750 + print $c2 "MIME-Version: 1.0\n",
751 + "Content-Type: $content_type\n",
752 + "Content-Transfer-Encoding: 8bit\n";
753 + }
754 + # Preserve unknown headers
755 + foreach my $key (keys %parsed_email) {
756 + next if $key eq 'body';
757 + print $c2 "$key: $parsed_email{$key}";
758 + }
759 +
760 + if ($parsed_email{'body'}) {
761 + print $c2 "\n$parsed_email{'body'}\n";
762 + delete($parsed_email{'body'});
763 + } else {
764 print __("Summary email is empty, skipping it\n");
765 $compose = -1;
766 }
767 +
768 + close $c2;
769 +
770 } elsif ($annotate) {
771 do_edit(@files);
772 }
@@ -792,6 +805,32 @@ sub ask {
805 return;
806 }
807
808 +sub parse_header_line {
809 + my $lines = shift;
810 + my $parsed_line = shift;
811 + my $addr_pat = join "|", qw(To Cc Bcc);
812 +
813 + foreach (split(/\n/, $lines)) {
814 + if (/^($addr_pat):\s*(.+)$/i) {
815 + $parsed_line->{$1} = [ parse_address_line($2) ];
816 + } elsif (/^([^:]*):\s*(.+)\s*$/i) {
817 + $parsed_line->{$1} = $2;
818 + }
819 + }
820 +}
821 +
822 +sub filter_body {
823 + my $c = shift;
824 + my $body = "";
825 + while (my $body_line = <$c>) {
826 + if ($body_line !~ m/^GIT:/) {
827 + $body .= $body_line;
828 + }
829 + }
830 + return $body;
831 +}
832 +
833 +
834 my %broken_encoding;
835
836 sub file_declares_8bit_cte {