1#! /usr/bin/perl -w
2
3#############################################################################
4##
5## Copyright (C) 2016 The Qt Company Ltd.
6## Contact: https://www.qt.io/licensing/
7##
8## This file is part of Qbs.
9##
10## $QT_BEGIN_LICENSE:LGPL$
11## Commercial License Usage
12## Licensees holding valid commercial Qt licenses may use this file in
13## accordance with the commercial license agreement provided with the
14## Software or, alternatively, in accordance with the terms contained in
15## a written agreement between you and The Qt Company. For licensing terms
16## and conditions see https://www.qt.io/terms-conditions. For further
17## information use the contact form at https://www.qt.io/contact-us.
18##
19## GNU Lesser General Public License Usage
20## Alternatively, this file may be used under the terms of the GNU Lesser
21## General Public License version 3 as published by the Free Software
22## Foundation and appearing in the file LICENSE.LGPL3 included in the
23## packaging of this file. Please review the following information to
24## ensure the GNU Lesser General Public License version 3 requirements
25## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26##
27## GNU General Public License Usage
28## Alternatively, this file may be used under the terms of the GNU
29## General Public License version 2.0 or (at your option) the GNU General
30## Public license version 3 or any later version approved by the KDE Free
31## Qt Foundation. The licenses are as published by the Free Software
32## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33## included in the packaging of this file. Please review the following
34## information to ensure the GNU General Public License requirements will
35## be met: https://www.gnu.org/licenses/gpl-2.0.html and
36## https://www.gnu.org/licenses/gpl-3.0.html.
37##
38## $QT_END_LICENSE$
39##
40#############################################################################
41use strict;
42
43my @files = ();
44my %defines = ();
45for (@ARGV) {
46    if (/^-D(.*)$/) {
47        $defines{$1} = 1;
48    } elsif (/^-/) {
49        printf STDERR "Unknown option '".$_."'\n";
50        exit 1;
51    } else {
52        push @files, $_;
53    }
54}
55
56int(@files) or die "usage: $0 [-D<define>]... <qdoc-file>\n";
57
58my @toc = ();
59my %title2page = ();
60my $doctitle = "";
61my $curpage = "";
62my $intoc = 0;
63my %prev_skips = ();
64my %next_skips = ();
65my %define_skips = ();
66my %polarity_skips = ();
67my $prev_skip = "";
68my $next_skip = "";
69my $define_skip = "";
70my $polarity_skip = 0;
71for my $file (@files) {
72    my $skipping = 0; # no nested ifs!
73    open FILE, $file or die "File $file cannot be opened.\n";
74    while (<FILE>) {
75        if (/^\h*\\if\h+defined\h*\(\h*(\H+)\h*\)/) {
76            $skipping = !defined($defines{$1});
77            if (!$intoc) {
78                $define_skip = $1;
79                $polarity_skip = $skipping;
80            }
81        } elsif (/^\h*\\else/) {
82            $skipping = 1 - $skipping;
83        } elsif (/^\h*\\endif/) {
84            $skipping = 0;
85        } elsif (keys(%title2page) == 1 && /^\h*\\list/) {
86            $intoc++;
87        } elsif (!$intoc) {
88            if ($skipping && /^\h*\\previouspage\h+(\H+)/) {
89                $prev_skip = $1;
90            } elsif ($skipping && /^\h*\\nextpage\h+(\H+)/) {
91                $next_skip = $1;
92            } elsif (/^\h*\\page\h+(\H+)/) {
93                $curpage = $1;
94            } elsif (/^\h*\\title\h+(.+)$/) {
95                if ($curpage eq "") {
96                    die "Title '$1' appears in no \\page.\n";
97                }
98                if (length($define_skip)) {
99                     $define_skips{$1} = $define_skip;
100                     $polarity_skips{$1} = $polarity_skip;
101                     $prev_skips{$1} = $prev_skip;
102                     $next_skips{$1} = $next_skip;
103                     $define_skip = $prev_skip = $next_skip = "";
104                }
105                $title2page{$1} = $curpage;
106                $doctitle = $1 if (!$doctitle);
107                $curpage = "";
108            }
109        } else {
110            if (/^\h*\\endlist/) {
111                $intoc--;
112            } elsif (!$skipping && /^\h*\\(?:o|li)\h+\\l\h*{(.*)}$/) {
113                push @toc, $1;
114            }
115        }
116    }
117    close FILE;
118}
119
120my %prev = ();
121my %next = ();
122my $last = $doctitle;
123for my $title (@toc) {
124    $next{$last} = $title2page{$title};
125    $prev{$title} = $title2page{$last};
126    $last = $title;
127}
128
129for my $file (@files) {
130    open IN, $file or die "File $file cannot be opened a second time?!\n";
131    open OUT, '>'.$file.".out" or die "File $file.out cannot be created.\n";
132    my $cutting = 0;
133    while (<IN>) {
134        if (!$cutting) {
135            if (/^\h*\\contentspage/) {
136                $cutting = 1;
137            }
138        } else {
139            if (/^\h*\\title\h+(.+)$/) {
140                if (defined($define_skips{$1})) {
141                    print OUT "    \\if defined(".$define_skips{$1}.")\n";
142                    if ($polarity_skips{$1}) {
143                        print OUT "    \\previouspage ".$prev_skips{$1} if ($prev_skips{$1});
144                        print OUT "    \\else\n";
145                    }
146                }
147                print OUT "    \\previouspage ".$prev{$1} if ($prev{$1});
148                if (defined($define_skips{$1})) {
149                    if (!$polarity_skips{$1}) {
150                        print OUT "    \\else\n";
151                        print OUT "    \\previouspage ".$prev_skips{$1} if ($prev_skips{$1});
152                    }
153                    print OUT "    \\endif\n";
154                }
155                print OUT "    \\page ".$title2page{$1};
156                if (defined($define_skips{$1})) {
157                    print OUT "    \\if defined(".$define_skips{$1}.")\n";
158                    if ($polarity_skips{$1}) {
159                        print OUT "    \\nextpage ".$next_skips{$1} if ($next_skips{$1});
160                        print OUT "    \\else\n";
161                    }
162                }
163                print OUT "    \\nextpage ".$next{$1} if ($next{$1});
164                if (defined($define_skips{$1})) {
165                    if (!$polarity_skips{$1}) {
166                        print OUT "    \\else\n";
167                        print OUT "    \\nextpage ".$next_skips{$1} if ($next_skips{$1});
168                    }
169                    print OUT "    \\endif\n";
170                }
171                print OUT "\n";
172                $cutting = 0;
173            } else {
174                next;
175            }
176        }
177        print OUT $_;
178    }
179    close OUT;
180    close IN;
181    rename($file.".out", $file) or die "Cannot replace $file with new version.\n";
182}
183