test: Skip tst_QMdiArea::nativeSubWindows() on Windows/ANGLE.
[profile/ivi/qtbase.git] / bin / syncqt
1 #!/usr/bin/perl
2 #############################################################################
3 ##
4 ## Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
5 ## Contact: http://www.qt-project.org/legal
6 ##
7 ## This file is part of the build configuration 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 Digia.  For licensing terms and
15 ## conditions see http://qt.digia.com/licensing.  For further information
16 ## use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
21 ## Foundation and appearing in the file LICENSE.LGPL included in the
22 ## packaging of this file.  Please review the following information to
23 ## ensure the GNU Lesser General Public License version 2.1 requirements
24 ## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ##
26 ## In addition, as a special exception, Digia gives you certain additional
27 ## rights.  These rights are described in the Digia Qt LGPL Exception
28 ## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ##
30 ## GNU General Public License Usage
31 ## Alternatively, this file may be used under the terms of the GNU
32 ## General Public License version 3.0 as published by the Free Software
33 ## Foundation and appearing in the file LICENSE.GPL included in the
34 ## packaging of this file.  Please review the following information to
35 ## ensure the GNU General Public License version 3.0 requirements will be
36 ## met: http://www.gnu.org/copyleft/gpl.html.
37 ##
38 ##
39 ## $QT_END_LICENSE$
40 ##
41 #############################################################################
42
43 #
44 # Synchronizes Qt header files - internal development tool.
45 #
46
47 # use packages -------------------------------------------------------
48 use File::Basename;
49 use File::Path;
50 use File::Spec;
51 use Cwd;
52 use Cwd 'abs_path';
53 use Config;
54 use strict;
55 use warnings;
56 use English qw(-no_match_vars );
57
58 my $normalizePath_fixDrive = ($^O eq "msys" ? 1 : 0);
59
60 ######################################################################
61 # Syntax:  normalizePath(\$path)
62 # Params:  Reference to a path that's going to be normalized.
63 #
64 # Purpose: Converts the path into a form that can be used as include
65 #          path from C++ sources and qmake's .pro files.
66 #          Only relevant on Windows.
67 # Returns: -none-
68 ######################################################################
69 sub normalizePath {
70     my $s = shift;
71     $$s =~ s=\\=/=g;
72     if ($normalizePath_fixDrive && $$s =~ m,^/([a-zA-Z])/(.*),) {
73         $$s = lc($1) . ":/$2";
74     }
75 }
76
77 # set output basedir to be where ever syncqt is run from
78 our $out_basedir = getcwd();
79 normalizePath(\$out_basedir);
80 our $basedir;
81 our $quoted_basedir;
82
83 # Make sure we use Windows line endings for chomp and friends on Windows.
84 $INPUT_RECORD_SEPARATOR = "\r\n" if ($^O eq "msys");
85
86 my $mkspecsdir = dirname(dirname($0));
87 normalizePath(\$mkspecsdir) if (defined $mkspecsdir);
88
89 # will be defined based on the modules sync.profile
90 our (%modules, %moduleheaders, @allmoduleheadersprivate, %classnames, %explicitheaders, %deprecatedheaders);
91 our @qpa_headers = ();
92
93 # global variables (modified by options)
94 my $isunix = 0;
95 my $module = 0;
96 my $showonly = 0;
97 my $verbose_level = 1;
98 my $remove_stale = 1;
99 my $force_win = 0;
100 my $force_relative = 0;
101 my $check_includes = 0;
102 my $copy_headers = 0;
103 my $create_uic_class_map = 0;
104 my $create_private_headers = 1;
105 my $minimal = 0;
106 my @modules_to_sync ;
107 $force_relative = 1 if ( -d "/System/Library/Frameworks" );
108
109
110 # functions ----------------------------------------------------------
111
112 ######################################################################
113 # Syntax:  showUsage()
114 # Params:  -none-
115 #
116 # Purpose: Show the usage of the script.
117 # Returns: -none-
118 ######################################################################
119 sub showUsage
120 {
121     print "$0 usage:\n";
122     print "  <module directory>    Specifies which module to sync header files for (required for shadow builds!)\n\n";
123
124     print "  -copy                 Copy headers instead of include-fwd(default: " . ($copy_headers ? "yes" : "no") . ")\n";
125     print "  -remove-stale         Removes stale headers              (default: " . ($remove_stale ? "yes" : "no") . ")\n";
126     print "  -relative             Force relative symlinks            (default: " . ($force_relative ? "yes" : "no") . ")\n";
127     print "  -windows              Force platform to Windows          (default: " . ($force_win ? "yes" : "no") . ")\n";
128     print "  -showonly             Show action but not perform        (default: " . ($showonly ? "yes" : "no") . ")\n";
129     print "  -minimal              Do not create CamelCase headers    (default: " . ($minimal ? "yes" : "no") . ")\n";
130     print "  -outdir <PATH>        Specify output directory for sync  (default: $out_basedir)\n";
131     print "  -mkspecsdir <PATH>    Set the path to the mkspecs        (detected: " . (defined $mkspecsdir ? $mkspecsdir : "-none-") . ")\n";
132     print "  -quiet                Only report problems, not activity (same as -verbose 0)\n";
133     print "  -v, -verbose <level>  Sets the verbosity level (max. 4)  (default: $verbose_level)\n";
134     print "                        The short form increases the level by +1\n";
135     print "  -separate-module <NAME>:<PROFILEDIR>:<HEADERDIR>\n";
136     print "                        Create headers for <NAME> with original headers in\n";
137     print "                        <HEADERDIR> relative to <PROFILEDIR> \n";
138     print "  -private              Force copy private headers         (default: " . ($create_private_headers ? "yes" : "no") . ")\n";
139     print "  -help                 This help\n";
140     exit 0;
141 }
142
143 ######################################################################
144 # Syntax:  checkUnix()
145 # Params:  -none-
146 #
147 # Purpose: Check if script runs on a Unix system or not. Cygwin
148 #          systems are _not_ detected as Unix systems.
149 # Returns: 1 if a unix system, else 0.
150 ######################################################################
151 sub checkUnix {
152     my ($r) = 0;
153     if ( $force_win != 0) {
154         return 0;
155     } elsif ( -f "/bin/uname" ) {
156         $r = 1;
157         (-f "\\bin\\uname") && ($r = 0);
158     } elsif ( -f "/usr/bin/uname" ) {
159         $r = 1;
160         (-f "\\usr\\bin\\uname") && ($r = 0);
161     }
162     if($r) {
163         $_ = $Config{'osname'};
164         $r = 0 if( /(ms)|(cyg)win/i );
165     }
166     return $r;
167 }
168
169 sub checkRelative {
170     my ($dir) = @_;
171     return 0 if($dir =~ /^\//);
172     return 0 if(!checkUnix() && $dir =~ /[a-zA-Z]:[\/\\]/);
173     return 1;
174 }
175
176 ######################################################################
177 # Syntax:  classNames(iheader)
178 # Params:  iheader, string, filename to parse for classname "symlinks"
179 #
180 # Purpose: Scans through iheader to find all classnames that should be
181 #          synced into library's include structure.
182 # Returns: List of all class names in a file.
183 ######################################################################
184 sub classNames {
185     my @ret;
186     my ($iheader) = @_;
187
188     my $classname = $classnames{basename($iheader)};
189     push @ret, $classname if ($classname);
190
191     my $parsable = "";
192     if(open(F, "<$iheader")) {
193         while(<F>) {
194             my $line = $_;
195             chomp $line;
196                         chop $line if ($line =~ /\r$/);
197             if($line =~ /^\#/) {
198                 if($line =~ /\\$/) {
199                     while($line = <F>) {
200                         chomp $line;
201                         last unless($line =~ /\\$/);
202                     }
203                 }
204                 return @ret if($line =~ m/^#pragma qt_sync_stop_processing/);
205                 push(@ret, $1) if($line =~ m/^#pragma qt_class\(([^)]*)\)[\r\n]*$/);
206                 $line = 0;
207             }
208             if($line) {
209                 $line =~ s,//.*$,,; #remove c++ comments
210                 $line .= ";" if($line =~ m/^Q_[A-Z_]*\(.*\)[\r\n]*$/); #qt macro
211                 $line .= ";" if($line =~ m/^QT_(BEGIN|END)_HEADER[\r\n]*$/); #qt macro
212                 $line .= ";" if($line =~ m/^QT_(BEGIN|END)_NAMESPACE(_[A-Z]+)*[\r\n]*$/); #qt macro
213                 $line .= ";" if($line =~ m/^QT_MODULE\(.*\)[\r\n]*$/); # QT_MODULE macro
214                 $parsable .= " " . $line;
215             }
216         }
217         close(F);
218     }
219
220     my $last_definition = 0;
221     my @namespaces;
222     for(my $i = 0; $i < length($parsable); $i++) {
223         my $definition = 0;
224         my $character = substr($parsable, $i, 1);
225         if($character eq "/" && substr($parsable, $i+1, 1) eq "*") { #I parse like this for greedy reasons
226             for($i+=2; $i < length($parsable); $i++) {
227                 my $end = substr($parsable, $i, 2);
228                 if($end eq "*/") {
229                     $last_definition = $i+2;
230                     $i++;
231                     last;
232                 }
233             }
234         } elsif($character eq "{") {
235             my $brace_depth = 1;
236             my $block_start = $i + 1;
237           BLOCK: for($i+=1; $i < length($parsable); $i++) {
238               my $ignore = substr($parsable, $i, 1);
239               if($ignore eq "{") {
240                   $brace_depth++;
241               } elsif($ignore eq "}") {
242                   $brace_depth--;
243                   unless($brace_depth) {
244                       for(my $i2 = $i+1; $i2 < length($parsable); $i2++) {
245                           my $end = substr($parsable, $i2, 1);
246                           if($end eq ";" || $end ne " ") {
247                               $definition = substr($parsable, $last_definition, $block_start - $last_definition) . "}";
248                               $i = $i2 if($end eq ";");
249                               $last_definition = $i + 1;
250                               last BLOCK;
251                           }
252                       }
253                   }
254               }
255           }
256         } elsif($character eq ";") {
257             $definition = substr($parsable, $last_definition, $i - $last_definition + 1);
258             $last_definition = $i + 1;
259         } elsif($character eq "}") {
260             # a naked } must be a namespace ending
261             # if it's not a namespace, it's eaten by the loop above
262             pop @namespaces;
263             $last_definition = $i + 1;
264         }
265
266         if (substr($parsable, $last_definition, $i - $last_definition + 1) =~ m/ namespace ([^ ]*) /
267             && substr($parsable, $i+1, 1) eq "{") {
268             push @namespaces, $1;
269
270             # Eat the opening { so that the condensing loop above doesn't see it
271             $i++;
272             $last_definition = $i + 1;
273         }
274
275         if($definition) {
276             $definition =~ s=[\n\r]==g;
277             my @symbols;
278             my $post_kw = qr/Q_DECL_FINAL|final|sealed/; # add here macros and keywords that go after the class-name of a class definition
279             if($definition =~ m/^ *typedef *.*\(\*([^\)]*)\)\(.*\);$/) {
280                 push @symbols, $1;
281             } elsif($definition =~ m/^ *typedef +(.*) +([^ ]*);$/) {
282                 push @symbols, $2;
283             } elsif($definition =~ m/^ *(template *<.*> *)?(class|struct) +([^ ]* +)?((?!$post_kw)[^<\s]+) ?(<[^>]*> ?)?\s*(?:$post_kw)?\s*((,|:)\s*(public|protected|private) *.*)? *\{\}$/o) {
284                 push @symbols, $4;
285             } elsif($definition =~ m/^ *Q_DECLARE_.*ITERATOR\((.*)\);$/) {
286                 push @symbols, "Q" . $1 . "Iterator";
287                 push @symbols, "QMutable" . $1 . "Iterator";
288             }
289
290             our $publicclassregexp;
291             foreach my $symbol (@symbols) {
292                 $symbol = (join("::", @namespaces) . "::" . $symbol) if (scalar @namespaces);
293
294                 if ($symbol =~ /^Q[^:]*$/           # no-namespace, starting with Q
295                     || $symbol =~ /^Phonon::/) {    # or in the Phonon namespace
296                     push @ret, $symbol;
297                 } elsif (defined($publicclassregexp)) {
298                     push @ret, $symbol if ($symbol =~ $publicclassregexp);
299                 }
300             }
301         }
302     }
303     return @ret;
304 }
305
306 sub make_path {
307     my ($dir, $lib, $be_verbose) = @_;
308     unless(-e $dir) {
309         mkpath $dir;
310         $dir = "<outbase>" . substr($dir, length($out_basedir)) if ($be_verbose < 3);
311         print "$lib: mkpath $dir\n" if ($be_verbose > 1);
312     }
313 }
314
315 ######################################################################
316 # Syntax:  syncHeader(header, iheader, copy, timestamp)
317 # Params:  header, string, filename to create "symlink" for
318 #          iheader, string, destination name of symlink
319 #          copy, forces header to be a copy of iheader
320 #          timestamp, the requested modification time if copying
321 #
322 # Purpose: Syncronizes header to iheader
323 # Returns: 1 if successful, else 0.
324 ######################################################################
325 sub syncHeader {
326     my ($lib, $header, $iheader, $copy, $ts) = @_;
327     normalizePath(\$iheader);
328     normalizePath(\$header);
329     return copyFile($lib, $iheader, $header) if($copy);
330
331     unless(-e $header) {
332         my $header_dir = dirname($header);
333         make_path($header_dir, $lib, $verbose_level);
334
335         #write it
336         my $iheader_out = fixPaths($iheader, $header_dir);
337         open(HEADER, ">$header") || die "Could not open $header for writing: $!\n";
338         print HEADER "#include \"$iheader_out\"\n";
339         close HEADER;
340         if(defined($ts)) {
341             utime(time, $ts, $header) or die "$iheader, $header";
342         }
343         return 1;
344     }
345     return 0;
346 }
347
348 ######################################################################
349 # Syntax:  fixPaths(file, dir)
350 # Params:  file, string, filepath to be made relative to dir
351 #          dir, string, dirpath for point of origin
352 #
353 # Purpose: file is made relative (if possible) of dir.
354 # Returns: String with the above applied conversion.
355 ######################################################################
356
357 sub cleanupPath {
358     my ($file) = @_;
359     normalizePath(\$file);
360     while ($file =~ s,/[^/]+/\.\./,/,) {}
361     return $file;
362 }
363
364 sub fixPaths {
365     my ($file, $dir) = @_;
366
367     my $out = File::Spec->abs2rel(cleanupPath($file), cleanupPath($dir));
368     $out =~ s,\\,/,g;
369     return $out;
370 }
371
372 ######################################################################
373 # Syntax:  fileContents(filename)
374 # Params:  filename, string, filename of file to return contents
375 #
376 # Purpose: Get the contents of a file.
377 # Returns: String with contents of the file, or empty string if file
378 #          doens't exist.
379 # Warning: Dies if it does exist but script cannot get read access.
380 ######################################################################
381 sub fileContents {
382     my ($filename) = @_;
383     my $filecontents = "";
384     if (-e $filename) {
385         open(I, "< $filename") || die "Could not open $filename for reading, read block?";
386         local $/;
387         binmode I;
388         $filecontents = <I>;
389         close I;
390     }
391     return $filecontents;
392 }
393
394 ######################################################################
395 # Syntax:  fileCompare(file1, file2)
396 # Params:  file1, string, filename of first file
397 #          file2, string, filename of second file
398 #
399 # Purpose: Determines if files are equal, and which one is newer.
400 # Returns: 0 if files are equal no matter the timestamp, -1 if file1
401 #          is newer, 1 if file2 is newer.
402 ######################################################################
403 sub fileCompare {
404     my ($file1, $file2) = @_;
405     my $file1contents = fileContents($file1);
406     my $file2contents = fileContents($file2);
407     if (! -e $file1) { return 1; }
408     if (! -e $file2) { return -1; }
409     return $file1contents ne $file2contents ? (stat($file2))[9] <=> (stat($file1))[9] : 0;
410 }
411
412 ######################################################################
413 # Syntax:  copyFile(file, ifile)
414 # Params:  file, string, filename to create duplicate for
415 #          ifile, string, destination name of duplicate
416 #
417 # Purpose: Keeps files in sync so changes in the newer file will be
418 #          written to the other.
419 # Returns: 1 if files were synced, else 0.
420 # Warning: Dies if script cannot get write access.
421 ######################################################################
422 sub copyFile
423 {
424     my ($lib, $file,$ifile, $copy,$knowdiff,$filecontents,$ifilecontents) = @_;
425     # Bi-directional synchronization
426     open( I, "< " . $file ) || die "Could not open $file for reading";
427     local $/;
428     binmode I;
429     $filecontents = <I>;
430     close I;
431     if ( open(I, "< " . $ifile) ) {
432         local $/;
433         binmode I;
434         $ifilecontents = <I>;
435         close I;
436         $copy = fileCompare($file, $ifile);
437         $knowdiff = 0,
438     } else {
439         $copy = -1;
440         $knowdiff = 1;
441     }
442
443     if ( $knowdiff || ($filecontents ne $ifilecontents) ) {
444         if ( $copy > 0 ) {
445             my $file_dir = dirname($file);
446             make_path($file_dir, $lib, $verbose_level);
447             open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)";
448             local $/;
449             binmode O;
450             print O $ifilecontents;
451             close O;
452             utime time, (stat($ifile))[9], $file;
453             return 1;
454         } elsif ( $copy < 0 ) {
455             my $ifile_dir = dirname($ifile);
456             make_path($ifile_dir, $lib, $verbose_level);
457             open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)";
458             local $/;
459             binmode O;
460             print O $filecontents;
461             close O;
462             utime time, (stat($file))[9], $ifile;
463             return 1;
464         }
465     }
466     return 0;
467 }
468
469 ######################################################################
470 # Syntax:  symlinkFile(file, ifile)
471 # Params:  file, string, filename to create "symlink" for
472 #          ifile, string, destination name of symlink
473 #
474 # Purpose: File is symlinked to ifile (or copied if filesystem doesn't
475 #          support symlink).
476 # Returns: 1 on success, else 0.
477 ######################################################################
478 sub symlinkFile
479 {
480     my ($lib, $file, $ifile) = @_;
481
482     if ($isunix) {
483         print "$lib: symlink created for $file " if ($verbose_level);
484         if ( $force_relative && ($ifile =~ /^$quoted_basedir/)) {
485             my $t = getcwd();
486             my $c = -1;
487             my $p = "../";
488             $t =~ s-^$quoted_basedir/--;
489             $p .= "../" while( ($c = index( $t, "/", $c + 1)) != -1 );
490             $file =~ s-^$quoted_basedir/-$p-;
491             print " ($file)\n" if($verbose_level);
492         }
493         print "\n" if($verbose_level);
494         return symlink($file, $ifile);
495     }
496     return copyFile($lib, $file, $ifile);
497 }
498
499 ######################################################################
500 # Syntax:  findFiles(dir, match, descend)
501 # Params:  dir, string, directory to search for name
502 #          match, string, regular expression to match in dir
503 #          descend, integer, 0 = non-recursive search
504 #                            1 = recurse search into subdirectories
505 #
506 # Purpose: Finds files matching a regular expression.
507 # Returns: List of matching files.
508 #
509 # Examples:
510 #   findFiles("/usr","\.cpp$",1)  - finds .cpp files in /usr and below
511 #   findFiles("/tmp","^#",0)      - finds #* files in /tmp
512 ######################################################################
513 sub findFiles {
514     my ($dir,$match,$descend) = @_;
515     my ($file,$p,@files);
516     local(*D);
517     normalizePath(\$dir);
518     ($dir eq "") && ($dir = ".");
519     if ( opendir(D,$dir) ) {
520         if ( $dir eq "." ) {
521             $dir = "";
522         } else {
523             ($dir =~ /\/$/) || ($dir .= "/");
524         }
525         foreach $file ( sort readdir(D) ) {
526             next if ( $file  =~ /^\.\.?$/ );
527             $p = $file;
528             ($file =~ /$match/) && (push @files, $p);
529             if ( $descend && -d $p && ! -l $p ) {
530                 push @files, &findFiles($p,$match,$descend);
531             }
532         }
533         closedir(D);
534     }
535     return @files;
536 }
537
538 sub listSubdirs {
539     my @subdirs = @_;
540     foreach my $subdir (@subdirs) {
541         opendir DIR, $subdir or die "Huh, directory ".$subdir." cannot be opened.";
542         foreach my $t (sort readdir(DIR)) {
543             push @subdirs, "$subdir/$t" if(-d "$subdir/$t" && !($t eq ".") &&
544                                            !($t eq "..") && !($t eq ".obj") &&
545                                            !($t eq ".moc") && !($t eq ".rcc") &&
546                                            !($t eq ".uic") && !($t eq "build") &&
547                                            !($t eq "doc"));
548         }
549         closedir DIR;
550     }
551     return @subdirs;
552 }
553
554 ######################################################################
555 # Syntax:  loadSyncProfile()
556 #
557 # Purpose: Locates the sync.profile.
558 # Returns: Hashmap of module name -> directory.
559 ######################################################################
560 sub loadSyncProfile {
561     my ($srcbase, $outbase) = @_;
562     if ($verbose_level) {
563         print("<srcbase> = $$srcbase \n");
564         print("<outbase> = $$outbase \n");
565     }
566
567     my $syncprofile = "$$srcbase/sync.profile";
568     my $result;
569     unless ($result = do "$syncprofile") {
570         die "syncqt couldn't parse $syncprofile: $@" if $@;
571         die "syncqt couldn't execute $syncprofile: $!" unless defined $result;
572     }
573     return $result;
574 }
575
576 sub basePrettify {
577     my ($arg) = @_;
578     $$arg =~ s,^\Q$basedir\E,<srcbase>,;
579     $$arg =~ s,^\Q$out_basedir\E,<outbase>,;
580 }
581
582 sub cleanPath {
583     my ($arg) = @_;
584     while ($arg =~ s,[^/]+/\.\.(/|$),,) {}
585     return $arg;
586 }
587
588 sub locateSyncProfile
589 {
590     my ($directory) = @_;
591     $directory = abs_path($directory);
592     while (1) {
593         my $file = $directory."/sync.profile";
594         return $file if (-e $file);
595         my $odir = $directory;
596         $directory = dirname($directory);
597         return undef if ($directory eq $odir);
598     }
599 }
600
601 sub isQpaHeader
602 {
603     my ($header) = @_;
604     foreach my $qpa_header (@qpa_headers) {
605         return 1 if ($header =~ $qpa_header);
606     }
607     return 0;
608 }
609
610 # check if this is an in-source build, and if so use that as the basedir too
611 $basedir = locateSyncProfile($out_basedir);
612 if ($basedir) {
613     $basedir = dirname($basedir) ;
614     normalizePath(\$basedir);
615     $quoted_basedir = "\Q$basedir";
616 }
617
618 # --------------------------------------------------------------------
619 # "main" function
620 # --------------------------------------------------------------------
621
622 while ( @ARGV ) {
623     my $var = 0;
624     my $val = 0;
625
626     #parse
627     my $arg = shift @ARGV;
628     if ($arg eq "-h" || $arg eq "-help" || $arg eq "-?" || $arg eq "?") {
629         $var = "show_help";
630         $val = "yes";
631     } elsif($arg eq "-copy") {
632         $var = "copy";
633         $val = "yes";
634     } elsif($arg eq "-o" || $arg eq "-outdir") {
635         $var = "output";
636         $val = shift @ARGV;
637     } elsif($arg eq "-showonly" || $arg eq "-remove-stale" || $arg eq "-windows" ||
638             $arg eq "-relative" || $arg eq "-check-includes") {
639         $var = substr($arg, 1);
640         $val = "yes";
641     } elsif($arg =~ /^-no-(.*)$/) {
642         $var = $1;
643         $val = "no";
644         #these are for commandline compat
645     } elsif($arg eq "-inc") {
646         $var = "output";
647         $val = shift @ARGV;
648     } elsif($arg eq "-module") {
649         $var = "module";
650         $val = shift @ARGV;
651     } elsif($arg eq "-separate-module") {
652         $var = "separate-module";
653         $val = shift @ARGV;
654     } elsif($arg eq "-show") {
655         $var = "showonly";
656         $val = "yes";
657     } elsif($arg eq "-quiet") {
658         $var = "verbose";
659         $val = "0";
660     } elsif($arg eq "-v") {
661         $var = "verbose";
662         $val = "yes";
663     } elsif($arg eq "-verbose") {
664         $var = "verbose";
665         $val = shift @ARGV;
666     } elsif($arg eq "-minimal") {
667         $var = "minimal";
668         $val = "yes";
669     } elsif($arg eq "-private") {
670         $var = "create_private_headers";
671         $val = "yes";
672     } elsif($arg eq "-mkspecsdir") {
673         $var = "mkspecsdir";
674         $val = shift @ARGV;
675     } elsif($arg =~/^-/) {
676         print "Unknown option: $arg\n\n" if(!$var);
677         showUsage();
678     } else {
679         $basedir = locateSyncProfile($arg);
680         die "Could not find a sync.profile for '$arg'\n" if (!$basedir);
681         $basedir = dirname($basedir);
682         normalizePath(\$basedir);
683         $quoted_basedir = "\Q$basedir";
684         $var = "ignore";
685     }
686
687     #do something
688     if(!$var || $var eq "show_help") {
689         print "Unknown option: $arg\n\n" if(!$var);
690         showUsage();
691     } elsif ($var eq "copy") {
692         if($val eq "yes") {
693             $copy_headers++;
694         } elsif($showonly) {
695             $copy_headers--;
696         }
697     } elsif ($var eq "showonly") {
698         if($val eq "yes") {
699             $showonly++;
700         } elsif($showonly) {
701             $showonly--;
702         }
703     } elsif ($var eq "verbose") {
704         if($val eq "yes") {
705             $verbose_level++;
706         } elsif($val eq "no" && $verbose_level) {
707             $verbose_level--;
708         } else {
709             $verbose_level = int($val);
710         }
711     } elsif ($var eq "check-includes") {
712         if($val eq "yes") {
713             $check_includes++;
714         } elsif($check_includes) {
715             $check_includes--;
716         }
717     } elsif ($var eq "remove-stale") {
718         if($val eq "yes") {
719             $remove_stale++;
720         } elsif($remove_stale) {
721             $remove_stale--;
722         }
723     } elsif ($var eq "windows") {
724         if($val eq "yes") {
725             $force_win++;
726         } elsif($force_win) {
727             $force_win--;
728         }
729     } elsif ($var eq "relative") {
730         if($val eq "yes") {
731             $force_relative++;
732         } elsif($force_relative) {
733             $force_relative--;
734         }
735     } elsif ($var eq "minimal") {
736         if($val eq "yes") {
737             $minimal++;
738         } elsif($minimal) {
739             $minimal--;
740         }
741     } elsif ($var eq "module") {
742         push @modules_to_sync, $val;
743     } elsif ($var eq "separate-module") {
744         my ($module, $prodir, $headerdir) = split(/:/, $val);
745         $modules{$module} = $prodir;
746         push @modules_to_sync, $module;
747         $moduleheaders{$module} = $headerdir;
748         $create_uic_class_map = 0;
749     } elsif ($var eq "mkspecsdir") {
750         if($val) {
751             $mkspecsdir = $val;
752             normalizePath(\$mkspecsdir);
753         } else {
754             die "The -mkspecsdir option requires an argument";
755         }
756     } elsif ($var eq "output") {
757         my $outdir = $val;
758         if(checkRelative($outdir)) {
759             $out_basedir = getcwd();
760             chomp $out_basedir;
761             $out_basedir .= "/" . $outdir;
762         } else {
763             $out_basedir = $outdir;
764         }
765         normalizePath(\$out_basedir);
766     }
767 }
768
769 die "Cannot automatically detect/use provided path to QtBase's build directory!\n" .
770     "QTDIR detected/provided: " . (defined $mkspecsdir ? $mkspecsdir : "-none-") . "\n" .
771     "Please use the -mkspecsdir option to provide the correct path.\nsyncqt failed"
772         if (!$mkspecsdir || !-d $mkspecsdir);
773
774 # if we have no $basedir we cannot be sure which sources you want, so die
775 die "Could not find any sync.profile for your module!\nPass <module directory> to syncqt to sync your header files.\nsyncqt failed" if (!$basedir);
776
777 my $class_lib_map_contents = "";
778 our @ignore_headers = ();
779 our @ignore_for_master_contents = ();
780 our @ignore_for_include_check = ();
781 our @ignore_for_qt_begin_header_check = ();
782 our @ignore_for_qt_begin_namespace_check = ();
783 our @ignore_for_qt_module_check = ();
784 our %inject_headers = ();
785
786 # load the module's sync.profile here, before we can
787 loadSyncProfile(\$basedir, \$out_basedir);
788
789 @modules_to_sync = keys(%modules) if($#modules_to_sync == -1);
790
791 my %allmoduleheadersprivate = map { $_ => 1 } @allmoduleheadersprivate;
792
793 $isunix = checkUnix; #cache checkUnix
794
795 my $qt_version = fileContents($mkspecsdir."/qconfig.pri");
796 if (length($qt_version)) {
797     $qt_version =~ s,.*^QT_VERSION[ \t]*=[ \t]*(\S+).*,$1,sm;
798 } else {
799     $qt_version = fileContents($basedir."/src/corelib/global/qglobal.h");
800     $qt_version =~ s,.*^#[ \t]*define[ \t]+QT_VERSION_STR[ \t]+"([^"]+)".*,$1,sm;
801 }
802 foreach my $lib (@modules_to_sync) {
803     die "No such module: $lib" unless(defined $modules{$lib});
804
805     #iteration info
806     my @dirs = split(/;/, $modules{$lib});
807     my $dir = $dirs[0];
808
809     my $project = $dir;
810     $project =~ s,/([^/]+)$,/$1/$1.pro,;
811     my $module_version = fileContents($project);
812     $module_version = $qt_version unless ($module_version =~ s,.*^VERSION[ \t]*=[ \t]*(\S+).*,$1,sm);
813
814     my $pathtoheaders = "";
815     $pathtoheaders = $moduleheaders{$lib} if ($moduleheaders{$lib});
816
817     my $allheadersprivate = 0;
818     $allheadersprivate = 1 if $allmoduleheadersprivate{$lib};
819
820     #information used after the syncing
821     my $pri_install_classes = "";
822     my $pri_install_files = "";
823     my $pri_install_pfiles = "";
824     my $pri_install_qpafiles = "";
825
826     #remove the old files
827     if($remove_stale) {
828         my %injections = ();
829         for my $p (keys %inject_headers) {
830             next unless ($p =~ /^\Q$dir\E(\/|$)/);
831             my $sp = $p;
832             $sp =~ s,^\Q$basedir\E/,$out_basedir/,;
833             for my $n (@{$inject_headers{$p}}) {
834                 $injections{$sp."/".$n} = 1;
835             }
836         }
837         my @subdirs = ("$out_basedir/include/$lib");
838         foreach my $subdir (@subdirs) {
839             if (opendir DIR, $subdir) {
840                 foreach my $t (sort { $b cmp $a } readdir(DIR)) {
841                     my $file = "$subdir/$t";
842                     if(-d $file) {
843                         push @subdirs, $file unless($t eq "." || $t eq "..");
844                     } else {
845                         my @files = ($file);
846                         #push @files, "$out_basedir/include/Qt/$t" if(-e "$out_basedir/include/Qt/$t");
847                         foreach my $file (@files) {
848                            my $remove_file = 0;
849                            if(open(F, "<$file")) {
850                                 while(my $line = <F>) {
851                                     chomp $line;
852                                     if($line =~ /^\#include \"([^\"]*)\"$/) {
853                                         my $include = $1;
854                                         $include = $subdir . "/" . $include unless(substr($include, 0, 1) eq "/");
855                                         $remove_file = 1 unless(-e $include or defined $injections{cleanPath($include)});
856                                     } else {
857                                         $remove_file = 0;
858                                         last;
859                                     }
860                                 }
861                                 close(F);
862                                 unlink $file if($remove_file);
863                             }
864                         }
865                     }
866                 }
867                 closedir DIR;
868             }
869
870         }
871     }
872
873     #create the new ones
874     foreach my $current_dir (@dirs) {
875         my $thisprivate = 0;
876         ($current_dir =~ s/^\^//) and $thisprivate = 1;
877         my @headers_paths = split(/;/, $pathtoheaders);
878         if (@headers_paths) {
879             @headers_paths = map { "$current_dir/$_" } @headers_paths;
880         } else {
881             push @headers_paths, $current_dir;
882         }
883
884         foreach my $headers_dir (@headers_paths) {
885             #calc subdirs
886             my @subdirs = listSubdirs($headers_dir);
887
888             #calc files and "copy" them
889             foreach my $subdir (@subdirs) {
890                 my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0);
891                 if (defined $inject_headers{$subdir}) {
892                     foreach my $if (@{$inject_headers{$subdir}}) {
893                         @headers = grep(!/^\Q$if\E$/, @headers); #in case we configure'd previously
894                         push @headers, "*".$if;
895                     }
896                 }
897                 my $header_dirname = "";
898                 foreach my $header (@headers) {
899                     my $shadow = ($header =~ s/^\*//);
900                     $header = 0 if($header =~ /^ui_.*.h/);
901                     foreach (@ignore_headers) {
902                         $header = 0 if($header eq $_);
903                     }
904                     if($header) {
905                         my $header_copies = 0;
906                         #figure out if it is a public header
907                         my $public_header = $header;
908                         my $qpa_header = 0;
909                         if(isQpaHeader($public_header)) {
910                             $public_header = 0;
911                             $qpa_header = 1;
912                         } elsif($allheadersprivate || $thisprivate || $public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
913                             $public_header = 0;
914                         } else {
915                             foreach (@ignore_for_master_contents) {
916                                 $public_header = 0 if($header eq $_);
917                             }
918                         }
919
920                         my $iheader = $subdir . "/" . $header;
921                         $iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow);
922                         my @classes = $public_header && !$minimal ? classNames($iheader) : ();
923                         if($showonly) {
924                             print "$header [$lib]\n";
925                             foreach(@classes) {
926                                 print "SYMBOL: $_\n";
927                             }
928                         } else {
929                             my $ts = (stat($iheader))[9];
930                             #find out all the places it goes..
931                             my @headers;
932                             if ($public_header) {
933                                 @headers = ( "$out_basedir/include/$lib/$header" );
934                                 foreach my $full_class (@classes) {
935                                     my $header_base = basename($header);
936                                     # Strip namespaces:
937                                     my $class = $full_class;
938                                     $class =~ s/^.*:://;
939     #                               if ($class =~ m/::/) {
940     #                                  class =~ s,::,/,g;
941     #                               }
942
943                                     if (defined $explicitheaders{$lib}{$class}) {
944                                         $header_copies++ if(syncHeader($lib, "$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$explicitheaders{$lib}{$class}", 0, $ts));
945                                     } else {
946                                         $class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n";
947                                         $header_copies++ if(syncHeader($lib, "$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0, $ts));
948                                     }
949
950                                     # KDE-Compat headers for Phonon
951                                     if ($lib eq "phonon") {
952                                         $header_copies++ if (syncHeader($lib, "$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0, $ts));
953                                     }
954                                 }
955
956                                 if ($explicitheaders{$lib}{basename($header)}) {
957                                     $header_copies++ if(syncHeader($lib, "$out_basedir/include/$lib/$explicitheaders{$lib}{basename($header)}", "$out_basedir/include/$lib/$header", 0, $ts));
958                                 }
959
960                             } elsif ($create_private_headers && !$qpa_header) {
961                                 @headers = ( "$out_basedir/include/$lib/$module_version/$lib/private/$header" );
962                             } elsif ($create_private_headers) {
963                                 @headers = ( "$out_basedir/include/$lib/$module_version/$lib/qpa/$header" );
964                             }
965
966                             foreach(@headers) { #sync them
967                                 $header_copies++ if(syncHeader($lib, $_, $iheader, $copy_headers && !$shadow, $ts));
968                             }
969
970                             if($public_header) {
971                                 #deal with the install directives
972                                 if($public_header) {
973                                     my $pri_install_iheader = fixPaths($iheader, $current_dir);
974                                     foreach my $class (@classes) {
975                                         # Strip namespaces:
976                                         $class =~ s/^.*:://;
977     #                                   if ($class =~ m/::/) {
978     #                                       $class =~ s,::,/,g;
979     #                                   }
980                                         my $class_header = fixPaths("$out_basedir/include/$lib/$class",
981                                                                     $current_dir) . " ";
982                                         $pri_install_classes .= $class_header
983                                                                     unless($pri_install_classes =~ $class_header);
984                                     }
985                                     if ($explicitheaders{$lib}{basename($iheader)}) {
986                                         my $compat_header = fixPaths("$out_basedir/include/$lib/$explicitheaders{$lib}{basename($iheader)}", $current_dir) . " ";
987                                         $pri_install_files .= $compat_header unless($pri_install_files =~ $compat_header);
988                                     }
989                                     $pri_install_files.= "$pri_install_iheader ";;
990                                 }
991                             }
992                             elsif ($qpa_header) {
993                                 my $pri_install_iheader = fixPaths($iheader, $current_dir);
994                                 $pri_install_qpafiles.= "$pri_install_iheader ";;
995                             }
996                             else {
997                                 my $pri_install_iheader = fixPaths($iheader, $current_dir);
998                                 $pri_install_pfiles.= "$pri_install_iheader ";;
999                             }
1000                         }
1001
1002                         if ($verbose_level && $header_copies) {
1003                             my $new_header_dirname = dirname($iheader);
1004                             basePrettify(\$new_header_dirname) if ($new_header_dirname && $verbose_level < 2);
1005                             my $header_base = basename($iheader);
1006                             if ($verbose_level < 3) {
1007                                 my $line_prefix = ",";
1008                                 if ($new_header_dirname ne $header_dirname) {
1009                                     $line_prefix = "$lib: created fwd-include header(s) for $new_header_dirname/ {";
1010                                     $line_prefix = " }\n".$line_prefix if ($header_dirname);
1011                                     $header_dirname = $new_header_dirname;
1012                                 } else {
1013                                     $line_prefix = ",";
1014                                 }
1015                                 print "$line_prefix $header_base ($header_copies)";
1016                             } else { # $verbose_level >= 3
1017                                 basePrettify(\$iheader) if ($verbose_level == 3);
1018                                 print "$lib: created $header_copies fwd-include headers for $iheader\n";
1019                             }
1020                         }
1021                     }
1022                 }
1023                 print " }\n" if ($header_dirname && $verbose_level > 0 && $verbose_level < 3);
1024             }
1025         }
1026     }
1027
1028     unless ($showonly || $minimal) {
1029         # create deprecated headers
1030         my $first = 1;
1031         while (my ($header, $include) = each %{$deprecatedheaders{$lib}}) {
1032             my $public_header = 0;
1033             $public_header = 1 unless ($allheadersprivate || ($header =~ /_p\.h$/));
1034             next unless ($public_header || $create_private_headers);
1035
1036             my $header_path = "$out_basedir/include/$lib/";
1037             unless ($public_header) {
1038                 $header_path .= "$module_version/$lib/private/";
1039             }
1040             $header_path .= "$header";
1041
1042             unless (-e $header_path) {
1043                 my $guard = "DEPRECATED_HEADER_" . $lib . "_" . $header;
1044                 $guard =~ s/([^a-zA-Z0-9_])/_/g;
1045
1046                 my $header_dir = dirname($header_path);
1047                 make_path($header_dir, $lib, $verbose_level);
1048
1049                 open(HEADER, ">$header_path") || die "Could not open $header_path for writing: $!\n";
1050                 print HEADER "#ifndef $guard\n";
1051                 print HEADER "#define $guard\n";
1052                 my $warning = "Header <$lib/";
1053                 $warning .= "private/" unless ($public_header);
1054                 $warning .= "$header> is deprecated. Please include <$include> instead.";
1055                 print HEADER "#if defined(__GNUC__)\n";
1056                 print HEADER "#  warning $warning\n";
1057                 print HEADER "#elif defined(_MSC_VER)\n";
1058                 print HEADER "#  pragma message (\"$warning\")\n";
1059                 print HEADER "#endif\n";
1060                 print HEADER "#include <$include>\n";
1061                 if ($public_header) {
1062                     print HEADER "#if 0\n";
1063                     print HEADER "#pragma qt_no_master_include\n";
1064                     print HEADER "#endif\n";
1065                 }
1066                 print HEADER "#endif\n";
1067                 close HEADER;
1068
1069                 if ($verbose_level < 3) {
1070                     my $line_prefix = ",";
1071                     $line_prefix = "$lib: created deprecated header(s) {" if ($first);
1072                     print "$line_prefix $header";
1073                 } else {
1074                     print "$lib: created deprecated header $header => $include\n";
1075                 }
1076                 $first = 0;
1077             }
1078
1079             my $addendum = fixPaths($header_path, $dir) . " ";
1080             if ($public_header) {
1081                 $pri_install_files .=  $addendum;
1082             } else {
1083                 $pri_install_pfiles .=  $addendum;
1084             }
1085         }
1086         if ($verbose_level < 3) {
1087             print " }\n" unless ($first);
1088         }
1089
1090         # module version header
1091         my $vheader = "$out_basedir/include/$lib/".lc($lib)."version.h";
1092         my $VHeader = "$out_basedir/include/$lib/${lib}Version";
1093         syncHeader($lib, $VHeader, $vheader, 0);
1094         $pri_install_files .= fixPaths($vheader, $dir) . " ";
1095         $pri_install_classes .= fixPaths($VHeader, $dir) . " ";
1096
1097         # KDE-Compat master header for Phonon
1098         if ($lib eq "phonon") {
1099             syncHeader($lib, "$out_basedir/include/phonon_compat/Phonon/Phonon", "$out_basedir/include/phonon/phonon", 0);
1100         }
1101
1102         #handle the headers.pri for each module
1103         my $headers_pri_contents = "";
1104         $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
1105         $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
1106         $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
1107         $headers_pri_contents .= "SYNCQT.QPA_HEADER_FILES = $pri_install_qpafiles\n";
1108         my $headers_pri_file = "$out_basedir/include/$lib/headers.pri";
1109         if(-e $headers_pri_file) {
1110             open HEADERS_PRI_FILE, "<$headers_pri_file";
1111             local $/;
1112             binmode HEADERS_PRI_FILE;
1113             my $old_headers_pri_contents = <HEADERS_PRI_FILE>;
1114             close HEADERS_PRI_FILE;
1115             $old_headers_pri_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
1116             $headers_pri_file = 0 if($old_headers_pri_contents eq $headers_pri_contents);
1117         }
1118         if($headers_pri_file) {
1119             my $headers_pri_dir = dirname($headers_pri_file);
1120             make_path($headers_pri_dir, $lib, $verbose_level);
1121             open HEADERS_PRI_FILE, ">$headers_pri_file";
1122             print HEADERS_PRI_FILE $headers_pri_contents;
1123             close HEADERS_PRI_FILE;
1124             print "$lib: created headers.pri file\n" if($verbose_level);
1125         }
1126     }
1127 }
1128 unless($showonly || !$create_uic_class_map) {
1129     my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h";
1130     if(-e $class_lib_map) {
1131         open CLASS_LIB_MAP, "<$class_lib_map";
1132         local $/;
1133         binmode CLASS_LIB_MAP;
1134         my $old_class_lib_map_contents = <CLASS_LIB_MAP>;
1135         close CLASS_LIB_MAP;
1136         $old_class_lib_map_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
1137         $class_lib_map = 0 if($old_class_lib_map_contents eq $class_lib_map_contents);
1138     }
1139     if($class_lib_map) {
1140         my $class_lib_map_dir = dirname($class_lib_map);
1141         make_path($class_lib_map_dir, "<outdir>", $verbose_level);
1142         open CLASS_LIB_MAP, ">$class_lib_map";
1143         print CLASS_LIB_MAP $class_lib_map_contents;
1144         close CLASS_LIB_MAP;
1145     }
1146 }
1147
1148 if($check_includes) {
1149     foreach my $lib (@modules_to_sync) {
1150             #calc subdirs
1151             my @subdirs = listSubdirs(map { s/^\^//; $_ } split(/;/, $modules{$lib}));
1152
1153             foreach my $subdir (@subdirs) {
1154                 my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0);
1155                 foreach my $header (@headers) {
1156                     my $header_skip_qt_begin_header_test = 0;
1157                     my $header_skip_qt_begin_namespace_test = 0;
1158                     $header = 0 if($header =~ /^ui_.*.h/);
1159                     foreach (@ignore_headers) {
1160                         $header = 0 if($header eq $_);
1161                     }
1162                     if($header) {
1163                         my $public_header = $header;
1164                         if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
1165                             $public_header = 0;
1166                         } elsif (isQpaHeader($public_header)) {
1167                             $public_header = 0;
1168                         } else {
1169                             foreach (@ignore_for_master_contents) {
1170                                 $public_header = 0 if($header eq $_);
1171                             }
1172                             if($public_header) {
1173                                 foreach (@ignore_for_include_check) {
1174                                     $public_header = 0 if($header eq $_);
1175                                 }
1176                                 foreach(@ignore_for_qt_begin_header_check) {
1177                                     $header_skip_qt_begin_header_test = 1 if ($header eq $_);
1178                                 }
1179                                 foreach(@ignore_for_qt_begin_namespace_check) {
1180                                     $header_skip_qt_begin_namespace_test = 1 if ($header eq $_);
1181                                 }
1182                             }
1183                         }
1184
1185                         my $iheader = $subdir . "/" . $header;
1186                         if($public_header) {
1187                             if(open(F, "<$iheader")) {
1188                                 my $qt_begin_header_found = 0;
1189                                 my $qt_end_header_found = 0;
1190                                 my $qt_begin_namespace_found = 0;
1191                                 my $qt_end_namespace_found = 0;
1192                                 my $line;
1193                                 my $stop_processing = 0;
1194                                 while($line = <F>) {
1195                                     chomp $line;
1196                                     my $output_line = 1;
1197                                     if($line =~ /^ *\# *pragma (qt_no_included_check|qt_sync_stop_processing)/) {
1198                                         $stop_processing = 1;
1199                                         last;
1200                                     } elsif($line =~ /^ *\# *include/) {
1201                                         my $include = $line;
1202                                         if($line =~ /<.*>/) {
1203                                             $include =~ s,.*<(.*)>.*,$1,;
1204                                         } elsif($line =~ /".*"/) {
1205                                             $include =~ s,.*"(.*)".*,$1,;
1206                                         } else {
1207                                             $include = 0;
1208                                         }
1209                                         if($include) {
1210                                             for my $trylib (keys(%modules)) {
1211                                                 if(-e "$out_basedir/include/$trylib/$include") {
1212                                                     print "$lib: WARNING: $iheader includes $include when it should include $trylib/$include\n";
1213                                                 }
1214                                             }
1215                                         }
1216                                     } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_BEGIN_HEADER\s*$/) {
1217                                         $qt_begin_header_found = 1;
1218                                     } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_END_HEADER\s*$/) {
1219                                         $qt_end_header_found = 1;
1220                                     } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_BEGIN_NAMESPACE\s*$/) {
1221                                         $qt_begin_namespace_found = 1;
1222                                     } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_END_NAMESPACE\s*$/) {
1223                                         $qt_end_namespace_found = 1;
1224                                     }
1225                                 }
1226                                 if ($header_skip_qt_begin_header_test == 0 and $stop_processing  == 0) {
1227                                     if ($qt_begin_header_found == 0) {
1228                                         print "$lib: WARNING: $iheader does not include QT_BEGIN_HEADER\n";
1229                                     }
1230
1231                                     if ($qt_begin_header_found && $qt_end_header_found == 0) {
1232                                         print "$lib: WARNING: $iheader has QT_BEGIN_HEADER but no QT_END_HEADER\n";
1233                                     }
1234                                 }
1235
1236                                 if ($header_skip_qt_begin_namespace_test == 0 and $stop_processing  == 0) {
1237                                     if ($qt_begin_namespace_found == 0) {
1238                                         print "$lib: WARNING: $iheader does not include QT_BEGIN_NAMESPACE\n";
1239                                     }
1240
1241                                     if ($qt_begin_namespace_found && $qt_end_namespace_found == 0) {
1242                                         print "$lib: WARNING: $iheader has QT_BEGIN_NAMESPACE but no QT_END_NAMESPACE\n";
1243                                     }
1244                                 }
1245
1246                                 close(F);
1247                             }
1248                         }
1249                     }
1250                 }
1251             }
1252     }
1253 }
1254
1255 exit 0;