1 #!/usr/bin/env perl !! 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 << 3 # << 4 # Treewide grep for references to files under 2 # Treewide grep for references to files under Documentation, and report 5 # non-existing files in stderr. 3 # non-existing files in stderr. 6 4 7 use warnings; !! 5 for f in $(git ls-files); do 8 use strict; !! 6 for ref in $(grep -ho "Documentation/[A-Za-z0-9_.,~/*+-]*" "$f"); do 9 use Getopt::Long qw(:config no_auto_abbrev); !! 7 # presume trailing . and , are not part of the name 10 !! 8 ref=${ref%%[.,]} 11 # NOTE: only add things here when the file was !! 9 12 # to mention a past documentation file, for ex !! 10 # use ls to handle wildcards 13 # the original work. !! 11 if ! ls $ref >/dev/null 2>&1; then 14 my %false_positives = ( !! 12 echo "$f: $ref" >&2 15 "Documentation/scsi/scsi_mid_low_api.r !! 13 fi 16 "drivers/vhost/vhost.c" => "Documentat !! 14 done 17 ); !! 15 done 18 << 19 my $scriptname = $0; << 20 $scriptname =~ s,.*/([^/]+/),$1,; << 21 << 22 # Parse arguments << 23 my $help = 0; << 24 my $fix = 0; << 25 my $warn = 0; << 26 << 27 if (! -e ".git") { << 28 printf "Warning: can't check if file e << 29 exit 0; << 30 } << 31 << 32 GetOptions( << 33 'fix' => \$fix, << 34 'warn' => \$warn, << 35 'h|help|usage' => \$help, << 36 ); << 37 << 38 if ($help != 0) { << 39 print "$scriptname [--help] [--fix]\n"; << 40 exit -1; << 41 } << 42 << 43 # Step 1: find broken references << 44 print "Finding broken references. This may tak << 45 << 46 my %broken_ref; << 47 << 48 my $doc_fix = 0; << 49 << 50 open IN, "git grep ':doc:\`' Documentation/|" << 51 or die "Failed to run git grep"; << 52 while (<IN>) { << 53 next if (!m,^([^:]+):.*\:doc\:\`([^\`] << 54 next if (m,sphinx/,); << 55 << 56 my $file = $1; << 57 my $d = $1; << 58 my $doc_ref = $2; << 59 << 60 my $f = $doc_ref; << 61 << 62 $d =~ s,(.*/).*,$1,; << 63 $f =~ s,.*\<([^\>]+)\>,$1,; << 64 << 65 if ($f =~ m,^/,) { << 66 $f = "$f.rst"; << 67 $f =~ s,^/,Documentation/,; << 68 } else { << 69 $f = "$d$f.rst"; << 70 } << 71 << 72 next if (grep -e, glob("$f")); << 73 << 74 if ($fix && !$doc_fix) { << 75 print STDERR "\nWARNING: Curre << 76 } << 77 $doc_fix++; << 78 << 79 print STDERR "$file: :doc:`$doc_ref`\n << 80 } << 81 close IN; << 82 << 83 open IN, "git grep 'Documentation/'|" << 84 or die "Failed to run git grep"; << 85 while (<IN>) { << 86 next if (!m/^([^:]+):(.*)/); << 87 << 88 my $f = $1; << 89 my $ln = $2; << 90 << 91 # On linux-next, discard the Next/ dir << 92 next if ($f =~ m,^Next/,); << 93 << 94 # Makefiles and scripts contain nasty << 95 next if ($f =~ m/Makefile/ || $f =~ m/ << 96 << 97 # It doesn't make sense to parse hidde << 98 next if ($f =~ m#/\.#); << 99 << 100 # Skip this script << 101 next if ($f eq $scriptname); << 102 << 103 # Ignore the dir where documentation w << 104 next if ($ln =~ m,\b(\S*)Documentation << 105 << 106 if ($ln =~ m,\b(\S*)(Documentation/[A- << 107 my $prefix = $1; << 108 my $ref = $2; << 109 my $base = $2; << 110 my $extra = $3; << 111 << 112 # some file references are lik << 113 # /usr/src/linux/Documentation << 114 # For now, ignore them << 115 next if ($extra =~ m/^{/); << 116 << 117 # Remove footnotes at the end << 118 # Documentation/devicetree/dt- << 119 $ref =~ s/(txt|rst)\[\d+]$/$1/ << 120 << 121 # Remove ending ']' without an << 122 $ref =~ s/\].*// if (!($ref =~ << 123 << 124 # Remove puntuation marks at t << 125 $ref =~ s/[\,\.]+$//; << 126 << 127 my $fulref = "$prefix$ref"; << 128 << 129 $fulref =~ s/^(\<file|ref)://; << 130 $fulref =~ s/^[\'\`]+//; << 131 $fulref =~ s,^\$\(.*\)/,,; << 132 $base =~ s,.*/,,; << 133 << 134 # Remove URL false-positives << 135 next if ($fulref =~ m/^http/); << 136 << 137 # Remove sched-pelt false-posi << 138 next if ($fulref =~ m,^Documen << 139 << 140 # Discard some build examples << 141 next if ($fulref =~ m,mnt/sdb/ << 142 << 143 # Check if exists, evaluating << 144 next if (grep -e, glob("$ref $ << 145 << 146 # Accept relative Documentatio << 147 if ($f =~ m/tools/) { << 148 my $path = $f; << 149 $path =~ s,(.*)/.*,$1, << 150 $path =~ s,testing/sel << 151 next if (grep -e, glob << 152 } << 153 << 154 # Discard known false-positive << 155 if (defined($false_positives{$ << 156 next if ($false_positi << 157 } << 158 << 159 if ($fix) { << 160 if (!($ref =~ m/(scrip << 161 $broken_ref{$r << 162 } << 163 } elsif ($warn) { << 164 print STDERR "Warning: << 165 } else { << 166 print STDERR "$f: $ful << 167 } << 168 } << 169 } << 170 close IN; << 171 << 172 exit 0 if (!$fix); << 173 << 174 # Step 2: Seek for file name alternatives << 175 print "Auto-fixing broken references. Please d << 176 << 177 foreach my $ref (keys %broken_ref) { << 178 my $new =$ref; << 179 << 180 my $basedir = "."; << 181 # On translations, only seek inside th << 182 $basedir = $1 if ($ref =~ m,(Document << 183 << 184 # get just the basename << 185 $new =~ s,.*/,,; << 186 << 187 my $f=""; << 188 << 189 # usual reason for breakage: DT file m << 190 if ($ref =~ /devicetree/) { << 191 # usual reason for breakage: D << 192 if (!$f) { << 193 my $new_ref = $ref; << 194 $new_ref =~ s/\.txt$/. << 195 $f=$new_ref if (-f $ne << 196 } << 197 << 198 if (!$f) { << 199 my $search = $new; << 200 $search =~ s,^.*/,,; << 201 $f = qx(find Documenta << 202 if (!$f) { << 203 # Manufacturer << 204 $search =~ s/^ << 205 $f = qx(find D << 206 } << 207 } << 208 } << 209 << 210 # usual reason for breakage: file rena << 211 if (!$f) { << 212 $new =~ s/\.txt$/.rst/; << 213 $f=qx(find $basedir -iname $ne << 214 } << 215 << 216 # usual reason for breakage: use dash << 217 if (!$f) { << 218 $new =~ s/[-_]/[-_]/g; << 219 $f=qx(find $basedir -iname $ne << 220 } << 221 << 222 # Wild guess: seek for the same name o << 223 if (!$f) { << 224 $f = qx(find $basedir -iname $ << 225 } << 226 << 227 my @find = split /\s+/, $f; << 228 << 229 if (!$f) { << 230 print STDERR "ERROR: Didn't fi << 231 } elsif (scalar(@find) > 1) { << 232 print STDERR "WARNING: Won't a << 233 foreach my $j (@find) { << 234 $j =~ s,^./,,; << 235 print STDERR " $j\n << 236 } << 237 } else { << 238 $f = $find[0]; << 239 $f =~ s,^./,,; << 240 print "INFO: Replacing $ref to << 241 foreach my $j (qx(git grep -l << 242 qx(sed "s\@$ref\@$f\@g << 243 } << 244 } << 245 } <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.