@@ -1744,6 +1744,25 @@ if ($opt_count_diff) {
1744
1744
exit if $opt_count_diff > 3;
1745
1745
goto Top_of_Processing_Loop;
1746
1746
}
1747
+ suggest_remedies_for_errors(\@Errors) if @Errors;
1748
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1749
+ sub suggest_remedies_for_errors { # {{{1
1750
+ my ($raa_errors) = @_; # [ [ numeric error code, filename], .. ]
1751
+ my $hit_timeout = 0;
1752
+ foreach my $pair (@{$raa_errors}) {
1753
+ my ($code, $file) = @{$pair};
1754
+ $hit_timeout = $code == -5 ? 1 : $hit_timeout;
1755
+ }
1756
+ if ($hit_timeout) {
1757
+ print "\n";
1758
+ print "One or more files took longer to process than expected.\n";
1759
+ print "Try rerunning without timeout guards by adding --timeout 0\n";
1760
+ print "to your command line arguments. See the documentation on\n";
1761
+ print "the --timeout switch for more information.\n";
1762
+ print "\n";
1763
+ }
1764
+ }
1765
+ # 1}}}
1747
1766
sub brief_usage { # {{{1
1748
1767
return "
1749
1768
cloc -- Count Lines of Code
@@ -7301,6 +7320,15 @@ sub rm_comments { # {{{1
7301
7320
# a corresponding */ can cause huge delays so put a timer on this.
7302
7321
my $max_duration_sec = scalar(@lines)/1000.0; # est lines per second
7303
7322
$max_duration_sec = 1.0 if $max_duration_sec < 1;
7323
+ # add a scale factor for super long lines
7324
+ my $max_line_len = 0;
7325
+ foreach my $line (@lines) {
7326
+ my $len = length($line);
7327
+ $max_line_len = $len if $len > $max_line_len;
7328
+ }
7329
+ if ($max_line_len > 1000) {
7330
+ $max_duration_sec *= $max_line_len / 2000;
7331
+ }
7304
7332
if (defined $opt_timeout) {
7305
7333
$max_duration_sec = $opt_timeout if $opt_timeout > 0;
7306
7334
}
@@ -7312,6 +7340,7 @@ sub rm_comments { # {{{1
7312
7340
@lines = &{$subroutine}(\@lines, @args); # apply filter...
7313
7341
alarm 0;
7314
7342
};
7343
+ #$@ = "alarm\n"; # to trigger the timeout case in tests
7315
7344
if ($@) {
7316
7345
# timed out
7317
7346
die unless $@ eq "alarm\n";
@@ -13536,6 +13565,69 @@ sub align_by_pairs { # {{{1
13536
13565
#print Dumper("align_by_pairs", @files_L_minus_dir, @files_R_minus_dir);
13537
13566
#die;
13538
13567
} # 1}}}
13568
+ sub align_from_git { # {{{1
13569
+ # have git identify the files that changed, as well as how
13570
+ my ($L_tag , # in
13571
+ $R_tag , # in
13572
+ $ra_added , # out
13573
+ $ra_removed , # out
13574
+ $ra_compare_list , # out
13575
+ $rh_renamed , # out
13576
+ ) = @_;
13577
+ print "-> align_from_git()\n" if $opt_v > 2;
13578
+
13579
+ # On the command line, L_tag and R_tag are commit hashes or tags. Here they are
13580
+ # replaced with temp directories like /tmp/vGxIL7AWRw and /tmp/BS400yIQEl
13581
+ my $cmd = "git -c \"safe.directory=*\" --no-pager diff --name-status --diff-filter=ADRM $L_tag $R_tag";
13582
+
13583
+ # A = added, D = deleted, M = modified, R = renamed; entries tab separated
13584
+ # Example:
13585
+ # M README.md
13586
+ # R089 package.json dist/pack age.json-AND
13587
+ # M package-lock.json
13588
+ # A src/apps/compare-tags-branches-commits-llm-explanation/README.md
13589
+ # A src/internals/cloc-git/cloc-diff-rel.ts
13590
+ # D src/internals/cloc-git/cloc-git-diff-rel-between-commits.ts
13591
+
13592
+ print $cmd, "\n" if $opt_v > 1;
13593
+ open(GSIM, "$cmd |") or die "Unable to run $cmd $!";
13594
+ while (<GSIM>) {
13595
+ chomp;
13596
+ my @words = split(/\t/);
13597
+ #print "align_from_git: words=[@words]\n";
13598
+ if (scalar(@words) == 2) {
13599
+ if ($words[0] =~ /^M/) {
13600
+ ( my $right = $words[1] ) =~ s[^${L_tag}/][${R_tag}/];
13601
+ push @{$ra_compare_list}, [ $words[1], $right ];
13602
+ } elsif ($words[0] =~ /^A/) {
13603
+ push @{$ra_added} , $words[1];
13604
+ } elsif ($words[0] =~ /^D/) {
13605
+ push @{$ra_removed}, $words[1];
13606
+ } else {
13607
+ die "cloc.align_from_git() parse failure with [$_]\n";
13608
+ }
13609
+ } elsif (scalar(@words) == 3) {
13610
+ if ($words[0] =~ /^R/) { # rename
13611
+ ( my $clean_L = $words[1] ) =~ s[^${L_tag}/][];
13612
+ ( my $clean_R = $words[2] ) =~ s[^${R_tag}/][];
13613
+ $rh_renamed->{ $clean_L } = $clean_R;
13614
+ push @{$ra_compare_list}, [ $words[1], $words[2] ];
13615
+ } elsif ($words[0] =~ /^A/) {
13616
+ push @{$ra_added} , $words[1];
13617
+ } elsif ($words[0] =~ /^D/) {
13618
+ push @{$ra_removed}, $words[1];
13619
+ } else {
13620
+ die "cloc.align_from_git() parse failure with [$_]\n";
13621
+ }
13622
+ } else {
13623
+ die "Unexpected output from git diff --name-status\n";
13624
+ }
13625
+ }
13626
+ close(GSIM);
13627
+
13628
+ print "<- align_from_git()\n" if $opt_v > 2;
13629
+ return;
13630
+ } # 1}}}
13539
13631
sub html_header { # {{{1
13540
13632
my ($title , ) = @_;
13541
13633
0 commit comments