|
2 | 2 |
|
3 | 3 | use strict;
|
4 | 4 | use warnings;
|
5 |
| -use File::Find; |
6 |
| -use Getopt::Long; |
7 | 5 |
|
8 |
| -my $basedir = "."; |
9 |
| -GetOptions("basedir=s" => \$basedir) |
10 |
| - or die("Cannot parse command line arguments\n"); |
| 6 | +# Parse arguments, a simple state machine for input like: |
| 7 | +# |
| 8 | +# howto/*.txt config/*.txt --section=1 git.txt git-add.txt [...] --to-lint git-add.txt a-file.txt [...] |
| 9 | +my %TXT; |
| 10 | +my %SECTION; |
| 11 | +my $section; |
| 12 | +my $lint_these = 0; |
| 13 | +for my $arg (@ARGV) { |
| 14 | + if (my ($sec) = $arg =~ /^--section=(\d+)$/s) { |
| 15 | + $section = $sec; |
| 16 | + next; |
| 17 | + } |
11 | 18 |
|
12 |
| -my $found_errors = 0; |
| 19 | + my ($name) = $arg =~ /^(.*?)\.txt$/s; |
| 20 | + unless (defined $section) { |
| 21 | + $TXT{$name} = $arg; |
| 22 | + next; |
| 23 | + } |
13 | 24 |
|
14 |
| -sub report { |
15 |
| - my ($where, $what, $error) = @_; |
16 |
| - print "$where: $error: $what\n"; |
17 |
| - $found_errors = 1; |
| 25 | + $SECTION{$name} = $section; |
18 | 26 | }
|
19 | 27 |
|
20 |
| -sub grab_section { |
21 |
| - my ($page) = @_; |
22 |
| - open my $fh, "<", "$basedir/$page.txt"; |
23 |
| - my $firstline = <$fh>; |
24 |
| - chomp $firstline; |
25 |
| - close $fh; |
26 |
| - my ($section) = ($firstline =~ /.*\((\d)\)$/); |
27 |
| - return $section; |
| 28 | +my $exit_code = 0; |
| 29 | +sub report { |
| 30 | + my ($pos, $line, $target, $msg) = @_; |
| 31 | + substr($line, $pos) = "' <-- HERE"; |
| 32 | + $line =~ s/^\s+//; |
| 33 | + print "$ARGV:$.: error: $target: $msg, shown with 'HERE' below:\n"; |
| 34 | + print "$ARGV:$.:\t'$line\n"; |
| 35 | + $exit_code = 1; |
28 | 36 | }
|
29 | 37 |
|
30 |
| -sub lint { |
31 |
| - my ($file) = @_; |
32 |
| - open my $fh, "<", $file |
33 |
| - or return; |
34 |
| - while (<$fh>) { |
35 |
| - my $where = "$file:$."; |
36 |
| - while (s/linkgit:((.*?)\[(\d)\])//) { |
37 |
| - my ($target, $page, $section) = ($1, $2, $3); |
| 38 | +@ARGV = sort values %TXT; |
| 39 | +die "BUG: Nothing to process!" unless @ARGV; |
| 40 | +while (<>) { |
| 41 | + my $line = $_; |
| 42 | + while ($line =~ m/linkgit:((.*?)\[(\d)\])/g) { |
| 43 | + my $pos = pos $line; |
| 44 | + my ($target, $page, $section) = ($1, $2, $3); |
38 | 45 |
|
39 |
| - # De-AsciiDoc |
40 |
| - $page =~ s/{litdd}/--/g; |
| 46 | + # De-AsciiDoc |
| 47 | + $page =~ s/{litdd}/--/g; |
41 | 48 |
|
42 |
| - if ($page !~ /^git/) { |
43 |
| - report($where, $target, "nongit link"); |
44 |
| - next; |
45 |
| - } |
46 |
| - if (! -f "$basedir/$page.txt") { |
47 |
| - report($where, $target, "no such source"); |
48 |
| - next; |
49 |
| - } |
50 |
| - my $real_section = grab_section($page); |
51 |
| - if ($real_section != $section) { |
52 |
| - report($where, $target, |
53 |
| - "wrong section (should be $real_section)"); |
54 |
| - next; |
55 |
| - } |
| 49 | + if (!exists $TXT{$page}) { |
| 50 | + report($pos, $line, $target, "link outside of our own docs"); |
| 51 | + next; |
| 52 | + } |
| 53 | + if (!exists $SECTION{$page}) { |
| 54 | + report($pos, $line, $target, "link outside of our sectioned docs"); |
| 55 | + next; |
| 56 | + } |
| 57 | + my $real_section = $SECTION{$page}; |
| 58 | + if ($section != $SECTION{$page}) { |
| 59 | + report($pos, $line, $target, "wrong section (should be $real_section)"); |
| 60 | + next; |
56 | 61 | }
|
57 | 62 | }
|
58 |
| - close $fh; |
59 |
| -} |
60 |
| - |
61 |
| -sub lint_it { |
62 |
| - lint($File::Find::name) if -f && /\.txt$/; |
63 |
| -} |
64 |
| - |
65 |
| -if (!@ARGV) { |
66 |
| - find({ wanted => \&lint_it, no_chdir => 1 }, $basedir); |
67 |
| -} else { |
68 |
| - for (@ARGV) { |
69 |
| - lint($_); |
70 |
| - } |
| 63 | + # this resets our $. for each file |
| 64 | + close ARGV if eof; |
71 | 65 | }
|
72 | 66 |
|
73 |
| -exit $found_errors; |
| 67 | +exit $exit_code; |
0 commit comments