1#!/usr/bin/perl
2
3use warnings;
4use strict;
5
6=head1 create_project_files.pl
7
8This simple script traverses the haiku sources and creates (incomplete) *.pro
9files in order to make the haiku sources available within the qt-creator IDE.
10Additionally, it will add those files to svn:ignore of their parent directory
11(unless already contained there).
12
13=cut
14
15use File::Basename;
16use File::Find;
17
18if (!@ARGV) {
19	die "usage: $0 <haiku-top-path>\n";
20}
21
22my $haikuTop = shift @ARGV;
23if (!-e "$haikuTop/ReadMe.cross-compile") {
24	die "'$haikuTop/ReadMe.cross-compile' not found - not a haiku top!\n";
25}
26
27my %collection;
28
29print "scanning ...\n";
30find({ wanted => \&process, no_chdir => 1},
31	("$haikuTop/headers", "$haikuTop/src"));
32
33writeProFile("$haikuTop/haiku.pro", { subdirs => ['headers', 'src'] });
34foreach my $dir (sort keys %collection) {
35	my $proFile = $dir.'/'.fileparse($dir).'.pro';
36	writeProFile($proFile, $collection{$dir});
37}
38
39sub process
40{
41	if (substr($_, -4, 4) eq '.svn') {
42		$File::Find::prune = 1;
43	} else {
44		return if $File::Find::dir eq $_;	# skip toplevel folders
45		my $name = (fileparse($_))[0];
46		if (-d $_) {
47			$collection{$File::Find::dir}->{subdirs} ||= [];
48			push @{$collection{$File::Find::dir}->{subdirs}}, $name;
49			return;
50		}
51		elsif ($_ =~ m{\.(h|hpp)$}i) {
52			$collection{$File::Find::dir}->{headers} ||= [];
53			push @{$collection{$File::Find::dir}->{headers}}, $name;
54		}
55		elsif ($_ =~ m{\.(c|cc|cpp|s|asm)$}i) {
56			$collection{$File::Find::dir}->{sources} ||= [];
57			push @{$collection{$File::Find::dir}->{sources}}, $name;
58		}
59	}
60}
61
62sub writeProFile
63{
64	my ($proFile, $info) = @_;
65
66	return if !$info;
67
68	print "creating $proFile\n";
69	open(my $proFileFH, '>', $proFile)
70		or die "unable to write $proFile";
71	print $proFileFH "TEMPLATE = subdirs\n";
72	print $proFileFH "CONFIG += ordered\n";
73	if (exists $info->{subdirs}) {
74		print $proFileFH
75			"SUBDIRS = ".join(" \\\n\t", sort @{$info->{subdirs}})."\n";
76	}
77	if (exists $info->{headers}) {
78		print $proFileFH
79			"HEADERS = ".join(" \\\n\t", sort @{$info->{headers}})."\n";
80	}
81	if (exists $info->{sources}) {
82		print $proFileFH
83			"SOURCES = ".join(" \\\n\t", sort @{$info->{sources}})."\n";
84	}
85	close $proFileFH;
86
87	updateSvnIgnore($proFile);
88}
89
90sub updateSvnIgnore
91{
92	my $proFile = shift;
93
94	my ($filename, $parentDir) = fileparse($proFile);
95
96	my $svnIgnore = qx{svn propget --strict svn:ignore $parentDir};
97	if (!grep { $_ eq $filename } split "\n", $svnIgnore) {
98		chomp $svnIgnore;
99		$svnIgnore .= "\n" unless !$svnIgnore;
100		$svnIgnore .= "$filename\n";
101		open(my $propsetFH, "|svn propset svn:ignore --file - $parentDir")
102			or die "unable to open pipe to 'svn propset'";
103		print $propsetFH $svnIgnore;
104		close($propsetFH);
105	}
106}
107