objective-ci 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. data/.gitignore +17 -0
  2. data/BSD-LICENSE.txt +31 -0
  3. data/GPL-LICENSE.txt +16 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +92 -0
  7. data/Rakefile +24 -0
  8. data/bin/ada_count +4 -0
  9. data/bin/asm_count +4 -0
  10. data/bin/awk_count +4 -0
  11. data/bin/break_filelist +4 -0
  12. data/bin/c_count +4 -0
  13. data/bin/cobol_count +4 -0
  14. data/bin/compute_all +4 -0
  15. data/bin/compute_sloc_lang +4 -0
  16. data/bin/count_extensions +4 -0
  17. data/bin/count_unknown_ext +4 -0
  18. data/bin/csh_count +4 -0
  19. data/bin/exp_count +4 -0
  20. data/bin/f90_count +4 -0
  21. data/bin/fortran_count +4 -0
  22. data/bin/generic_count +4 -0
  23. data/bin/get_sloc +4 -0
  24. data/bin/get_sloc_details +4 -0
  25. data/bin/haskell_count +4 -0
  26. data/bin/java_count +4 -0
  27. data/bin/jsp_count +4 -0
  28. data/bin/lex_count +4 -0
  29. data/bin/lexcount1 +4 -0
  30. data/bin/lisp_count +4 -0
  31. data/bin/make_filelists +4 -0
  32. data/bin/makefile_count +4 -0
  33. data/bin/ml_count +4 -0
  34. data/bin/modula3_count +4 -0
  35. data/bin/objc_count +4 -0
  36. data/bin/oclint-0.8 +4 -0
  37. data/bin/oclint-json-compilation-database +4 -0
  38. data/bin/oclint-xcodebuild +4 -0
  39. data/bin/pascal_count +4 -0
  40. data/bin/perl_count +4 -0
  41. data/bin/php_count +4 -0
  42. data/bin/pmd-cpd-objc +7 -0
  43. data/bin/print_sum +4 -0
  44. data/bin/python_count +4 -0
  45. data/bin/ruby_count +4 -0
  46. data/bin/sed_count +4 -0
  47. data/bin/sh_count +4 -0
  48. data/bin/show_filecount +4 -0
  49. data/bin/sloccount +4 -0
  50. data/bin/sql_count +4 -0
  51. data/bin/tcl_count +4 -0
  52. data/docs/jenkins-setup-violations.png +0 -0
  53. data/docs/jenkins-setup.jpg +0 -0
  54. data/externals/oclint/oclint-0.8 +0 -0
  55. data/externals/oclint/oclint-json-compilation-database +86 -0
  56. data/externals/oclint/oclint-xcodebuild +216 -0
  57. data/externals/pmd-cpd/ObjCLanguage-0.0.7-SNAPSHOT.jar +0 -0
  58. data/externals/pmd-cpd/pmd-4.2.5.jar +0 -0
  59. data/externals/sloccount/ada_count +27 -0
  60. data/externals/sloccount/asm_count +166 -0
  61. data/externals/sloccount/awk_count +27 -0
  62. data/externals/sloccount/break_filelist +1308 -0
  63. data/externals/sloccount/c_count +0 -0
  64. data/externals/sloccount/cobol_count +82 -0
  65. data/externals/sloccount/compute_all +87 -0
  66. data/externals/sloccount/compute_sloc_lang +66 -0
  67. data/externals/sloccount/count_extensions +56 -0
  68. data/externals/sloccount/count_unknown_ext +32 -0
  69. data/externals/sloccount/csh_count +27 -0
  70. data/externals/sloccount/exp_count +27 -0
  71. data/externals/sloccount/f90_count +81 -0
  72. data/externals/sloccount/fortran_count +83 -0
  73. data/externals/sloccount/generic_count +77 -0
  74. data/externals/sloccount/get_sloc +544 -0
  75. data/externals/sloccount/get_sloc_details +103 -0
  76. data/externals/sloccount/haskell_count +122 -0
  77. data/externals/sloccount/java_count +0 -0
  78. data/externals/sloccount/jsp_count +0 -0
  79. data/externals/sloccount/lex_count +70 -0
  80. data/externals/sloccount/lexcount1 +0 -0
  81. data/externals/sloccount/lisp_count +27 -0
  82. data/externals/sloccount/make_filelists +193 -0
  83. data/externals/sloccount/makefile_count +27 -0
  84. data/externals/sloccount/ml_count +0 -0
  85. data/externals/sloccount/modula3_count +65 -0
  86. data/externals/sloccount/objc_count +89 -0
  87. data/externals/sloccount/pascal_count +0 -0
  88. data/externals/sloccount/perl_count +147 -0
  89. data/externals/sloccount/php_count +0 -0
  90. data/externals/sloccount/print_sum +40 -0
  91. data/externals/sloccount/python_count +120 -0
  92. data/externals/sloccount/ruby_count +27 -0
  93. data/externals/sloccount/sed_count +27 -0
  94. data/externals/sloccount/sh_count +27 -0
  95. data/externals/sloccount/show_filecount +58 -0
  96. data/externals/sloccount/sloccount +258 -0
  97. data/externals/sloccount/sql_count +76 -0
  98. data/externals/sloccount/tcl_count +27 -0
  99. data/lib/objective-ci.rb +3 -0
  100. data/lib/objective_ci/ci_tasks.rb +142 -0
  101. data/lib/objective_ci/version.rb +3 -0
  102. data/objective-ci.gemspec +26 -0
  103. metadata +255 -0
