App-cloc
view release on metacpan or search on metacpan
--write-lang-def=<file> Writes to <file> the language processing filters
then exits. Useful as a first step to creating
custom language definitions (see also
--force-lang-def, --read-lang-def).
${BB}Output Options${NN}
--3 Print third-generation language output.
(This option can cause report summation to fail
if some reports were produced with this option
while others were produced without it.)
--by-percent X Instead of comment and blank line counts, show
these values as percentages based on the value
of X in the denominator:
X = 'c' -> # lines of code
X = 'cm' -> # lines of code + comments
X = 'cb' -> # lines of code + blanks
X = 'cmb' -> # lines of code + comments + blanks
For example, if using method 'c' and your code
has twice as many lines of comments as lines
of code, the value in the comment column will
be 200%. The code column remains a line count.
--csv Write the results as comma separated values.
$opt_report_file ,
$opt_sdir ,
$opt_sum_reports ,
$opt_processes ,
$opt_unicode ,
$opt_no3 , # accept it but don't use it
$opt_3 ,
$opt_extract_with ,
$opt_by_file ,
$opt_by_file_by_lang ,
$opt_by_percent ,
$opt_xml ,
$opt_xsl ,
$opt_yaml ,
$opt_csv ,
$opt_csv_delimiter ,
$opt_fullpath ,
$opt_json ,
$opt_md ,
$opt_match_f ,
$opt_not_match_f ,
"sql_project|sql-project=s" => \$opt_sql_project ,
"sql_append|sql-append" => \$opt_sql_append ,
"sql_style|sql-style=s" => \$opt_sql_style ,
"inline" => \$opt_inline ,
"exclude_ext|exclude-ext=s" => \$opt_exclude_ext ,
"ignore_whitespace|ignore-whitespace" => \$opt_ignore_whitespace ,
"ignore_case|ignore-case" => \$opt_ignore_case ,
"follow_links|follow-links" => \$opt_follow_links ,
"autoconf" => \$opt_autoconf ,
"sum_one|sum-one" => \$opt_sum_one ,
"by_percent|by-percent=s" => \$opt_by_percent ,
"stdin_name|stdin-name=s" => \$opt_stdin_name ,
"windows" => \$opt_force_on_windows ,
"unix" => \$opt_force_on_unix ,
"show_os|show-os" => \$opt_show_os ,
"skip_archive|skip-archive=s" => \$opt_skip_archive ,
"max_file_size|max-file-size=i" => \$opt_max_file_size ,
"use_sloccount|use-sloccount" => \$opt_use_sloccount ,
"no_autogen|no-autogen" => \$opt_no_autogen ,
"git" => \$opt_force_git ,
);
$opt_by_file = 1;
$skip_generate_report = 1;
$opt_sum_reports = 0;
}
if ($opt_sql_style) {
$opt_sql_style = lc $opt_sql_style;
if (!grep { lc $_ eq $opt_sql_style } qw ( Oracle )) {
die "'$opt_sql_style' is not a recognized SQL style.\n";
}
}
$opt_by_percent = '' unless defined $opt_by_percent;
if ($opt_by_percent and $opt_by_percent !~ m/^(c|cm|cb|cmb)$/i) {
die "--by-percent must be either 'c', 'cm', 'cb', or 'cmb'\n";
}
$opt_by_percent = lc $opt_by_percent;
if (defined $opt_vcs) {
if ($opt_vcs eq "git") {
$opt_vcs = "git ls-files";
my @submodules = invoke_generator('git submodule status');
foreach my $SM (@submodules) {
$SM =~ s/^\s+//; # may have leading space
$SM =~ s/\(\S+\)\s*$//; # may end with something like (heads/master)
my ($checksum, $dir) = split(' ', $SM, 2);
$dir =~ s/\s+$//;
$data_line = sprintf "%-${spacing_n}s" , $first_column;
} else {
$data_line = sprintf "%-${spacing_1}s ", $first_column;
}
if ($BY_FILE) {
$data_line .= sprintf "%${spacing_2}s" , "" ;
} else {
$data_line .= sprintf "%${spacing_2}s " , "files";
}
my $PCT_symbol = "";
$PCT_symbol = " \%" if $opt_by_percent;
$data_line .= sprintf "%${spacing_2}s %${spacing_2}s %${spacing_2}s",
"blank${PCT_symbol}" ,
"comment${PCT_symbol}" ,
"code";
if ($Style eq "txt") {
push @results, $data_line;
push @results, $hyphen_line;
}
push @results, $lang_or_file;
}
foreach my $S (qw(same modified added removed)) {
my $indent = $spacing_1 - 2;
my $line .= sprintf " %-${indent}s", $S;
if ($BY_FILE) {
$line .= sprintf " ";
} else {
$line .= sprintf " %${spacing_2}s", $rhhh_count->{$lang_or_file}{'nFiles'}{$S};
}
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$rhhh_count->{$lang_or_file}{'code'}{$S} ,
$rhhh_count->{$lang_or_file}{'comment'}{$S},
$rhhh_count->{$lang_or_file}{'blank'}{$S} );
if ($rhhh_count->{$lang_or_file}{'code'}{$S} > 0) {
$line .= sprintf " %14.2f %14.2f %${spacing_2}s",
$rhhh_count->{$lang_or_file}{'blank'}{$S} / $DEN * 100,
$rhhh_count->{$lang_or_file}{'comment'}{$S} / $DEN * 100,
$rhhh_count->{$lang_or_file}{'code'}{$S} ;
} else {
$line .= sprintf " %14.2f %14.2f %${spacing_2}s",
push @results, $hyphen_line;
push @results, "SUM:";
foreach my $S (qw(same modified added removed)) {
my $indent = $spacing_1 - 2;
my $line .= sprintf " %-${indent}s", $S;
if ($BY_FILE) {
$line .= sprintf " ";
} else {
$line .= sprintf " %${spacing_2}s", $sum{'nFiles'}{$S};
}
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent,
$sum{'code'}{$S}, $sum{'comment'}{$S}, $sum{'blank'}{$S});
if ($sum{'code'}{$S} > 0) {
$line .= sprintf " %14.2f %14.2f %${spacing_2}s",
$sum{'blank'}{$S} / $DEN * 100,
$sum{'comment'}{$S} / $DEN * 100,
$sum{'code'}{$S} ;
} else {
$line .= sprintf " %14.2f %14.2f %${spacing_2}s",
0.0, 0.0, $sum{'code'}{$S} ;
}
if ($BY_FILE) {
$L .= sprintf " <file name=\"%s\" files_count=\"1\" ",
xml_metachars(
rm_leading_tempdir($lang_or_file, \%TEMP_DIR));
} else {
$L .= sprintf " <language name=\"%s\" files_count=\"%d\" ",
$lang_or_file ,
$rhhh_count->{$lang_or_file}{'nFiles'}{$S};
}
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$rhhh_count->{$lang_or_file}{'code'}{$S} ,
$rhhh_count->{$lang_or_file}{'comment'}{$S},
$rhhh_count->{$lang_or_file}{'blank'}{$S} );
foreach my $T (qw(blank comment)) {
if ($rhhh_count->{$lang_or_file}{'code'}{$S} > 0) {
$L .= sprintf "%s=\"%.2f\" ",
$T, $rhhh_count->{$lang_or_file}{$T}{$S} / $DEN * 100;
} else {
$L .= sprintf "%s=\"0.0\" ", $T;
}
foreach my $T (qw(blank comment code)) {
$L .= sprintf "%s=\"%d\" ",
$T, $rhhh_count->{$lang_or_file}{$T}{$S};
}
}
push @results, $L . "/>";
}
my $L = sprintf " <total sum_files=\"%d\" ", $sum{'nFiles'}{$S};
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent,
$sum{'code'}{$S} ,
$sum{'comment'}{$S},
$sum{'blank'}{$S} );
foreach my $V (qw(blank comment)) {
if ($sum{'code'}{$S} > 0) {
$L .= sprintf "%s=\"%.2f\" ", $V, $sum{$V}{$S} / $DEN * 100;
} else {
$L .= sprintf "%s=\"0.0\" ", $V;
}
}
foreach my $lang_or_file (sort {
$rhhh_count->{$b}{'code'} <=>
$rhhh_count->{$a}{'code'}
}
keys %{$rhhh_count}) {
if ($BY_FILE) {
$line = rm_leading_tempdir($lang_or_file, \%TEMP_DIR) . "$DELIM ";
} else {
$line = $lang_or_file . "${DELIM} ";
}
if ($opt_by_percent) {
foreach my $item (qw(nFiles)) {
next if $BY_FILE and $item eq 'nFiles';
foreach my $symbol (qw(same modified added removed)) {
if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol}) {
$line .= "$rhhh_count->{$lang_or_file}{$item}{$symbol}${DELIM} ";
} else {
$line .= "0${DELIM} ";
}
}
}
$data_line = sprintf "%-${spacing_n}s ", $first_column;
} else {
$data_line = sprintf "%-${spacing_1}s ", $first_column;
}
if ($BY_FILE) {
$data_line .= sprintf "%${spacing_2}s " , " " ;
} else {
$data_line .= sprintf "%${spacing_2}s " , "files";
}
my $PCT_symbol = "";
$PCT_symbol = " \%" if $opt_by_percent;
$data_line .= sprintf "%${spacing_2}s %${spacing_2}s %${spacing_2}s",
"blank${PCT_symbol}" ,
"comment${PCT_symbol}" ,
"code";
$data_line .= sprintf " %8s %14s",
"scale" ,
"3rd gen. equiv"
if $opt_3;
if ($opt_md) {
my @col_header = ();
if ($BY_FILE) {
my $clean_filename = rm_leading_tempdir($lang_or_file, \%TEMP_DIR);
$clean_filename = xml_metachars($clean_filename) if $opt_xml;
$data_line = sprintf $Format{'1'}{$Style}, $clean_filename;
} else {
$data_line = sprintf $Format{'2'}{$Style}, $lang_or_file;
}
$data_line .= sprintf $Format{3}{$Style} ,
$rhh_count->{$lang_or_file}{'nFiles'} unless $BY_FILE;
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$rhh_count->{$lang_or_file}{'code'} ,
$rhh_count->{$lang_or_file}{'comment'},
$rhh_count->{$lang_or_file}{'blank'} );
$data_line .= sprintf $Format{5}{$Style} ,
$rhh_count->{$lang_or_file}{'blank'} / $DEN * 100,
$rhh_count->{$lang_or_file}{'comment'} / $DEN * 100,
$rhh_count->{$lang_or_file}{'code'} ;
} else {
$data_line .= sprintf $Format{4}{$Style} ,
$rhh_count->{$lang_or_file}{'blank'} ,
if ($BY_FILE or ($report_type eq "by report file")) {
push @results, " <file " . $data_line . "/>";
} else {
push @results, " <language " . $data_line . "/>";
}
} elsif ($opt_yaml or $opt_json) {
my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();
push @results,"${Q}" . rm_leading_tempdir($lang_or_file, \%TEMP_DIR). "${Q} :$open_B";
push @results," ${Q}nFiles${Q}: " . $rhh_count->{$lang_or_file}{'nFiles'} . $C
unless $BY_FILE;
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$rhh_count->{$lang_or_file}{'code'} ,
$rhh_count->{$lang_or_file}{'comment'},
$rhh_count->{$lang_or_file}{'blank'} );
push @results," ${Q}blank_pct${Q}: " .
sprintf("%3.2f", $rhh_count->{$lang_or_file}{'blank'} / $DEN * 100) . $C;
push @results," ${Q}comment_pct${Q}: " .
sprintf("%3.2f", $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100) . $C;
push @results," ${Q}code${Q}: " . $rhh_count->{$lang_or_file}{'code'} . $C;
} else {
push @results," ${Q}blank${Q}: " . $rhh_count->{$lang_or_file}{'blank'} . $C;
if ($BY_FILE) {
$first_column = $rhh_count->{$lang_or_file}{'lang'};
$clean_name = rm_leading_tempdir($lang_or_file, \%TEMP_DIR);
$str = $clean_name . ${DELIM};
} else {
$first_column = $rhh_count->{$lang_or_file}{'nFiles'};
$str = $clean_name . ${DELIM} .
$first_column . ${DELIM};
}
}
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$rhh_count->{$lang_or_file}{'code'} ,
$rhh_count->{$lang_or_file}{'comment'},
$rhh_count->{$lang_or_file}{'blank'} );
$str .= sprintf("%3.2f", $rhh_count->{$lang_or_file}{'blank'} / $DEN * 100) . ${DELIM} .
sprintf("%3.2f", $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100) . ${DELIM} .
$rhh_count->{$lang_or_file}{'code'};
} else {
$str .= $rhh_count->{$lang_or_file}{'blank'} . ${DELIM} .
$rhh_count->{$lang_or_file}{'comment'}. ${DELIM} .
$rhh_count->{$lang_or_file}{'code'};
my $avg_scale = 1; # weighted average of scale factors
$avg_scale = sprintf("%.2f", $sum_scaled / $sum_code)
if $sum_code and $opt_3;
if ($opt_xml) {
$data_line = "";
if (!$BY_FILE) {
$data_line .= sprintf "sum_files=\"%d\" ", $sum_files;
}
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$sum_code, $sum_comment, $sum_blank);
$data_line .= sprintf $Format{'5'}{$Style},
$sum_blank / $DEN * 100,
$sum_comment / $DEN * 100,
$sum_code ;
} else {
$data_line .= sprintf $Format{'4'}{$Style},
$sum_blank ,
$sum_comment ,
$sum_code ;
}
if (!$opt_by_file_by_lang or $ALREADY_SHOWED_XML_SECTION) {
push @results, "</results>";
} else {
$ALREADY_SHOWED_XML_SECTION = 1;
}
} elsif ($opt_yaml or $opt_json) {
my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();
push @results, "${Q}SUM${Q}: ${open_B}";
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$sum_code, $sum_comment, $sum_blank);
push @results, " ${Q}blank${Q}: " . sprintf("%.2f", $sum_blank / $DEN * 100) . $C;
push @results, " ${Q}comment${Q}: ". sprintf("%.2f", $sum_comment / $DEN * 100) . $C;
push @results, " ${Q}code${Q}: " . $sum_code . $C;
} else {
push @results, " ${Q}blank${Q}: " . $sum_blank . $C;
push @results, " ${Q}comment${Q}: ". $sum_comment . $C;
push @results, " ${Q}code${Q}: " . $sum_code . $C;
}
push @results, " ${Q}nFiles${Q}: " . $sum_files . $C;
} elsif ($opt_csv) {
# do nothing
} else {
if ($BY_FILE) {
$data_line = sprintf "%-${spacing_0}s ", "SUM:" ;
} else {
$data_line = sprintf "%-${spacing_1}s ", "SUM:" ;
$data_line .= sprintf "%${spacing_2}d ", $sum_files;
}
if ($opt_by_percent) {
my $DEN = compute_denominator($opt_by_percent ,
$sum_code, $sum_comment, $sum_blank);
$data_line .= sprintf $Format{'5'}{$Style},
$sum_blank / $DEN * 100,
$sum_comment / $DEN * 100,
$sum_code ;
} else {
$data_line .= sprintf $Format{'4'}{$Style},
$sum_blank ,
$sum_comment ,
$sum_code ;
# Given filename, returns TRUE if its contents really is lex.
# lex file must have "%%", "%{", and "%}".
# In theory, a lex file doesn't need "%{" and "%}", but in practice
# they all have them, and requiring them avoid mislabeling a
# non-lexfile as a lex file.
my $filename = shift;
chomp($filename);
my $is_lex = 0; # Value to determine.
my $percent_percent = 0;
my $percent_opencurly = 0;
my $percent_closecurly = 0;
# Return cached result, if available:
if ($lex_files{$filename}) { return $lex_files{$filename};}
open(LEX_FILE, "<$filename") ||
die "Can't open $filename to determine if it's lex.\n";
while(<LEX_FILE>) {
$percent_percent++ if (m/^\s*\%\%/);
$percent_opencurly++ if (m/^\s*\%\{/);
$percent_closecurly++ if (m/^\s*\%\}/);
}
close(LEX_FILE);
if ($percent_percent && $percent_opencurly && $percent_closecurly)
{$is_lex = 1;}
$lex_files{$filename} = $is_lex; # Store result in cache.
return $is_lex;
} # 1}}}
sub really_is_expect { # {{{1
# Given filename, returns TRUE if its contents really are Expect.
# Many "exp" files (such as in Apache and Mesa) are just "export" data,
# summarizing something else # (e.g., its interface).
=head2 Output Options
=over 4
=item B<--3>
Print third-generation language output. (This option can cause report
summation to fail if some reports were produced with this option while
others were produced without it.)
=item B<--by-percent X>
Instead of comment and blank line counts, show
these values as percentages based on the
value of X in the denominator:
X = 'c' -> # lines of code
X = 'cm' -> # lines of code + comments
X = 'cb' -> # lines of code + blanks
X = 'cmb' -> # lines of code + comments + blanks
For example, if using method 'c' and your code
has twice as many lines of comments as lines
of code, the value in the comment column will
( run in 0.425 second using v1.01-cache-2.11-cpan-709fd43a63f )