blob: ab636e8a69770d8bb8a01f121808e1970018a2de [file] [log] [blame]
Reid Spencer8dd91272005-05-16 18:30:38 +00001#!/usr/bin/perl -w
2#
3# Program: userloc.pl
4#
5# Synopsis: This program uses "cvs annotate" to get a summary of how many lines
6# of code the various developres are responsible for. It takes one
7# argument, the directory to process. If the argument is not specified
8# then the cwd is used. The directory must be an LLVM tree checked out
9# from cvs.
10#
Reid Spencer092ae902006-08-11 18:36:55 +000011# Syntax: userloc.pl [-recurse|-tag=tag|-html... <directory>...
Reid Spencer8dd91272005-05-16 18:30:38 +000012#
13# Options:
Reid Spencer8dd91272005-05-16 18:30:38 +000014# -recurse
15# Recurse through sub directories. Without this, only the
16# specified directory is examined
17# -tag=tag
18# Use "tag" to select the revision (as per cvs -r option)
19# -html
20# Generate HTML output instead of text output
21
Reid Spencer092ae902006-08-11 18:36:55 +000022die "Usage userloc.pl [-recurse|-tag=tag|-html] <directories>..."
Reid Spencer8dd91272005-05-16 18:30:38 +000023 if ($#ARGV < 0);
24
25my $tag = "";
Reid Spencer8dd91272005-05-16 18:30:38 +000026my $recurse = 0;
27my $html = 0;
Reid Spencer092ae902006-08-11 18:36:55 +000028my $debug = 0;
Reid Spencer8dd91272005-05-16 18:30:38 +000029while ( substr($ARGV[0],0,1) eq '-' )
30{
Reid Spencer092ae902006-08-11 18:36:55 +000031 if ($ARGV[0] eq "-recurse") {
Reid Spencer8dd91272005-05-16 18:30:38 +000032 $recurse = 1;
Reid Spencer092ae902006-08-11 18:36:55 +000033 } elsif ($ARGV[0] =~ /-tag=.*/) {
Reid Spencer8dd91272005-05-16 18:30:38 +000034 $tag = $ARGV[0];
35 $tag =~ s#-tag=(.*)#$1#;
Reid Spencer092ae902006-08-11 18:36:55 +000036 } elsif ($ARGV[0] eq "-html") {
Reid Spencer8dd91272005-05-16 18:30:38 +000037 $html = 1;
Reid Spencer092ae902006-08-11 18:36:55 +000038 } elsif ($ARGV[0] eq "-debug") {
39 $debug = 1;
40 } else {
Reid Spencer8dd91272005-05-16 18:30:38 +000041 die "Invalid option: $ARGV[0]";
42 }
43 shift;
44}
45
Reid Spencer092ae902006-08-11 18:36:55 +000046die "Usage userloc.pl [-recurse|-tag=tag|-html] <directories>..."
Reid Spencer8dd91272005-05-16 18:30:38 +000047 if ($#ARGV < 0);
48
49my %Stats;
50my %StatsDetails;
51
52sub ValidateFile
53{
54 my $f = $_[0];
55 my $d = $_[1];
56
Reid Spencer8dd91272005-05-16 18:30:38 +000057 if ( $d =~ ".*autoconf.*")
58 {
59 return 1 if ($f eq "configure.ac");
60 return 1 if ($f eq "AutoRegen.sh");
61 return 0;
62 }
Reid Spencer092ae902006-08-11 18:36:55 +000063 return 0 if ( "$f" eq "configure");
64 return 0 if ( "$f" eq 'PPCPerfectShuffle.h' );
65 return 0 if ( $f =~ /.*\.cvs/);
Reid Spencer8dd91272005-05-16 18:30:38 +000066 return 1;
67}
68
69sub GetCVSFiles
70{
71 my $d = $_[0];
72 my $files ="";
73 open STATUS, "cvs -nfz6 status $d -l 2>/dev/null |"
74 || die "Can't 'cvs status'";
75 while ( defined($line = <STATUS>) )
76 {
77 if ( $line =~ /^File:.*/ )
78 {
79 chomp($line);
80 $line =~ s#^File: ([A-Za-z0-9._-]*)[ \t]*Status:.*#$1#;
81 $files = "$files $d/$line" if (ValidateFile($line,$d));
82 }
83
84 }
85 return $files;
86}
87
Reid Spencer092ae902006-08-11 18:36:55 +000088my $annotate = "cvs -z6 annotate -lf ";
Reid Spencer8dd91272005-05-16 18:30:38 +000089if (length($tag) > 0)
90{
Reid Spencer092ae902006-08-11 18:36:55 +000091 $annotate = $annotate . " -r" . $tag;
Reid Spencer8dd91272005-05-16 18:30:38 +000092}
93
Reid Spencer092ae902006-08-11 18:36:55 +000094sub ScanDir
Reid Spencer8dd91272005-05-16 18:30:38 +000095{
96 my $Dir = $_[0];
97 my $files = GetCVSFiles($Dir);
98
99 open (DATA,"$annotate $files 2>/dev/null |")
100 || die "Can't read cvs annotation data";
101
Reid Spencer8dd91272005-05-16 18:30:38 +0000102 while ( defined($line = <DATA>) )
103 {
Reid Spencer092ae902006-08-11 18:36:55 +0000104 if ($line =~ /^[0-9.]*[ \t]*\([^)]*\):/)
Reid Spencer8dd91272005-05-16 18:30:38 +0000105 {
Reid Spencer8dd91272005-05-16 18:30:38 +0000106 chomp($line);
Reid Spencer092ae902006-08-11 18:36:55 +0000107 $line =~ s#^[0-9.]*[ \t]*\(([a-zA-Z0-9_.-]*) [^)]*\):.*#$1#;
Reid Spencer8dd91272005-05-16 18:30:38 +0000108 $Stats{$line}++;
109 }
110 }
111
Reid Spencer8dd91272005-05-16 18:30:38 +0000112 close DATA;
113}
114
115sub ValidateDirectory
116{
117 my $d = $_[0];
Reid Spencer092ae902006-08-11 18:36:55 +0000118 return 0 if (! -d "$d" || ! -d "$d/CVS");
Reid Spencer8dd91272005-05-16 18:30:38 +0000119 return 0 if ($d =~ /.*CVS.*/);
120 return 0 if ($d =~ /.*Debug.*/);
121 return 0 if ($d =~ /.*Release.*/);
122 return 0 if ($d =~ /.*Profile.*/);
Reid Spencer8dd91272005-05-16 18:30:38 +0000123 return 0 if ($d =~ /.*docs\/CommandGuide\/html.*/);
124 return 0 if ($d =~ /.*docs\/CommandGuide\/man.*/);
125 return 0 if ($d =~ /.*docs\/CommandGuide\/ps.*/);
126 return 0 if ($d =~ /.*docs\/CommandGuide\/man.*/);
127 return 0 if ($d =~ /.*docs\/HistoricalNotes.*/);
128 return 0 if ($d =~ /.*docs\/img.*/);
129 return 0 if ($d =~ /.*bzip2.*/);
130 return 1 if ($d =~ /.*projects\/Stacker.*/);
131 return 1 if ($d =~ /.*projects\/sample.*/);
132 return 0 if ($d =~ /.*projects\/llvm-.*/);
133 return 0 if ($d =~ /.*win32.*/);
Reid Spencer092ae902006-08-11 18:36:55 +0000134 return 0 if ($d =~ /.*\/.libs\/.*/);
Reid Spencer8dd91272005-05-16 18:30:38 +0000135 return 1;
136}
137
138my $RowCount = 0;
139sub printStats
140{
141 my $dir = $_[0];
142 my $hash = $_[1];
143 my $user;
144 my $total = 0;
145
146 if ($RowCount % 10 == 0)
147 {
Reid Spencer092ae902006-08-11 18:36:55 +0000148 if ($html) {
149 print " <tr><th style=\"text-align:left\">Directory</th>\n";
150 foreach $user (sort keys %Stats)
151 {
152 print "<th style=\"text-align:right\">",$user,"</th>\n";
153 }
154 print "</tr>\n";
Reid Spencer8dd91272005-05-16 18:30:38 +0000155 }
156 }
157
158 $RowCount++;
159
Reid Spencer8dd91272005-05-16 18:30:38 +0000160 if ($html)
161 { print "<tr><td style=\"text-align:left\">",$dir,"</td>"; }
162 else
163 { print $dir,"\n"; }
164
Reid Spencer5a685662005-05-16 18:52:57 +0000165 foreach $user (keys %{$hash}) { $total += $hash->{$user}; }
166
Reid Spencer8dd91272005-05-16 18:30:38 +0000167 foreach $user ( sort keys %Stats )
168 {
169 my $v = $hash->{$user};
170 if (defined($v))
171 {
172 if ($html)
173 {
174 printf "<td style=\"text-align:right\">%d<br/>(%2.1f%%)</td>", $v,
175 (100.0/$total)*$v;
176 }
177 else
178 {
179 printf "%8d (%4.1f%%): %s\n", $v, (100.0/$total)*$v, $user;
180 }
181 }
182 elsif ($html)
183 {
184 print "<td style=\"text-align:right\">-&nbsp;</td>";
185 }
186 }
187 print "</tr>\n" if ($html);
188}
189
190my @ALLDIRS = @ARGV;
191
192if ($recurse)
193{
194 $Dirs = join(" ", @ARGV);
195 $Dirs = `find $Dirs -type d \! -name CVS -print`;
196 @ALLDIRS = split(' ',$Dirs);
197}
198
199if ($html)
200{
201print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
202print "<html>\n<head>\n";
203print " <title>LLVM LOC Based On CVS Annotation</title>\n";
204print " <link rel=\"stylesheet\" href=\"llvm.css\" type=\"text/css\"/>\n";
205print "</head>\n";
206print "<body><div class=\"doc_title\">LLVM LOC Based On CVS Annotation</div>\n";
207print "<p>This document shows the total lines of code per user in each\n";
208print "LLVM directory. Lines of code are attributed by the user that last\n";
209print "committed the line. This does not necessarily reflect authorship.</p>\n";
Reid Spencer8dd91272005-05-16 18:30:38 +0000210}
211
Reid Spencer092ae902006-08-11 18:36:55 +0000212my @ignored_dirs;
213
Reid Spencer8dd91272005-05-16 18:30:38 +0000214for $Dir (@ALLDIRS)
215{
Reid Spencer092ae902006-08-11 18:36:55 +0000216 if ( ValidateDirectory($Dir) )
Reid Spencer8dd91272005-05-16 18:30:38 +0000217 {
218 ScanDir($Dir);
219 }
220 elsif ($html)
221 {
Reid Spencer092ae902006-08-11 18:36:55 +0000222 push @ignored_dirs, $Dir;
Reid Spencer8dd91272005-05-16 18:30:38 +0000223 }
224}
225
226if ($html)
227{
Reid Spencer8dd91272005-05-16 18:30:38 +0000228 print "<table>\n";
229}
230
Reid Spencer8dd91272005-05-16 18:30:38 +0000231printStats("Total",\%Stats);
232
Reid Spencer092ae902006-08-11 18:36:55 +0000233if ($html)
Reid Spencer8dd91272005-05-16 18:30:38 +0000234{
Reid Spencer092ae902006-08-11 18:36:55 +0000235 print "</table>";
236 if (scalar @ignored_dirs > 0) {
237 print "<p>The following directories were skipped:</p>\n";
238 print "<ol>\n";
239 foreach $index (0 .. $#ignored_dirs) {
240 print " <li>", $ignored_dirs[$index], "</li>\n";
241 }
242 print "</ol>\n";
243 }
244 print "</body></html>\n";
Reid Spencer8dd91272005-05-16 18:30:38 +0000245}