@@ -0,0 +1,544 @@
1
+ #!/usr/bin/perl -w
2
+
3
+ # get_sloc
4
+ # Take a list of dirs, and get the SLOC or filecount data from them.
5
+ # NOTE: The intended input data ignores zero-length files & ignores dups,
6
+ # so if that's true for the input data, it'll be true for the output data!
7
+
8
+ # This code works but is NOT cleaned up-- it basically grew like
9
+ # topsy. Many of the variable names are misleading, as my needs for
10
+ # output changed.
11
+
12
+ # This is part of SLOCCount, a toolsuite that counts
13
+ # source lines of code (SLOC).
14
+ # Copyright (C) 2001-2004 David A. Wheeler.
15
+ #
16
+ # This program is free software; you can redistribute it and/or modify
17
+ # it under the terms of the GNU General Public License as published by
18
+ # the Free Software Foundation; either version 2 of the License, or
19
+ # (at your option) any later version.
20
+ #
21
+ # This program is distributed in the hope that it will be useful,
22
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ # GNU General Public License for more details.
25
+ #
26
+ # You should have received a copy of the GNU General Public License
27
+ # along with this program; if not, write to the Free Software
28
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
+ #
30
+ # To contact David A. Wheeler, see his website at:
31
+ # http://www.dwheeler.com.
32
+
33
+
34
+
35
+ # Default values for the effort estimation model; the model is
36
+ # effort = ($effort_factor * KiloSLOC) ** $effort_exponent.
37
+ # The following numbers are for basic COCOMO:
38
+
39
+ $effort_factor = 2.40;
40
+ $effort_exponent = 1.05;
41
+ $effort_estimation_message = "Basic COCOMO model,";
42
+
43
+ $schedule_factor = 2.5;
44
+ $schedule_exponent = 0.38;
45
+ $schedule_estimation_message = "Basic COCOMO model,";
46
+
47
+ # Average Salary / year.
48
+ # Source: ComputerWorld, Sep. 4, 2000 Salary Survey,
49
+ # average (U.S.) programmer/analyst salary.
50
+
51
+ $person_cost = 56286.;
52
+
53
+ # Overhead; the person cost is multiplied by this value to determine
54
+ # true annual costs.
55
+
56
+ $overhead = 2.4;
57
+
58
+ @license_list = ( "GPL", "LGPL", "MIT", "BSD", "distributable",
59
+ "public domain", "MPL");
60
+
61
+ %license_of = (); # input is name of program, output is license.
62
+
63
+ $no_license_total = 0;
64
+
65
+ %non_language_list = (
66
+ "dup" => 1,
67
+ "not" => 1,
68
+ "unknown" => 1,
69
+ "auto" => 1,
70
+ "zero" => 1,
71
+ );
72
+
73
+ %ignore_language_list = (
74
+ "makefile" => 1,
75
+ "sql" => 1,
76
+ "html" => 1,
77
+ );
78
+
79
+ # Default input values
80
+ $dirs_in_stdin = 0; # 0: dirs to analyze as arguments, 1: in stdin
81
+
82
+ # Default Output Values:
83
+
84
+ $computing_sloc = 1; # 0= showing filecounts, 1= showing SLOC.
85
+ $narrow = 1;
86
+ $sort_by = "total"; # If empty, sort by name; else "total" or lang name.
87
+ $show_effort = 0; # Show effort for each component?
88
+ $break_line = 1; # Break up long lines into multiple lines?
89
+ $show_non_lang = 0; # Show non-language counts?
90
+ $one_program = 0; # Are all files part of a single program?
91
+ $show_header = 1; # Show header?
92
+ $show_footer = 1; # Show footer?
93
+
94
+
95
+ # Global variables:
96
+
97
+ @dirs = (); # Directories to examine
98
+
99
+ %examined_directories = (); # Keys = Names of directories examined this run.
100
+
101
+ # Subroutines.
102
+
103
+ sub commify {
104
+ # TODO: Needs to be internationalized.
105
+ my $text = reverse $_[0];
106
+ $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
107
+ return scalar reverse $text;
108
+ }
109
+
110
+ sub numformat {
111
+ # Format number nicely with commas.
112
+ my $num = shift;
113
+ my $digits = shift;
114
+ return commify(sprintf("%0.${digits}f", $num));
115
+ }
116
+
117
+ sub effort_person_months {
118
+ # Given the SLOC, reply an estimate of the number of person-months
119
+ # needed to develop it traditionally.
120
+ my $total_sloc = shift;
121
+ return ( ($effort_factor*(($total_sloc/1000.0)**$effort_exponent)));
122
+ }
123
+
124
+ sub estimate_schedule {
125
+ # Given the person-months, reply an estimate of the number of months
126
+ # needed to develop it traditionally.
127
+ my $person_months = shift;
128
+ return ($schedule_factor*($person_months**$schedule_exponent));
129
+ }
130
+
131
+ sub get_lang_total {
132
+ my $lang = shift;
133
+ if (defined($lang_total{$lang})) {return $lang_total{$lang}}
134
+ else {return 0;}
135
+ }
136
+
137
+ # MAIN PROGRAM
138
+
139
+
140
+ # Process options (if any):
141
+
142
+ if ($#ARGV < 0) {
143
+ print STDERR "Error! You must list at least one directory to process, or --stdin.\n";
144
+ exit(1);
145
+ }
146
+
147
+ while ((scalar (@ARGV) > 0) && ($ARGV[0] =~ m/^-/)) {
148
+ $arg = shift;
149
+ if ($arg eq "--") {last;}
150
+ elsif ($arg eq "--filecount") {$computing_sloc = 0;}
151
+ elsif ($arg eq "--filecounts") {$computing_sloc = 0;}
152
+ elsif ($arg eq "--sloc") {$computing_sloc = 1;}
153
+ elsif ($arg eq "--narrow") {$narrow = 1;}
154
+ elsif ($arg eq "--wide") {$narrow = 0;}
155
+ elsif ($arg eq "--break") {$break_line = 1;}
156
+ elsif ($arg eq "--nobreak") {$break_line = 0;}
157
+ elsif ($arg eq "--sort") {$sort_by = shift;} # Must be "total" or a lang.
158
+ elsif ($arg eq "--nosort") {$sort_by = "";}
159
+ elsif ($arg eq "--showother") {$show_non_lang = 1;}
160
+ elsif ($arg eq "--noshowother") {$show_non_lang = 0;}
161
+ elsif ($arg eq "--oneprogram") {$one_program = 1;}
162
+ elsif ($arg eq "--noheader") {$show_header = 0;}
163
+ elsif ($arg eq "--nofooter") {$show_footer = 0;}
164
+ elsif ($arg eq "--addlang") { $lang = shift;
165
+ if (!defined($ignore_language_list{$lang})) {
166
+ die "Sorry, but $lang isn't ignored"; };
167
+ delete $ignore_language_list{$lang}; }
168
+ elsif ($arg eq "--addlangall") { %ignore_language_list = (); }
169
+ elsif ($arg eq "--effort") {$effort_factor = (shift)*1.0;
170
+ $effort_exponent = (shift)*1.0;
171
+ $effort_estimation_message = "effort model"}
172
+ elsif ($arg eq "--schedule") {$schedule_factor = (shift)*1.0;
173
+ $schedule_exponent = (shift)*1.0;
174
+ $schedule_estimation_message = "schedule model"}
175
+ elsif ($arg eq "--personcost") {$person_cost = (shift)*1.0;}
176
+ elsif ($arg eq "--overhead") {$overhead = (shift)*1.0;}
177
+ elsif ($arg eq "--stdin") {$dirs_in_stdin = 1;}
178
+ else {die "Unknown option: $arg\n";}
179
+ }
180
+
181
+
182
+ # Determine the languages to show:
183
+
184
+
185
+ if ($computing_sloc) { $show_non_lang = 0; }
186
+
187
+ if (!$show_non_lang) {
188
+ # Add the non_language_list to the ignored languages.
189
+ foreach $langname (keys(%non_language_list))
190
+ {$ignore_language_list{$langname} = 1;}
191
+ }
192
+
193
+
194
+ %lang_total = ();
195
+ %license_total = ();
196
+
197
+ @data_lines = ();
198
+
199
+ $sloc = 0;
200
+ $total_sloc = 0;
201
+ $total_lang_sloc = 0;
202
+ $grand_total_sloc = 0;
203
+ $grand_total_lang_sloc = 0;
204
+ $effort = 0.0;
205
+ $grand_total_effort = 0.0;
206
+ $grand_schedule = 0.0;
207
+
208
+ if (!$narrow) {
209
+ # Ouch! To accurately determine the column positions and names,
210
+ # without "pre-knowing" them, we need to look through the data.
211
+ # So, we'll do it twice. This isn't efficient - if needed,
212
+ # speed it up by rewriting this to do it in-memory.
213
+ while (defined($_ = <DATAFILE>)) {
214
+ ($lang, $sloc) = split;
215
+ next if ( (!defined($lang)) || (!defined($sloc)) );
216
+ next if ($ignore_language_list{$lang});
217
+ $lang_total{$lang} = 0;
218
+ }
219
+ }
220
+
221
+
222
+ # Print the header.
223
+ if ($show_header) {
224
+ if ($narrow) {
225
+ if ($computing_sloc) { print "SLOC\t"; }
226
+ else { print "#Files\t"; }
227
+ if ($show_effort) {print "P.Y.\t";}
228
+ print "Directory\t";
229
+ if ($computing_sloc) { print "SLOC-by-Language (Sorted)"; }
230
+ else { print "#Files-by-Language (Sorted)"; }
231
+ print "\n";
232
+ } else {
233
+ if ($computing_sloc) { print "SLOC\t"; }
234
+ else { print "#Files\t"; }
235
+ if ($show_effort) {print "P.M.\t";}
236
+ printf "%-22s\t", "Dir";
237
+ foreach $lang (keys(%lang_total)) {
238
+ print "$lang\t";
239
+ $lang_total{$lang} = 0;
240
+ };
241
+ print "\n";
242
+ }
243
+ }
244
+
245
+ if ($dirs_in_stdin == 1) {
246
+ while (defined($dir = <STDIN>)) {
247
+ chomp ($dir);
248
+ push (@dirs, $dir);
249
+ }
250
+ }
251
+
252
+ while ($dir = shift) {
253
+ push (@dirs, $dir);
254
+ }
255
+
256
+
257
+ foreach $dir (@dirs) {
258
+ if (! -d "$dir") {
259
+ # print "Skipping non-directory $dir\n";
260
+ next;
261
+ }
262
+
263
+ # Skip previously-examined directories.
264
+ if ($examined_directories{$dir}) {
265
+ # print "Skipping already-examined directory $dir\n";
266
+ next;
267
+ }
268
+ $examined_directories{$dir} = 1;
269
+
270
+ if (! -r "${dir}/filelist") {
271
+ # print "Skipping directory $dir; it doesn't contain a file 'filelist'\n";
272
+ next;
273
+ }
274
+
275
+
276
+ $simplename = $dir;
277
+ $simplename =~ s!^.*\/!!;
278
+ $total_sloc = 0;
279
+ $total_lang_sloc = 0;
280
+ $preceding_entry = 0;
281
+
282
+ $line = "";
283
+ %lang_data = ();
284
+
285
+ if ($computing_sloc) {
286
+ $filename = "${dir}/all-physical.sloc";
287
+ } else {
288
+ $filename = "${dir}/all.filecount";
289
+ }
290
+ if (open(DATAFILE, "<$filename")) {
291
+ while (defined($_ = <DATAFILE>)) {
292
+ ($lang, $sloc) = split;
293
+ next if ( (!defined($lang)) || (!defined($sloc)) );
294
+ next if ($ignore_language_list{$lang});
295
+ if ($narrow) { if ($sloc) {$lang_data{$lang} = $sloc;}}
296
+ else { $line .= "${sloc}\t"; }
297
+ if ($lang eq $sort_by) {$interesting_lang_sloc = $sloc;}
298
+ $total_sloc += $sloc;
299
+ $total_lang_sloc += $sloc unless ($non_language_list{$lang});
300
+ $lang_total{$lang} += $sloc;
301
+ }
302
+ close(DATAFILE);
303
+ } else {
304
+ print STDERR "Error openinig $filename\n";
305
+ }
306
+ if ($narrow) {
307
+ # For narrow view, sort the language entries.
308
+ foreach $entry (sort {$lang_data{$b} <=> $lang_data{$a}} keys %lang_data){
309
+ if ($preceding_entry) {$line .= ",";}
310
+ $preceding_entry = 1;
311
+ $line .= "${entry}=${lang_data{$entry}}";
312
+ }
313
+ if (!$preceding_entry) {$line .= "(none)";}
314
+ }
315
+
316
+ $grand_total_sloc += $total_sloc;
317
+ $grand_total_lang_sloc += $total_lang_sloc;
318
+
319
+ $effort = effort_person_months($total_sloc);
320
+ $grand_total_effort += $effort;
321
+
322
+ $schedule = estimate_schedule($effort);
323
+ if ($schedule > $grand_schedule) {
324
+ $grand_schedule = $schedule; # The longest leg wins.
325
+ }
326
+
327
+ $displayed_effort = "";
328
+ if ($show_effort) { $displayed_effort = sprintf "%.2f\t", $effort; }
329
+ if ($narrow) {
330
+ $displayed_name = "$simplename";
331
+ } else {
332
+ $displayed_name = sprintf "%-22s\t", $simplename;
333
+ }
334
+
335
+ # Add to the corresponding license, if the license is known.
336
+ $license = "";
337
+ if (open(LICENSE_FILE, "<${dir}/PROGRAM_LICENSE")) {
338
+ $license = <LICENSE_FILE>;
339
+ chomp($license);
340
+ close(LICENSE_FILE);
341
+ if ($license) {
342
+ $license_of{$simplename} = $license; # Hash currently unused.
343
+ if (! defined($license_total{$license})) {
344
+ $license_total{$license} = 0;
345
+ }
346
+ $license_total{$license} = $license_total{$license} + $total_sloc;
347
+ }
348
+ } else {
349
+ $no_license_total += $total_sloc;
350
+ }
351
+
352
+ if ($narrow) {
353
+ $line = sprintf "%-7d %s%-15s %-s\n", $total_sloc, $displayed_effort,
354
+ $simplename, $line;
355
+ if ($break_line && (length($line) > 77)) { # Break up long line.
356
+ $line =~ s/(.{71})([^,]*),(.*)/$1$2,\n $3/;
357
+ }
358
+ if ($license) {
359
+ $line .= " [$license]\n";
360
+ }
361
+ } else {
362
+ $line = "${total_sloc}\t${displayed_effort}${displayed_name}${line}\n";
363
+ }
364
+ if ($sort_by) {
365
+ if ($sort_by eq "total") {$line = "$total_sloc\t$line";}
366
+ else {$line = "$interesting_lang_sloc\t$line";}
367
+ $data_lines[$#data_lines+1] = $line; # Add to data lines.
368
+ } else {
369
+ print $line; # No sort - print immediately for speed.
370
+ }
371
+
372
+ }
373
+
374
+ if ($sort_by) {
375
+ # Print sorted version. This is a little inefficient, but for
376
+ # only a few hundred or thousand values it doesn't matter.
377
+ @sorted_data_lines = sort { ($b =~ /^(\d+)/)[0] <=> ($a =~ /^(\d+)/)[0] }
378
+ @data_lines;
379
+ foreach $line (@sorted_data_lines) {
380
+ $short_line = $line;
381
+ $short_line =~ s/^[^\t]*\t//; # Remove sort field.
382
+ print $short_line;
383
+ }
384
+ }
385
+
386
+
387
+ if (! $show_footer) {exit(0);}
388
+ if ($grand_total_sloc == 0) {
389
+ print "SLOC total is zero, no further analysis performed.\n";
390
+ exit(1);
391
+ }
392
+
393
+ # Print the footer.
394
+ if ($narrow) {
395
+ print "\n";
396
+ print "\n";
397
+ print "Totals grouped by language (dominant language first):\n";
398
+ # If you don't want the list sorted by size of language, just do:
399
+ # foreach $lang (@language_list) {
400
+ foreach $lang (sort {&get_lang_total($b) <=> &get_lang_total($a) } keys(%lang_total) ) {
401
+ $percent = get_lang_total($lang) * 100.0 / $grand_total_sloc;
402
+ if ($percent > 0.0) {
403
+ printf "%-9s %9d (%.2f%%)\n", $lang . ":", $lang_total{$lang}, $percent;
404
+ }
405
+ };
406
+
407
+ if ($show_non_lang) {
408
+ # The previous list showed "non-languages", so now we'll show only the
409
+ # data for data associated with a normal language:
410
+ print "\n";
411
+ print "\n";
412
+ foreach $lang (sort {&get_lang_total($b) <=> &get_lang_total($a) } keys(%lang_total)) {
413
+ next if (defined($non_language_list{$lang}));
414
+ $percent = $lang_total{$lang} * 100.0 / $grand_total_lang_sloc;
415
+ if ($percent > 0.0) {
416
+ printf "%-9s %9d (%.2f%%)\n", $lang . ":", $lang_total{$lang}, $percent;
417
+ }
418
+ };
419
+ }
420
+
421
+ } else { # Not narrow.
422
+
423
+ print "$grand_total_sloc\t";
424
+ if ($show_effort) {printf "%.2f\t", $grand_total_effort;}
425
+
426
+ printf "%-22s", "Totals";
427
+ foreach $lang (keys(%lang_total)) {
428
+ print "\t$lang_total{$lang}";
429
+ };
430
+
431
+ print "\t";
432
+ if ($show_effort) {printf "\t";}
433
+ printf "%-22s\t", "Percentages";
434
+ foreach $lang (keys(%lang_total)) {
435
+ $percent = $lang_total{$lang} * 100.0 / $grand_total_sloc;
436
+ printf "\t%0.2f", $percent;
437
+ };
438
+ print "\n";
439
+
440
+ print "\t";
441
+ if ($show_effort) {printf "\t";}
442
+ printf "%-22s\t", "Code Percentages";
443
+ foreach $lang (keys(%lang_total)) {
444
+ next if (defined($non_language_list{$lang}));
445
+ $percent = $lang_total{$lang} * 100.0 / $grand_total_lang_sloc;
446
+ printf "\t%0.2f", $percent;
447
+ };
448
+ print "\n";
449
+ }
450
+
451
+ print "\n";
452
+ print "\n";
453
+
454
+
455
+ if (%license_total) {
456
+ # We have license info on something, so if there's anything
457
+ # unallocated, add that to the list.
458
+ if ($no_license_total) {
459
+ $license_total{"Not listed"} = $no_license_total;
460
+ }
461
+ print "Licenses:\n";
462
+ foreach $license (sort {$license_total{$b} <=> $license_total{$a} } keys(%license_total)) {
463
+ $percent = $license_total{$license} * 100.0 / $grand_total_sloc;
464
+ if ($percent > 0.0) {
465
+ printf "%9d (%.2f%%) %s\n", $license_total{$license}, $percent, $license;
466
+ }
467
+ };
468
+ print "\n";
469
+ print "\n";
470
+
471
+ print "Percentage of Licenses containing selected key phrases:\n";
472
+ %license_phrase = ();
473
+ foreach $license (keys(%license_total)) {
474
+ foreach $phrase (@license_list) {
475
+ if ($license =~ m/\b$phrase\b/i) {
476
+ if (!defined($license_phrase{$phrase})) {$license_phrase{$phrase} = 0;}
477
+ $license_phrase{$phrase} = $license_phrase{$phrase} +
478
+ $license_total{$license};
479
+ }
480
+ }
481
+ }
482
+
483
+ foreach $phrase (sort {$license_phrase{$b} <=> $license_phrase{$a} } keys(%license_phrase)) {
484
+ $percent = $license_phrase{$phrase} * 100.0 / $grand_total_sloc;
485
+ if ($percent > 0.0) {
486
+ printf "%9d (%.2f%%) %s\n", $license_phrase{$phrase}, $percent, $phrase;
487
+ }
488
+ };
489
+
490
+ }
491
+
492
+
493
+ print "\n";
494
+ print "\n";
495
+
496
+ if ($computing_sloc) {
497
+ if ($one_program) {
498
+ # If it's one program, override the grand total of effort
499
+ # and the schedule calculations by using the total SLOC.
500
+
501
+ $grand_total_effort = effort_person_months($grand_total_sloc);
502
+ $grand_schedule = estimate_schedule($grand_total_effort);
503
+ }
504
+ printf "Total Physical Source Lines of Code (SLOC) = %s\n",
505
+ commify($grand_total_sloc);
506
+
507
+ printf "Development Effort Estimate, Person-Years (Person-Months) = %s (%s)\n",
508
+ numformat($grand_total_effort/12.0, 2),
509
+ numformat($grand_total_effort, 2);
510
+ print " ($effort_estimation_message " .
511
+ "Person-Months = $effort_factor * (KSLOC**$effort_exponent))\n";
512
+
513
+ printf "Schedule Estimate, Years (Months) = %s (%s)\n",
514
+ numformat($grand_schedule/12.0, 2),
515
+ numformat($grand_schedule, 2);
516
+ print " ($schedule_estimation_message " .
517
+ "Months = $schedule_factor * (person-months**$schedule_exponent))\n";
518
+
519
+ # Don't show this if there are multiple programs, because the computation
520
+ # is essentially meaningless: after the "smaller" projects have completed,
521
+ # the longest one would keep going:
522
+ if ($one_program && ($grand_schedule > 0.0)) {
523
+ printf "Estimated Average Number of Developers (Effort/Schedule) = %s\n",
524
+ numformat($grand_total_effort / $grand_schedule, 2);
525
+ }
526
+
527
+
528
+ $value = ($grand_total_effort / 12.0) * $person_cost * $overhead;
529
+ printf "Total Estimated Cost to Develop = \$ %s\n",
530
+ numformat($value, 0);
531
+ printf " (average salary = \$%s/year, overhead = %0.2f).\n",
532
+ commify($person_cost), $overhead;
533
+
534
+ } else {
535
+ print "Total Number of Files = $grand_total_sloc\n";
536
+ print "Total Number of Source Code Files = $grand_total_lang_sloc\n";
537
+ }
538
+ print "SLOCCount, Copyright (C) 2001-2004 David A. Wheeler\n";
539
+ print "SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL.\n";
540
+ print "SLOCCount comes with ABSOLUTELY NO WARRANTY, and you are welcome to\n";
541
+ print "redistribute it under certain conditions as specified by the GNU GPL license;\n";
542
+ print "see the documentation for details.\n";
543
+ print "Please credit this data as \"generated using David A. Wheeler's 'SLOCCount'.\"\n";
544
+
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/perl -w
2
+
3
+ # get_sloc_details
4
+ # Take a list of dirs, and get the detailed SLOC entries for every file.
5
+
6
+ # This is part of SLOCCount, a toolsuite that counts
7
+ # source lines of code (SLOC).
8
+ # Copyright (C) 2001-2004 David A. Wheeler.
9
+ #
10
+ # This program is free software; you can redistribute it and/or modify
11
+ # it under the terms of the GNU General Public License as published by
12
+ # the Free Software Foundation; either version 2 of the License, or
13
+ # (at your option) any later version.
14
+ #
15
+ # This program is distributed in the hope that it will be useful,
16
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ # GNU General Public License for more details.
19
+ #
20
+ # You should have received a copy of the GNU General Public License
21
+ # along with this program; if not, write to the Free Software
22
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
+ #
24
+ # To contact David A. Wheeler, see his website at:
25
+ # http://www.dwheeler.com.
26
+
27
+
28
+ sub print_data
29
+ {
30
+ my $dir = shift;
31
+ my $langfile = shift;
32
+ my $saw_total = 0;
33
+ my $filename = "${dir}/${langfile}";
34
+ my $lang = $langfile;
35
+ $lang =~ s/_outfile\.dat$//;
36
+
37
+ open(RAWDATA, "<$filename") ||
38
+ return;
39
+ # die "Can't open file in $dir for language $lang.\n";
40
+
41
+ if ($lang eq "asm") {
42
+ while (<RAWDATA>) {
43
+ if (m/^Total:/) {
44
+ $saw_total = 1;
45
+ last;
46
+ }
47
+ chomp;
48
+ if (m/^([0-9]+)\s+\([^\)]+\)\s+(.*)/) {
49
+ print "$1\t$lang\t$dir\t$2\n";
50
+ } else {
51
+ print STDERR "Warning: file $filename has unexpected text: $_\n";
52
+ }
53
+ }
54
+ } else {
55
+ while (<RAWDATA>) {
56
+ if (m/^Total:/) {
57
+ $saw_total = 1;
58
+ last;
59
+ }
60
+ chomp;
61
+ if (m/^([0-9]+)\s+(.*)/) {
62
+ print "$1\t$lang\t$dir\t$2\n";
63
+ } else {
64
+ print STDERR "Warning: file $filename has unexpected text: $_\n";
65
+ }
66
+ }
67
+ }
68
+ close(RAWDATA);
69
+ if (! $saw_total) {
70
+ print STDERR "Warning! No 'Total' line in $filename.\n";
71
+ }
72
+ }
73
+
74
+ # MAIN PROGRAM
75
+
76
+
77
+ if ($#ARGV < 0) {
78
+ print STDERR "Error! You must list at least one directory to process.\n";
79
+ exit(1);
80
+ }
81
+
82
+
83
+ while ( $dir = shift ) {
84
+
85
+ if (! -d "$dir") {
86
+ # print "Skipping non-directory $dir\n";
87
+ next;
88
+ }
89
+
90
+ if (! -r "${dir}/filelist") {
91
+ # print "Skipping directory $dir; it doesn't contain a file 'filelist'\n";
92
+ next;
93
+ }
94
+
95
+ opendir(DATADIR, $dir) || die "can't opendir $dir: $!";
96
+ @outfiles = grep { /outfile\.dat$/ } readdir(DATADIR);
97
+ closedir DATADIR;
98
+ foreach $langfile (@outfiles) {
99
+ print_data($dir, $langfile);
100
+ }
101
+
102
+ }
103
+