fixnavi.pl 6.67 KB
Newer Older
1
#! /usr/bin/perl
2

3
use warnings;
4 5
use strict;

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
sub visitDir($)
{
    my ($dir) = @_;
    my @ret = ();
    my @subret = ();
    opendir DIR, $dir or die "$dir: $!\n";
    my @ents = readdir DIR;
    closedir DIR;
    for my $ent (grep !/^\./, @ents) {
        my $ret = $dir."/".$ent;
        if (-d $ret) {
            push @subret, &visitDir($ret);
        } elsif ($ret =~ /\.qdoc$/) {
            push @ret, $ret;
        }
    }
    return @ret, @subret;
}

25 26 27 28 29 30 31 32 33
my @files = ();
my %defines = ();
for (@ARGV) {
    if (/^-D(.*)$/) {
        $defines{$1} = 1;
    } elsif (/^-/) {
        printf STDERR "Unknown option '".$_."'\n";
        exit 1;
    } else {
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
34 35 36 37 38
        if (-d $_) {
            push @files, visitDir($_);
        } else {
            push @files, $_;
        }
39 40 41
    }
}

42
int(@files) or die "usage: $0 [-D<define>]... <qdoc-file>...\n";
43

44
my @toc = ();
45
my %title2type = ();
46 47
my %title2page = ();
my $doctitle = "";
48 49
my %prev_skips = ();
my %next_skips = ();
50 51 52 53
my %prev_define_skips = ();
my %next_define_skips = ();
my %prev_polarity_skips = ();
my %next_polarity_skips = ();
54
for my $file (@files) {
55
    my ($curtype, $curpage, $inhdr, $havetoc, $intoc, $inif) = ("", 0, 0, 0, 0);
56 57 58
    my ($define_skip, $polarity_skip, $skipping) = ("", 0, 0);
    my ($prev_define_skip, $prev_polarity_skip, $prev_skip,
        $next_define_skip, $next_polarity_skip, $next_skip) = ("", 0, "", "", 0, "");
59 60 61
    open FILE, $file or die "File $file cannot be opened.\n";
    while (<FILE>) {
        if (/^\h*\\if\h+defined\h*\(\h*(\H+)\h*\)/) {
62 63
            die "Nested \\if at $file:$.\n" if ($inif);
            $inif = 1;
64
            $skipping = !defined($defines{$1});
65
            if ($inhdr) {
66 67 68 69
                $define_skip = $1;
                $polarity_skip = $skipping;
            }
        } elsif (/^\h*\\else/) {
70
            die "Unmatched \\else in $file:$.\n" if (!$inif);
71 72
            $skipping = 1 - $skipping;
        } elsif (/^\h*\\endif/) {
73 74
            die "Unmatched \\endif in $file:$.\n" if (!$inif);
            $inif = 0;
75
            $skipping = 0;
76
            $define_skip = "";
77 78 79
        } elsif (keys(%title2page) == 1 && /^\h*\\section1 Table Of Contents/) {
            $havetoc = 1;
        } elsif ($havetoc && /^\h*\\list/) {
80
            $intoc++;
81 82 83
        } elsif ($intoc) {
            if (/^\h*\\endlist/) {
                $intoc--;
84
            } elsif (!$skipping && /^\h*\\li\h+\\l\h*{(.*)}$/) {
85 86 87
                push @toc, $1;
            }
        } elsif ($inhdr) {
88 89 90 91 92 93
            if (/^\h*\\previouspage\h+(\H+)/) {
                $prev_skip = $1 if ($skipping);
                ($prev_define_skip, $prev_polarity_skip) = ($define_skip, $polarity_skip);
            } elsif (/^\h*\\nextpage\h+(\H+)/) {
                $next_skip = $1 if ($skipping);
                ($next_define_skip, $next_polarity_skip) = ($define_skip, $polarity_skip);
94 95 96
            } elsif (/^\h*\\(page|example)\h+(\H+)/) {
                $curtype = $1;
                $curpage = $2;
97 98
            } elsif (/^\h*\\title\h+(.+)$/) {
                if ($curpage eq "") {
99
                    die "Title '$1' appears in no \\page or \\example.\n";
100
                }
101 102 103 104 105 106 107 108 109
                if (length($prev_define_skip)) {
                    ($prev_define_skips{$1}, $prev_polarity_skips{$1}, $prev_skips{$1}) =
                            ($prev_define_skip, $prev_polarity_skip, $prev_skip);
                    $prev_define_skip = $prev_skip = "";
                }
                if (length($next_define_skip)) {
                    ($next_define_skips{$1}, $next_polarity_skips{$1}, $next_skips{$1}) =
                            ($next_define_skip, $next_polarity_skip, $next_skip);
                    $next_define_skip = $next_skip = "";
110
                }
111
                $title2type{$1} = $curtype;
112 113 114
                $title2page{$1} = $curpage;
                $doctitle = $1 if (!$doctitle);
                $curpage = "";
115
                $inhdr = 0;
116 117
            }
        } else {
118
            if (/^\h*\\contentspage\b/) {
119
                $havetoc = 0;
120
                $inhdr = 1;
121 122 123
            }
        }
    }
124 125
    die "Missing \\title in $file\n" if ($inhdr);
    die "Unclosed TOC in $file\n" if ($intoc);
126
    close FILE;
127 128 129 130 131
}

