sh: tracing: Use the DWARF unwinder for CALLER_ADDRx
[safe/jmp/linux-2.6] / scripts / get_maintainer.pl
index 446803e..cdb44b6 100755 (executable)
@@ -30,6 +30,7 @@ my $email_git_max_maintainers = 5;
 my $email_git_min_percent = 5;
 my $email_git_since = "1-year-ago";
 my $email_git_blame = 0;
+my $email_remove_duplicates = 1;
 my $output_multiline = 1;
 my $output_separator = ", ";
 my $scm = 0;
@@ -71,6 +72,7 @@ if (!GetOptions(
                'git-min-percent=i' => \$email_git_min_percent,
                'git-since=s' => \$email_git_since,
                'git-blame!' => \$email_git_blame,
+               'remove-duplicates!' => \$email_remove_duplicates,
                'm!' => \$email_maintainer,
                'n!' => \$email_usename,
                'l!' => \$email_list,
@@ -158,32 +160,28 @@ close(MAINT);
 
 my %mailmap;
 
-open(MAILMAP, "<${lk_path}.mailmap") || warn "$P: Can't open .mailmap\n";
-while (<MAILMAP>) {
-    my $line = $_;
-
-    next if ($line =~ m/^\s*#/);
-    next if ($line =~ m/^\s*$/);
+if ($email_remove_duplicates) {
+    open(MAILMAP, "<${lk_path}.mailmap") || warn "$P: Can't open .mailmap\n";
+    while (<MAILMAP>) {
+       my $line = $_;
 
-    my ($name, $address) = parse_email($line);
-    $line = format_email($name, $address);
+       next if ($line =~ m/^\s*#/);
+       next if ($line =~ m/^\s*$/);
 
-    next if ($line =~ m/^\s*$/);
+       my ($name, $address) = parse_email($line);
+       $line = format_email($name, $address);
 
-    if (exists($mailmap{$name})) {
-       my $obj = $mailmap{$name};
-       push(@$obj, $address);
-    } else {
-       my @arr = ($address);
-       $mailmap{$name} = \@arr;
-    }
-}
-close(MAILMAP);
+       next if ($line =~ m/^\s*$/);
 
-foreach my $name (sort {$mailmap{$a} <=> $mailmap{$b}} keys %mailmap) {
-    my $obj = $mailmap{$name};
-    foreach my $address (@$obj) {
+       if (exists($mailmap{$name})) {
+           my $obj = $mailmap{$name};
+           push(@$obj, $address);
+       } else {
+           my @arr = ($address);
+           $mailmap{$name} = \@arr;
+       }
     }
+    close(MAILMAP);
 }
 
 ## use the filenames on the command line or find the filenames in the patchfiles
@@ -315,22 +313,22 @@ if ($email || $email_list) {
 }
 
 if ($scm) {
-    @scm = sort_and_uniq(@scm);
+    @scm = uniq(@scm);
     output(@scm);
 }
 
 if ($status) {
-    @status = sort_and_uniq(@status);
+    @status = uniq(@status);
     output(@status);
 }
 
 if ($subsystem) {
-    @subsystem = sort_and_uniq(@subsystem);
+    @subsystem = uniq(@subsystem);
     output(@subsystem);
 }
 
 if ($web) {
-    @web = sort_and_uniq(@web);
+    @web = uniq(@web);
     output(@web);
 }
 
@@ -373,6 +371,7 @@ MAINTAINER field selection options:
     --n => include name 'Full Name <addr\@domain.tld>'
     --l => include list(s) if any
     --s => include subscriber only list(s) if any
+    --remove-duplicates => minimize duplicate email names/addresses
   --scm => print SCM tree(s) if any
   --status => print status if any
   --subsystem => print subsystem name if any
@@ -389,7 +388,7 @@ Other options:
   --help => show this help information
 
 Default options:
-  [--email --git --m --n --l --multiline --pattern-depth=0]
+  [--email --git --m --n --l --multiline --pattern-depth=0 --remove-duplicates]
 
 Notes:
   Using "-f directory" may give unexpected results:
@@ -438,12 +437,12 @@ sub parse_email {
     my $name = "";
     my $address = "";
 
-    if ($formatted_email =~ /^([^<]+)<(.*\@.*)>.*$/) {
+    if ($formatted_email =~ /^([^<]+)<(.+\@.*)>.*$/) {
        $name = $1;
        $address = $2;
-    } elsif ($formatted_email =~ /^\s*<(.*\@.*)>.*$/) {
+    } elsif ($formatted_email =~ /^\s*<(.+\@\S*)>.*$/) {
        $address = $1;
-    } elsif ($formatted_email =~ /^\s*(.*\@.*)$/) {
+    } elsif ($formatted_email =~ /^(.+\@\S*).*$/) {
        $address = $1;
     }
 
@@ -486,12 +485,46 @@ sub format_email {
     return $formatted_email;
 }
 
-sub add_categories {
+sub find_starting_index {
+
     my ($index) = @_;
 
-    $index = $index - 1;
-    while ($index >= 0) {
+    while ($index > 0) {
        my $tv = $typevalue[$index];
+       if (!($tv =~ m/^(\C):\s*(.*)/)) {
+           last;
+       }
+       $index--;
+    }
+
+    return $index;
+}
+
+sub find_ending_index {
+    my ($index) = @_;
+
+    while ($index < @typevalue) {
+       my $tv = $typevalue[$index];
+       if (!($tv =~ m/^(\C):\s*(.*)/)) {
+           last;
+       }
+       $index++;
+    }
+
+    return $index;
+}
+
+sub add_categories {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    push(@subsystem, $typevalue[$start]);
+
+    for ($i = $start + 1; $i < $end; $i++) {
+       my $tv = $typevalue[$i];
        if ($tv =~ m/^(\C):\s*(.*)/) {
            my $ptype = $1;
            my $pvalue = $2;
@@ -514,11 +547,12 @@ sub add_categories {
            } elsif ($ptype eq "M") {
                my ($name, $address) = parse_email($pvalue);
                if ($name eq "") {
-                   if ($index >= 0) {
-                       my $tv = $typevalue[$index - 1];
+                   if ($i > 0) {
+                       my $tv = $typevalue[$i - 1];
                        if ($tv =~ m/^(\C):\s*(.*)/) {
                            if ($1 eq "P") {
                                $name = $2;
+                               $pvalue = format_email($name, $address);
                            }
                        }
                    }
@@ -533,23 +567,20 @@ sub add_categories {
            } elsif ($ptype eq "S") {
                push(@status, $pvalue);
            }
-
-           $index--;
-       } else {
-           push(@subsystem,$tv);
-           $index = -1;
        }
     }
 }
 
-sub email_address_inuse {
-    my ($test_address) = @_;
+my %email_hash_name;
+my %email_hash_address;
 
-    foreach my $line (@email_to) {
-       my ($name, $address) = parse_email($line);
+sub email_inuse {
+    my ($name, $address) = @_;
+
+    return 1 if (($name eq "") && ($address eq ""));
+    return 1 if (($name ne "") && exists($email_hash_name{$name}));
+    return 1 if (($address ne "") && exists($email_hash_address{$address}));
 
-       return 1 if ($address eq $test_address);
-    }
     return 0;
 }
 
@@ -558,9 +589,19 @@ sub push_email_address {
 
     my ($name, $address) = parse_email($line);
 
-    if (!email_address_inuse($address)) {
+    if ($address eq "") {
+       return 0;
+    }
+
+    if (!$email_remove_duplicates) {
+       push(@email_to, format_email($name, $address));
+    } elsif (!email_inuse($name, $address)) {
        push(@email_to, format_email($name, $address));
+       $email_hash_name{$name}++;
+       $email_hash_address{$address}++;
     }
+
+    return 1;
 }
 
 sub push_email_addresses {
@@ -576,7 +617,9 @@ sub push_email_addresses {
            push_email_address($entry);
        }
     } else {
-       warn("Invalid MAINTAINERS address: '" . $address . "'\n");
+       if (!push_email_address($address)) {
+           warn("Invalid MAINTAINERS address: '" . $address . "'\n");
+       }
     }
 }
 
@@ -600,6 +643,9 @@ sub mailmap {
        my ($name, $address) = parse_email($line);
        if (!exists($hash{$name})) {
            $hash{$name} = $address;
+       } elsif ($address ne $hash{$name}) {
+           $address = $hash{$name};
+           $line = format_email($name, $address);
        }
        if (exists($mailmap{$name})) {
            my $obj = $mailmap{$name};
@@ -652,31 +698,23 @@ sub recent_git_signoffs {
 
     $total_sign_offs = @lines;
 
-    @lines = mailmap(@lines);
+    if ($email_remove_duplicates) {
+       @lines = mailmap(@lines);
+    }
 
     @lines = sort(@lines);
+
     # uniq -c
-    foreach my $line (@lines) {
-       $hash{$line}++;
-    }
+    $hash{$_}++ for @lines;
+
     # sort -rn
-    @lines = ();
     foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
-       push(@lines,"$hash{$line}       $line");
-    }
-
-    foreach my $line (@lines) {
-       if ($line =~ m/([0-9]+)\s+(.*)/) {
-           my $sign_offs = $1;
-           $line = $2;
-           $count++;
-           if ($sign_offs < $email_git_min_signatures ||
-               $count > $email_git_max_maintainers ||
-               $sign_offs * 100 / $total_sign_offs < $email_git_min_percent) {
-               last;
-           }
-           push_email_address($line);
-       }
+       my $sign_offs = $hash{$line};
+       $count++;
+       last if ($sign_offs < $email_git_min_signatures ||
+                $count > $email_git_max_maintainers ||
+                $sign_offs * 100 / $total_sign_offs < $email_git_min_percent);
+       push_email_address($line);
     }
 }
 
@@ -743,7 +781,9 @@ sub git_assign_blame {
 
        $total_sign_offs += @lines;
 
-       @lines = mailmap(@lines);
+       if ($email_remove_duplicates) {
+           @lines = mailmap(@lines);
+       }
 
        $hash{$_}++ for @lines;
     }