|
1 #!/usr/bin/perl |
|
2 ############################################################################ |
|
3 # |
|
4 # |
|
5 # Generates a tmake project file. |
|
6 # |
|
7 # Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved. |
|
8 # |
|
9 # Permission to use, copy, modify, and distribute this software and its |
|
10 # documentation for any purpose and without fee is hereby granted, provided |
|
11 # that this copyright notice appears in all copies. |
|
12 # No representations are made about the suitability of this software for any |
|
13 # purpose. It is provided "as is" without express or implied warranty. |
|
14 # |
|
15 ############################################################################ |
|
16 |
|
17 # Default project settings |
|
18 $project{"TEMPLATE"} = "app"; |
|
19 $project{"CONFIG"} = "qt warn_on release"; |
|
20 |
|
21 @project_extra = (); |
|
22 |
|
23 while ( @ARGV ) { # parse command line args |
|
24 $_ = shift @ARGV; |
|
25 if ( s/^-// ) { |
|
26 if ( /^o(.*)/ ) { |
|
27 $outfile = ($1 eq "") ? shift @ARGV : $1; |
|
28 ($outfile eq "-") && ($outfile = ""); |
|
29 } elsif ( /^n(.*)/ ) { |
|
30 $project{"TARGET"} = ($1 eq "") ? shift @ARGV : $1; |
|
31 } elsif ( /^t(.*)/ ) { |
|
32 $project{"TEMPLATE"} = ($1 eq "") ? shift @ARGV : $1; |
|
33 $project{"TEMPLATE"} =~ s/\.t$//i; |
|
34 } elsif ( /lower/ ) { |
|
35 $tolower = 1; |
|
36 } else { |
|
37 &progen_usage; |
|
38 } |
|
39 } elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override |
|
40 push( @project_extra, $_ ); |
|
41 } else { |
|
42 push (@files, $_ ); |
|
43 } |
|
44 } |
|
45 |
|
46 $outfile eq "" || open(STDOUT,">" . $outfile) || |
|
47 &progen_error("Can't create \"$outfile\""); |
|
48 |
|
49 if ( ! @files ) { |
|
50 @files = &find_files(".",".*",1); |
|
51 } |
|
52 |
|
53 if ( $tolower ) { |
|
54 foreach $f ( @files ) { |
|
55 $f =~ tr/A-Z/a-z/; |
|
56 } |
|
57 } |
|
58 |
|
59 @hdr = sort grep(/\.(h|hh|hpp|hxx)$/i,@files); |
|
60 @src = sort grep(/\.(c|cpp|cc|cxx)$/i && ! /moc_/i,@files); |
|
61 |
|
62 # Remove source files that are included by other source files |
|
63 foreach $f ( @src ) { |
|
64 $srcdict{$f} = 1; |
|
65 } |
|
66 foreach $f ( @src ) { |
|
67 if ( open(F,"< $f") ) { |
|
68 while ( <F> ) { |
|
69 if ( /^\s*#\s*include\s+\"([^\"]*)\"/ ) { |
|
70 $srcdict{$1} = 0; |
|
71 } |
|
72 } |
|
73 } |
|
74 } |
|
75 foreach $f( @src ) { |
|
76 $srcdict{$f} && (push(@src2,$f)); |
|
77 } |
|
78 @src = @src2; |
|
79 |
|
80 $project{"HEADERS"} = join(" ",sort @hdr); |
|
81 $project{"SOURCES"} = join(" ",sort @src); |
|
82 |
|
83 foreach $p ( @project_extra ) { |
|
84 if ( $p =~ /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) { |
|
85 if ( $project{$1} ne "" ) { |
|
86 Project($p); |
|
87 } |
|
88 } |
|
89 } |
|
90 |
|
91 $project{"HEADERS"} =~ s/\s+/ \\\n\t\t /g; |
|
92 $project{"SOURCES"} =~ s/\s+/ \\\n\t\t /g; |
|
93 |
|
94 print "TEMPLATE\t= " . $project{"TEMPLATE"} . "\n"; |
|
95 print "CONFIG\t\t= " . $project{"CONFIG"} . "\n"; |
|
96 print "HEADERS\t\t= " . $project{"HEADERS"} . "\n"; |
|
97 print "SOURCES\t\t= " . $project{"SOURCES"} . "\n"; |
|
98 if ( $project{"TARGET"} ne "" ) { |
|
99 print "TARGET\t\t= " . $project{"TARGET"} . "\n"; |
|
100 } |
|
101 |
|
102 foreach ( @project_extra ) { |
|
103 if ( /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) { |
|
104 if ( $project{$1} eq "" ) { |
|
105 $t = $1; |
|
106 if ( length($t) < 8 ) { |
|
107 $t .= "\t\t"; |
|
108 } elsif ( length($t) < 16 ) { |
|
109 $t .= "\t"; |
|
110 } else { |
|
111 $t .= " "; |
|
112 } |
|
113 print "$t$2= $3\n"; |
|
114 } |
|
115 } |
|
116 } |
|
117 |
|
118 exit 0; |
|
119 |
|
120 |
|
121 # |
|
122 # progen_usage() |
|
123 # |
|
124 # Prints a message about program usage and exits |
|
125 # |
|
126 |
|
127 sub progen_usage { |
|
128 print STDERR "Usage:\n progen [options] [files]\n"; |
|
129 print STDERR "Options:\n"; |
|
130 print STDERR " -lower Lower-case letters filenames (useful for non-Unix)\n"; |
|
131 print STDERR " -n name Specify a project name (= TARGET)\n"; |
|
132 print STDERR " -o file Write output to \"file\"\n"; |
|
133 print STDERR " -t file Specify a template file other than qtapp\n"; |
|
134 exit 1; |
|
135 } |
|
136 |
|
137 |
|
138 # |
|
139 # progen_error(msg) |
|
140 # |
|
141 # Prints the message and exits |
|
142 # |
|
143 |
|
144 sub progen_error { |
|
145 my($msg) = @_; |
|
146 print STDERR "progen error: " . $msg . "\n"; |
|
147 exit 1; |
|
148 } |
|
149 |
|
150 |
|
151 # |
|
152 # Finds files. |
|
153 # |
|
154 # Examples: |
|
155 # find_files("/usr","\.cpp$",1) - finds .cpp files in /usr and below |
|
156 # find_files("/tmp","^#",0) - finds #* files in /tmp |
|
157 # |
|
158 |
|
159 sub find_files { |
|
160 my($dir,$match,$descend) = @_; |
|
161 my($file,$p,@files); |
|
162 local(*D); |
|
163 $dir =~ s=\\=/=g; |
|
164 ($dir eq "") && ($dir = "."); |
|
165 if ( opendir(D,$dir) ) { |
|
166 if ( $dir eq "." ) { |
|
167 $dir = ""; |
|
168 } else { |
|
169 ($dir =~ /\/$/) || ($dir .= "/"); |
|
170 } |
|
171 foreach $file ( readdir(D) ) { |
|
172 next if ( $file =~ /^\.\.?$/ ); |
|
173 $p = $dir . $file; |
|
174 ($file =~ /$match/i) && (push @files, $p); |
|
175 if ( $descend && -d $p && ! -l $p ) { |
|
176 push @files, &find_files($p,$match,$descend); |
|
177 } |
|
178 } |
|
179 closedir(D); |
|
180 } |
|
181 return @files; |
|
182 } |
|
183 |
|
184 |
|
185 # |
|
186 # strip_project_val(tag) |
|
187 # |
|
188 # Strips white space from project value strings. |
|
189 # |
|
190 |
|
191 sub strip_project_val { |
|
192 my($v) = @_; |
|
193 $v =~ s/^\s+//; # trim white space |
|
194 $v =~ s/\s+$//; |
|
195 return $v; |
|
196 } |
|
197 |
|
198 |
|
199 # |
|
200 # Project(strings) |
|
201 # |
|
202 # This is a powerful function for setting or reading project variables. |
|
203 # Returns the resulting project variables (joined with space between). |
|
204 # |
|
205 # This is a slightly modified version of the Project function in tmake. |
|
206 |
|
207 sub Project { |
|
208 my @settings = @_; |
|
209 my($r,$t,$s,$v,$p,$c); |
|
210 $r = ""; |
|
211 foreach ( @settings ) { |
|
212 $v = $_; |
|
213 if ( $v =~ s/^\s*((?:[\w\-]+:)?\w+)\s*(\+=|\*=|\-=|\/=|=)\s*// ) { |
|
214 $t = $1; |
|
215 $s = $2; |
|
216 $v = strip_project_val($v); |
|
217 $p = $project{$t}; |
|
218 if ( $s eq "=" ) { # set variable |
|
219 $p = $v; |
|
220 } elsif ( $s eq "+=" ) { # append |
|
221 if ( $p eq "" ) { |
|
222 $p = $v; |
|
223 } else { |
|
224 $p .= " " . $v; |
|
225 } |
|
226 } elsif ( $s eq "*=" ) { # append if not contained |
|
227 if ( !($p =~ /(?:^|\s)\Q$v\E(?:\s|$)/) ) { |
|
228 if ( $p eq "" ) { |
|
229 $p = $v; |
|
230 } else { |
|
231 $p .= " " . $v; |
|
232 } |
|
233 } |
|
234 } elsif ( $s eq "-=" ) { # subtract |
|
235 $p =~ s/$v//g; |
|
236 } elsif ( $s eq "/=" ) { # sed |
|
237 $cmd = '$p =~ ' . $v; |
|
238 eval $cmd; |
|
239 } |
|
240 $project{$t} = strip_project_val($p); |
|
241 } else { |
|
242 $p = strip_project_val($project{$v}); |
|
243 } |
|
244 if ( $p ne "" ) { |
|
245 $r = ($r eq "") ? $p : ($r . " " . $p); |
|
246 } |
|
247 } |
|
248 return $r; |
|
249 } |