]> git.lyx.org Git - lyx.git/blob - development/checkurls/search_url.pl
Cmake build tests: href entries checked
[lyx.git] / development / checkurls / search_url.pl
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3 #
4 # file search_url.pl
5 # script to search for url's in lyxfiles
6 # and testing their validity.
7 #
8 # Syntax: search_url.pl [(filesToScan|(ignored|reverted|extra|selected)URLS)={path_to_control]*
9 # Param value is a path to a file containing list of xxx:
10 # filesToScan={xxx = lyx-file-names to be scanned for}
11 # ignoredURLS={xxx = urls that are discarded from test}
12 # revertedURLS={xxx = urls that should fail, to test the test with invalid urls}
13 # extraURLS={xxx = urls which should be also checked}
14 #
15 # This file is free software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public
17 # License as published by the Free Software Foundation; either
18 # version 2 of the License, or (at your option) any later version.
19 #
20 # This software is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 # General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public
26 # License along with this software; if not, write to the Free Software
27 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 #
29 # Copyright (c) 2013 Kornel Benko <kornel@lyx.org>
30 #           (c) 2013 Scott Kostyshak <skotysh@lyx.org>
31
32 use strict;
33
34 BEGIN  {
35   use File::Spec;
36   my $p = File::Spec->rel2abs(__FILE__);
37   $p =~ s/[\/\\]?[^\/\\]+$//;
38   unshift(@INC, "$p");
39 }
40
41 use CheckURL;
42
43 $ENV{LANG} = "en";
44 $ENV{LANGUAGE} = "en";
45
46 my %URLS = ();
47 my %ignoredURLS = ();
48 my %revertedURLS = ();
49 my %extraURLS = ();
50 my %selectedURLS = ();
51
52 my $checkSelectedOnly = 0;
53 for my $arg (@ARGV) {
54   die("Bad argument \"$arg\"") if ($arg !~ /=/);
55   my ($type,$val) = split("=", $arg);
56   if ($type eq "filesToScan") {
57     #The file should be a list of files to search in
58     if (open(FLIST, $val)) {
59       while (my $l = <FLIST>) {
60         chomp($l);
61         &parse_file($l);
62       }
63       close(FLIST);
64     }
65   }
66   elsif ($type eq "ignoredURLS") {
67     &readUrls($val, \%ignoredURLS);
68   }
69   elsif ($type eq "revertedURLS") {
70     &readUrls($val, \%revertedURLS);
71   }
72   elsif ($type eq "extraURLS") {
73     &readUrls($val,  \%extraURLS);
74   }
75   elsif ($type eq "selectedURLS") {
76     $checkSelectedOnly = 1;
77     &readUrls($val,  \%selectedURLS);
78   }
79   else {
80     die("Invalid argument \"$arg\"");
81   }
82 }
83
84 my @urls = sort keys %URLS, keys %extraURLS;
85 my $errorcount = 0;
86
87 my $URLScount = 0;
88
89 for my $u (@urls) {
90   if (defined($ignoredURLS{$u})) {
91     $ignoredURLS{$u} += 1;
92     next;
93   }
94   next if ($checkSelectedOnly && ! defined(${selectedURLS}{$u}));
95   if (defined(${selectedURLS}{$u})) {
96     ${selectedURLS}{$u} += 1;
97   }
98   $URLScount++;
99   print "Checking '$u'";
100   my $res = &check_url($u);
101   if ($res) {
102     print ": Failed\n";
103   }
104   else {
105     print ": OK\n";
106   }
107   my $printSourceFiles = 0;
108   my $err_txt = "Error url:";
109
110   if ($res || $checkSelectedOnly) {
111     $printSourceFiles = 1;
112   }
113   if ($res && defined($revertedURLS{$u})) {
114     $err_txt = "Failed url:";
115   }
116   $res = ! $res if (defined($revertedURLS{$u}));
117   if ($res || $checkSelectedOnly) {
118     print "$err_txt \"$u\"\n";
119   }
120   if ($printSourceFiles) {
121     if (defined($URLS{$u})) {
122       for my $f(sort keys %{$URLS{$u}}) {
123         my $lines = ":" . join(',', @{$URLS{$u}->{$f}});
124         print "  $f$lines\n";
125       }
126     }
127     if ($res ) {
128       $errorcount++;
129     }
130   }
131 }
132
133 &printNotUsedURLS("Ignored", \%ignoredURLS);
134 &printNotUsedURLS("Selected", \%selectedURLS);
135
136 print "\n$errorcount URL-tests failed out of $URLScount\n\n";
137 exit($errorcount);
138
139 ###############################################################################
140
141 sub printNotUsedURLS($$)
142 {
143   my ($txt, $rURLS) = @_;
144   my @msg = ();
145   for my $u ( sort keys %{$rURLS}) {
146     if ($rURLS->{$u} < 2) {
147       push(@msg, $u);
148     }
149   }
150   if (@msg) {
151     print "\n$txt URLs not found in sources: " . join(' ',@msg) . "\n";
152   }
153 }
154
155 sub readUrls($$)
156 {
157   my ($file, $rUrls) = @_;
158
159   die("Could not read file $file") if (! open(ULIST, $file));
160   while (my $l = <ULIST>) {
161     $l =~ s/[\r\n]+$//;         # remove eol
162     $l =~ s/\s*\#.*$//;         # remove comment
163     next if ($l eq "");
164     $rUrls->{$l} = 1;
165   }
166   close(ULIST);
167 }
168
169 sub parse_file($)
170 {
171   my($f) = @_;
172   my $status = "out";           # outside of URL
173
174   return if ($f =~ /\/attic\//);
175   if(open(FI, $f)) {
176     my $line = 0;
177     while(my $l = <FI>) {
178       $line++;
179       $l =~ s/[\r\n]+$//;       #  Simulate chomp
180       if ($status eq "out") {
181         # searching for "\begin_inset Flex URL"
182         if($l =~ /^\s*\\begin_inset\s+Flex\s+URL\s*$/) {
183           $status = "inUrlInset";
184         }
185         elsif ($l =~ /^\s*\\begin_inset\s+CommandInset\s+href\s*$/) {
186           $status = "inHrefInset";
187         }
188         else {
189           # Outside of url, check also
190           if ($l =~ /"((ftp|http|https):\/\/[^ ]+)"/) {
191             my $url = $1;
192             &handle_url($url, $f, "x$line");
193           }
194         }
195       }
196       else {
197         if($l =~ /^\s*\\end_(layout|inset)\s*$/) {
198           $status = "out";
199         }
200         elsif ($status eq "inUrlInset") {
201           if ($l =~ /\s*([a-z]+:\/\/.+)\s*$/) {
202             my $url = $1;
203             $status = "out";
204             &handle_url($url, $f, "u$line");
205           }
206         }
207         elsif ($status eq "inHrefInset") {
208           if ($l =~ /^target\s+"([a-z]+:\/\/[^ ]+)"$/) {
209             my $url = $1;
210             $status = "out";
211             &handle_url($url, $f, "h$line");
212           }
213         }
214       }
215     }
216     close(FI);
217   }
218 }
219
220 sub handle_url($$$)
221 {
222   my($url, $f, $line) = @_;
223
224   if(!defined($URLS{$url})) {
225     $URLS{$url} = {};
226     $URLS{$url}->{$f} = [];
227   }
228   push(@{$URLS{$url}->{$f}}, $line);
229 }