1
1
#!/usr/bin/env perl
2
2
# cloc -- Count Lines of Code {{{1
3
- # Copyright (C) 2006-2024 Al Danial <al.danial@gmail.com>
3
+ # Copyright (C) 2006-2025 Al Danial <al.danial@gmail.com>
4
4
# First release August 2006
5
5
#
6
6
# Includes code from:
@@ -45,6 +45,7 @@ use File::Spec;
45
45
use IO::File;
46
46
use List::Util qw( min max );
47
47
use Cwd;
48
+ use Encode qw( encode );
48
49
use POSIX qw { strftime ceil};
49
50
50
51
# Digest::MD5 isn't in the standard distribution. Use it only if installed.
@@ -60,8 +61,6 @@ use Digest::MD5;
60
61
# Time::HiRes became standard with Perl 5.8
61
62
my $HAVE_Time_HiRes = 1;
62
63
use Time::HiRes;
63
- #eval "use Time::HiRes;";
64
- #$HAVE_Time_HiRes = 1 if defined $Time::HiRes::VERSION;
65
64
66
65
my $HAVE_Rexexp_Common = 1;
67
66
# Regexp::Common isn't in the standard distribution. It will
273
272
$opt_no_recurse ,
274
273
$opt_only_count_files ,
275
274
$opt_fmt ,
275
+ $opt_encoding ,
276
276
);
277
277
278
278
my $getopt_success = GetOptions( # {{{1
@@ -380,6 +380,7 @@ my $getopt_success = GetOptions( # {{{1
380
380
"no_recurse|no-recurse" => \$opt_no_recurse ,
381
381
"only_count_files|only-count-files" => \$opt_only_count_files ,
382
382
"fmt=i" => \$opt_fmt ,
383
+ "encoding=s" => \$opt_encoding , # not production ready #880
383
384
);
384
385
# 1}}}
385
386
$config_file = $opt_config_file if defined $opt_config_file;
@@ -791,6 +792,7 @@ my %Extension_Collision = (
791
792
'Verilog-SystemVerilog/Coq' => [ 'v' ] ,
792
793
'Visual Basic/TeX/Apex Class' => [ 'cls' ] ,
793
794
'Scheme/SaltStack' => [ 'sls' ] ,
795
+ 'SKILL/.NET IL' => [ 'il' ] ,
794
796
);
795
797
my @Autogen_to_ignore = no_autogen_files($list_no_autogen);
796
798
if ($opt_force_lang_def) {
@@ -6463,16 +6465,19 @@ sub open_file { # {{{1
6463
6465
$filename, # filename to open
6464
6466
$use_new_file, # whether to use `new IO::File` or `open` when not using Win32::LongPath
6465
6467
) = @_;
6466
- if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {
6467
- my $file = undef;
6468
- openL(\$file, $mode, $filename);
6469
- return $file;
6470
- } elsif ($use_new_file) {
6471
- return new IO::File $filename, $mode;
6468
+ my $fh = undef;
6469
+ if (defined $opt_encoding) {
6470
+ open($fh,"<:encoding($opt_encoding)", $filename) or
6471
+ die "Failed open('<:encoding($opt_encoding)', $filename): $!";
6472
+ } else {
6473
+ if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {
6474
+ openL(\$fh, $mode, $filename);
6475
+ } elsif ($use_new_file) {
6476
+ return new IO::File $filename, $mode;
6477
+ }
6478
+ open($fh, $mode, $filename);
6472
6479
}
6473
- my $file = undef;
6474
- open($file, $mode, $filename);
6475
- return $file;
6480
+ return $fh;
6476
6481
} # 1}}}
6477
6482
sub unlink_file { # {{{1
6478
6483
# portable method to unlink a file. On Windows this uses Win32::LongPath to
@@ -6753,6 +6758,8 @@ sub classify_file { # {{{1
6753
6758
} elsif ($Language_by_Extension{$extension} eq 'Pascal/Pawn') {
6754
6759
my $lang_p_or_p = "";
6755
6760
return Pascal_or_Pawn($full_file, $rh_Err, $raa_errors);
6761
+ } elsif ($Language_by_Extension{$extension} eq 'SKILL/.NET IL') {
6762
+ return SKILL_or_DotNetIL($full_file, $rh_Err, $raa_errors);
6756
6763
} elsif ($Language_by_Extension{$extension} eq 'Brainfuck') {
6757
6764
if (really_is_bf($full_file)) {
6758
6765
return $Language_by_Extension{$extension};
@@ -8919,7 +8926,7 @@ sub set_constants { # {{{1
8919
8926
'ipl' => 'IPL' ,
8920
8927
'pro' => 'IDL/Qt Project/Prolog/ProGuard' ,
8921
8928
'ig' => 'Modula3' ,
8922
- 'il' => 'SKILL' ,
8929
+ 'il' => 'SKILL/.NET IL' ,
8923
8930
'ils' => 'SKILL++' ,
8924
8931
'inc' => 'PHP/Pascal/Fortran/Pawn',
8925
8932
'ino' => 'Arduino Sketch' ,
@@ -9035,6 +9042,10 @@ sub set_constants { # {{{1
9035
9042
'mojom' => 'Mojom' ,
9036
9043
'mojo' => 'Mojo' ,
9037
9044
'🔥' => 'Mojo' ,
9045
+ 'mbt' => 'MoonBit' ,
9046
+ 'mbti' => 'MoonBit' ,
9047
+ 'mbtx' => 'MoonBit' ,
9048
+ 'mbty' => 'MoonBit' ,
9038
9049
'meson.build' => 'Meson' ,
9039
9050
'metal' => 'Metal' ,
9040
9051
'mk' => 'make' ,
@@ -10520,6 +10531,7 @@ sub set_constants { # {{{1
10520
10531
[ 'call_regexp_common' , 'C' ],
10521
10532
[ 'remove_inline' , '#.*$' ],
10522
10533
],
10534
+ 'MoonBit' => [ [ 'remove_matches' , '^\s*//' ], ],
10523
10535
'Nemerle' => [
10524
10536
[ 'rm_comments_in_strings', '"', '/*', '*/' ],
10525
10537
[ 'rm_comments_in_strings', '"', '//', '' ],
@@ -10564,6 +10576,11 @@ sub set_constants { # {{{1
10564
10576
'Mustache' => [
10565
10577
[ 'remove_between_general', '{{!', '}}' ],
10566
10578
],
10579
+ '.NET IL' => [
10580
+ [ 'rm_comments_in_strings', '"', '/*', '*/' ],
10581
+ [ 'rm_comments_in_strings', '"', '//', '' ],
10582
+ [ 'call_regexp_common' , 'C++' ],
10583
+ ],
10567
10584
'Nickel' => [
10568
10585
[ 'remove_matches' , '^\s*#' ],
10569
10586
[ 'remove_inline' , '#.*$' ],
@@ -10909,6 +10926,7 @@ sub set_constants { # {{{1
10909
10926
[ 'rm_comments_in_strings', '"', '//', '' ],
10910
10927
[ 'call_regexp_common' , 'C++' ],
10911
10928
],
10929
+ 'SKILL/.NET IL' => [ [ 'die' , ], ], # never called
10912
10930
'SKILL' => [
10913
10931
[ 'call_regexp_common' , 'C' ],
10914
10932
[ 'remove_matches' , '^\s*;' ],
@@ -11756,8 +11774,10 @@ sub set_constants { # {{{1
11756
11774
'Modelica' => 2.00,
11757
11775
'MUMPS' => 4.21,
11758
11776
'Mustache' => 1.75,
11777
+ 'MoonBit' => 2.50,
11759
11778
'Nastran' => 1.13,
11760
11779
'Nemerle' => 2.50,
11780
+ '.NET IL' => 3.00,
11761
11781
'NetLogo' => 4.00,
11762
11782
'Nickel' => 2.00,
11763
11783
'Nim' => 2.00,
@@ -11964,6 +11984,7 @@ sub set_constants { # {{{1
11964
11984
'Verilog-SystemVerilog/Coq' => 1.00,
11965
11985
'MATLAB/Mathematica/Objective-C/MUMPS/Mercury' => 1.00,
11966
11986
'IDL/Qt Project/Prolog/ProGuard' => 1.00,
11987
+ 'SKILL/.NET IL' => 1.00,
11967
11988
);
11968
11989
# 1}}}
11969
11990
%{$rh_Known_Binary_Archives} = ( # {{{1
@@ -12969,6 +12990,44 @@ sub Pascal_or_Pawn { # {{{1
12969
12990
return "Pawn";
12970
12991
}
12971
12992
} # 1}}}
12993
+ sub SKILL_or_DotNetIL { # {{{1
12994
+ my ($file , # in
12995
+ $rh_Err , # in hash of error codes
12996
+ $raa_errors , # out
12997
+ ) = @_;
12998
+
12999
+ print "-> SKILL_or_DotNetIL($file)\n" if $opt_v > 2;
13000
+
13001
+ my $lang = undef;
13002
+ my $IN = open_file('<', $file, 1);
13003
+ if (!defined $IN) {
13004
+ push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
13005
+ return $lang;
13006
+ }
13007
+ my $skill = 0;
13008
+ my $dnet_il = 0;
13009
+ while (<$IN>) {
13010
+ next if /^\s*$/;
13011
+ if (/^\s*;/) {
13012
+ $skill += 50;
13013
+ } elsif (/^\.(class|assembly|method|custom|entrypoint)/) {
13014
+ $dnet_il += 50;
13015
+ last;
13016
+ } elsif (/{\s*$/ or /^\s*}/) {
13017
+ $dnet_il += 5;
13018
+ } elsif (/^\s*(procedure|let|foreach)\b/) {
13019
+ $skill += 1;
13020
+ }
13021
+ }
13022
+ $IN->close;
13023
+
13024
+ print "<- SKILL_or_DotNetIL($file: SKILL=$skill, .NET IL=$dnet_il\n" if $opt_v > 2;
13025
+ if ($skill > $dnet_il) {
13026
+ return "SKILL";
13027
+ } else {
13028
+ return ".NET IL";
13029
+ }
13030
+ } # 1}}}
12972
13031
sub html_colored_text { # {{{1
12973
13032
# http://www.pagetutor.com/pagetutor/makapage/pics/net216-2.gif
12974
13033
my ($color, $text) = @_;
0 commit comments