fixqt4headers.pl 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #!/usr/bin/env perl
  2. #############################################################################
  3. ##
  4. ## Copyright (C) 2016 The Qt Company Ltd.
  5. ## Contact: https://www.qt.io/licensing/
  6. ##
  7. ## This file is part of the porting tools of the Qt Toolkit.
  8. ##
  9. ## $QT_BEGIN_LICENSE:LGPL$
  10. ## Commercial License Usage
  11. ## Licensees holding valid commercial Qt licenses may use this file in
  12. ## accordance with the commercial license agreement provided with the
  13. ## Software or, alternatively, in accordance with the terms contained in
  14. ## a written agreement between you and The Qt Company. For licensing terms
  15. ## and conditions see https://www.qt.io/terms-conditions. For further
  16. ## information use the contact form at https://www.qt.io/contact-us.
  17. ##
  18. ## GNU Lesser General Public License Usage
  19. ## Alternatively, this file may be used under the terms of the GNU Lesser
  20. ## General Public License version 3 as published by the Free Software
  21. ## Foundation and appearing in the file LICENSE.LGPL3 included in the
  22. ## packaging of this file. Please review the following information to
  23. ## ensure the GNU Lesser General Public License version 3 requirements
  24. ## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
  25. ##
  26. ## GNU General Public License Usage
  27. ## Alternatively, this file may be used under the terms of the GNU
  28. ## General Public License version 2.0 or (at your option) the GNU General
  29. ## Public license version 3 or any later version approved by the KDE Free
  30. ## Qt Foundation. The licenses are as published by the Free Software
  31. ## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
  32. ## included in the packaging of this file. Please review the following
  33. ## information to ensure the GNU General Public License requirements will
  34. ## be met: https://www.gnu.org/licenses/gpl-2.0.html and
  35. ## https://www.gnu.org/licenses/gpl-3.0.html.
  36. ##
  37. ## $QT_END_LICENSE$
  38. ##
  39. #############################################################################
  40. use Cwd;
  41. use File::Find;
  42. use File::Spec;
  43. use IO::File;
  44. use Getopt::Long;
  45. use strict;
  46. use warnings;
  47. my $dry_run = 0;
  48. my $help = 0;
  49. my $stripModule = 0;
  50. my $fixedFileCount = 0;
  51. my $fileCount = 0;
  52. my $verbose = 0;
  53. my $qtdir;
  54. my $qtIncludeDir;
  55. my $USAGE=<<EOF;
  56. This script replaces all Qt 4 style includes with Qt 5 includes.
  57. Usage: $0 [options]
  58. Options:
  59. --dry-run : Do not replace anything, just print what would be replaced
  60. --strip-modules : Strip the module headers for writing portable code
  61. --verbose : Verbose
  62. --qtdir <directory> : Point to Qt 5's qtbase directory
  63. EOF
  64. if (!GetOptions('dry-run' => \$dry_run, 'help' => \$help,
  65. 'strip-modules' => \$stripModule, 'verbose' => \$verbose, 'qtdir:s' => \$qtdir)
  66. || $help) {
  67. print $USAGE;
  68. exit (1);
  69. }
  70. my %headerSubst = ();
  71. my $cwd = getcwd();
  72. sub fixHeaders
  73. {
  74. my $fileName = $File::Find::name;
  75. my $relFileName = File::Spec->abs2rel($fileName, $cwd);
  76. # only check sources, also ignore symbolic links and directories
  77. return unless -f $fileName && $fileName =~ /(\.h|\.cpp|\/C|\.cc|\.CC)$/;
  78. my $inFile = new IO::File('<' . $fileName) or die ('Unable to open ' . $fileName . ': ' . $!);
  79. $fileCount++;
  80. my @affectedClasses;
  81. my @outLines;
  82. while (my $line = <$inFile>) {
  83. if ($line =~ /^#(\s*)include(\s*)<.*?\/(.*?)>(.*)/) {
  84. my $newHeader = $headerSubst{$3};
  85. if ($newHeader) {
  86. $line = '#' . $1 . 'include' . $2 . '<' . $newHeader . '>' . $4 . "\n";
  87. push(@affectedClasses, $3);
  88. }
  89. } elsif ($line =~ /^#(\s*)include(\s*)<QtGui>(.*)/) {
  90. $line = '#' . $1 . 'include' . $2 . '<QtWidgets>' . $3 . "\n";
  91. push(@affectedClasses, 'QtGui');
  92. }
  93. push(@outLines, $line);
  94. }
  95. $inFile->close();
  96. if (scalar(@affectedClasses)) {
  97. $fixedFileCount++;
  98. print $relFileName, ': ', join(', ', @affectedClasses), "\n" if ($verbose || $dry_run);
  99. if (!$dry_run) {
  100. my $outFile = new IO::File('>' . $fileName) or die ('Unable to open ' . $fileName . ': ' . $!);
  101. map { print $outFile $_; } @outLines;
  102. $outFile->close();
  103. }
  104. } else {
  105. print $relFileName, ": no modification.\n" if ($verbose || $dry_run);
  106. }
  107. }
  108. sub findQtHeaders
  109. {
  110. my ($dirName,$includeDir) = @_;
  111. local (*DIR);
  112. my $moduleIncludeDir = $includeDir . '/' . $dirName;
  113. opendir(DIR, $moduleIncludeDir) || die ('Unable to open ' . $moduleIncludeDir . ': ' . $!);
  114. my @headers = readdir(DIR);
  115. closedir(DIR);
  116. foreach my $header (@headers) {
  117. next if (-d ($moduleIncludeDir . '/' . $header) || $header =~ /\.pri$/);
  118. $headerSubst{$header} = $stripModule ? $header : ($dirName . '/' . $header);
  119. }
  120. }
  121. # -------- MAIN
  122. if ($qtdir) {
  123. $qtIncludeDir = $qtdir . '/include';
  124. } else {
  125. $qtIncludeDir = `qmake -query QT_INSTALL_HEADERS`;
  126. chop($qtIncludeDir);
  127. }
  128. die "The location of the Qt 5 include files could not be determined.\n"
  129. ."Please ensure qmake can be found in PATH or pass the command line option --qtdir.\n"
  130. unless -d $qtIncludeDir;
  131. findQtHeaders('QtCore', $qtIncludeDir);
  132. findQtHeaders('QtConcurrent', $qtIncludeDir);
  133. findQtHeaders('QtWidgets', $qtIncludeDir);
  134. findQtHeaders('QtPrintSupport', $qtIncludeDir);
  135. if (-d $qtIncludeDir . '/include/QtMultimedia') {
  136. findQtHeaders('QtMultimedia', $qtIncludeDir);
  137. findQtHeaders('QtMultimediaWidgets', $qtIncludeDir);
  138. } elsif (-d $qtIncludeDir . '/../qtmultimedia' ) {
  139. # This is the case if QTDIR points to a source tree instead of an installed Qt
  140. findQtHeaders('QtMultimedia', $qtIncludeDir . '/../qtmultimedia');
  141. findQtHeaders('QtMultimediaWidgets', $qtIncludeDir . '/../qtmultimedia');
  142. }
  143. # Support porting from "Qt 4.99" QtDeclarative to QtQuick (QQuickItem et al)
  144. if (-d $qtIncludeDir . '/include/QtQuick') {
  145. findQtHeaders('QtQuick', $qtIncludeDir);
  146. } elsif (-d $qtIncludeDir . '/../qtdeclarative' ) {
  147. # This is the case if QTDIR points to a source tree instead of an installed Qt
  148. findQtHeaders('QtQuick', $qtIncludeDir . '/../qtdeclarative');
  149. }
  150. # special case
  151. $headerSubst{'QtGui'} = 'QtWidgets/QtWidgets';
  152. find({ wanted => \&fixHeaders, no_chdir => 1}, $cwd);
  153. print 'Done. ', ($dry_run ? 'Checked' : 'Modified'), ' ', $fixedFileCount, ' of ', $fileCount, " file(s).\n";