my %prev = ();
my %next = ();
my $last = $doctitle;
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
132
my $lastpage = $title2page{$last};
133
for my $title (@toc) {
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
134
    my $page = $title2page{$title};
135
    defined($page) or die "TOC refers to unknown page/example '$title'.\n";
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
136 137
    $next{$last} = $page;
    $prev{$title} = $lastpage;
138
    $last = $title;
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
139
    $lastpage = $page;
140 141
}

142 143 144 145 146 147 148 149 150
for my $file (@files) {
    open IN, $file or die "File $file cannot be opened a second time?!\n";
    open OUT, '>'.$file.".out" or die "File $file.out cannot be created.\n";
    my $cutting = 0;
    while (<IN>) {
        if (!$cutting) {
            if (/^\h*\\contentspage/) {
                $cutting = 1;
            }
151
        } else {
152
            if (/^\h*\\title\h+(.+)$/) {
153 154 155
                if (defined($prev_define_skips{$1})) {
                    print OUT "    \\if defined(".$prev_define_skips{$1}.")\n";
                    if ($prev_polarity_skips{$1}) {
156 157 158 159 160
                        print OUT "    \\previouspage ".$prev_skips{$1} if ($prev_skips{$1});
                        print OUT "    \\else\n";
                    }
                }
                print OUT "    \\previouspage ".$prev{$1} if ($prev{$1});
161 162
                if (defined($prev_define_skips{$1})) {
                    if (!$prev_polarity_skips{$1}) {
163 164 165 166 167
                        print OUT "    \\else\n";
                        print OUT "    \\previouspage ".$prev_skips{$1} if ($prev_skips{$1});
                    }
                    print OUT "    \\endif\n";
                }
168
                print OUT "    \\".$title2type{$1}." ".$title2page{$1};
169 170 171
                if (defined($next_define_skips{$1})) {
                    print OUT "    \\if defined(".$next_define_skips{$1}.")\n";
                    if ($next_polarity_skips{$1}) {
172 173 174 175 176
                        print OUT "    \\nextpage ".$next_skips{$1} if ($next_skips{$1});
                        print OUT "    \\else\n";
                    }
                }
                print OUT "    \\nextpage ".$next{$1} if ($next{$1});
177 178
                if (defined($next_define_skips{$1})) {
                    if (!$next_polarity_skips{$1}) {
179 180 181 182 183 184 185 186 187 188
                        print OUT "    \\else\n";
                        print OUT "    \\nextpage ".$next_skips{$1} if ($next_skips{$1});
                    }
                    print OUT "    \\endif\n";
                }
                print OUT "\n";
                $cutting = 0;
            } else {
                next;
            }
189
        }
190
        print OUT $_;
191
    }
192 193 194
    close OUT;
    close IN;
    rename($file.".out", $file) or die "Cannot replace $file with new version.\n";
195
}