1f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#! /usr/bin/perl
2f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich# A script to scan PCRE's man pages to check for typos in the control
4f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich# sequences. I use only a small set of the available repertoire, so it is 
5f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich# straightforward to check that nothing else has slipped in by mistake. This
6f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich# script should be called in the doc directory.
7f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
8f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich$yield = 0;
9f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
10f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (scalar(@ARGV) > 0)
11f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
12f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  $line = 0; 
13f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  $file = shift @ARGV;
14f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    
15f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  open (IN, $file) || die "Failed to open $file\n";
16f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  
17f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (<IN>)
18f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {  
19f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    $line++; 
20f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (/^\s*$/)
21f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
22f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      printf "Empty line $line of $file\n";
23f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      $yield = 1;  
24f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }   
25f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    elsif (/^\./)
26f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
27f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (!/^\.\s*$|
28f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.B\s+\S| 
29f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.TH\s\S|
30f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.SH\s\S|
31f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.SS\s\S|
32f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.TP(?:\s?\d+)?\s*$|
33f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.SM\s*$|
34f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.br\s*$| 
35f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.rs\s*$| 
36f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.sp\s*$| 
37f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.nf\s*$| 
38f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.fi\s*$| 
39f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.P\s*$| 
40f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.PP\s*$| 
41f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.\\"(?:\ HREF)?\s*$|
42f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.\\"\sHTML\s<a\shref="[^"]+?">\s*$|
43f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.\\"\sHTML\s<a\sname="[^"]+?"><\/a>\s*$|
44f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.\\"\s<\/a>\s*$|
45f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.\\"\sJOINSH\s*$|
46f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            ^\.\\"\sJOIN\s*$/x  
47f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich         )
48f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
49f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        printf "Bad control line $line of $file\n";
50f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        $yield = 1;
51f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
52f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
53f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else
54f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
55f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (/\\[^ef]|\\f[^IBP]/)
56f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
57f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        printf "Bad backslash in line $line of $file\n";  
58f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        $yield = 1; 
59f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        } 
60f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }   
61f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
62f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich     
63f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  close(IN);   
64f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
65f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  
66f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichexit $yield;
67f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich# End  
68