diff options
Diffstat (limited to 'src/contrib/SDL-3.2.20/build-scripts/add-source-to-projects.pl')
-rwxr-xr-x | src/contrib/SDL-3.2.20/build-scripts/add-source-to-projects.pl | 599 |
1 files changed, 599 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/build-scripts/add-source-to-projects.pl b/src/contrib/SDL-3.2.20/build-scripts/add-source-to-projects.pl new file mode 100755 index 0000000..5ba0a69 --- /dev/null +++ b/src/contrib/SDL-3.2.20/build-scripts/add-source-to-projects.pl | |||
@@ -0,0 +1,599 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | |||
3 | # Add source files and headers to Xcode and Visual Studio projects. | ||
4 | # THIS IS NOT ROBUST, THIS IS JUST RYAN AVOIDING RUNNING BETWEEN | ||
5 | # THREE COMPUTERS AND A BUNCH OF DEVELOPMENT ENVIRONMENTS TO ADD | ||
6 | # A STUPID FILE TO THE BUILD. | ||
7 | |||
8 | |||
9 | use warnings; | ||
10 | use strict; | ||
11 | use File::Basename; | ||
12 | |||
13 | |||
14 | my %xcode_references = (); | ||
15 | sub generate_xcode_id { | ||
16 | my @chars = ('0'..'9', 'A'..'F'); | ||
17 | my $str; | ||
18 | |||
19 | do { | ||
20 | my $len = 16; | ||
21 | $str = '0000'; # start and end with '0000' so we know we added it. | ||
22 | while ($len--) { | ||
23 | $str .= $chars[rand @chars] | ||
24 | }; | ||
25 | $str .= '0000'; # start and end with '0000' so we know we added it. | ||
26 | } while (defined($xcode_references{$str})); | ||
27 | |||
28 | $xcode_references{$str} = 1; # so future calls can't generate this one. | ||
29 | |||
30 | return $str; | ||
31 | } | ||
32 | |||
33 | sub process_xcode { | ||
34 | my $addpath = shift; | ||
35 | my $pbxprojfname = shift; | ||
36 | my $lineno; | ||
37 | |||
38 | %xcode_references = (); | ||
39 | |||
40 | my $addfname = basename($addpath); | ||
41 | my $addext = ''; | ||
42 | if ($addfname =~ /\.(.*?)\Z/) { | ||
43 | $addext = $1; | ||
44 | } | ||
45 | |||
46 | my $is_public_header = ($addpath =~ /\Ainclude\/SDL3\//) ? 1 : 0; | ||
47 | my $filerefpath = $is_public_header ? "SDL3/$addfname" : $addfname; | ||
48 | |||
49 | my $srcs_or_headers = ''; | ||
50 | my $addfiletype = ''; | ||
51 | |||
52 | if ($addext eq 'c') { | ||
53 | $srcs_or_headers = 'Sources'; | ||
54 | $addfiletype = 'sourcecode.c.c'; | ||
55 | } elsif ($addext eq 'm') { | ||
56 | $srcs_or_headers = 'Sources'; | ||
57 | $addfiletype = 'sourcecode.c.objc'; | ||
58 | } elsif ($addext eq 'h') { | ||
59 | $srcs_or_headers = 'Headers'; | ||
60 | $addfiletype = 'sourcecode.c.h'; | ||
61 | } else { | ||
62 | die("Unexpected file extension '$addext'\n"); | ||
63 | } | ||
64 | |||
65 | my $fh; | ||
66 | |||
67 | open $fh, '<', $pbxprojfname or die("Failed to open '$pbxprojfname': $!\n"); | ||
68 | chomp(my @pbxproj = <$fh>); | ||
69 | close($fh); | ||
70 | |||
71 | # build a table of all ids, in case we duplicate one by some miracle. | ||
72 | $lineno = 0; | ||
73 | foreach (@pbxproj) { | ||
74 | $lineno++; | ||
75 | |||
76 | # like "F3676F582A7885080091160D /* SDL3.dmg */ = {" | ||
77 | if (/\A\t\t([A-F0-9]{24}) \/\* (.*?) \*\/ \= \{\Z/) { | ||
78 | $xcode_references{$1} = $2; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | # build out of a tree of PBXGroup items. | ||
83 | my %pbxgroups = (); | ||
84 | my $thispbxgroup; | ||
85 | my $pbxgroup_children; | ||
86 | my $pbxgroup_state = 0; | ||
87 | my $pubheaders_group_hash = ''; | ||
88 | my $libsrc_group_hash = ''; | ||
89 | $lineno = 0; | ||
90 | foreach (@pbxproj) { | ||
91 | $lineno++; | ||
92 | if ($pbxgroup_state == 0) { | ||
93 | $pbxgroup_state++ if /\A\/\* Begin PBXGroup section \*\/\Z/; | ||
94 | } elsif ($pbxgroup_state == 1) { | ||
95 | # like "F3676F582A7885080091160D /* SDL3.dmg */ = {" | ||
96 | if (/\A\t\t([A-F0-9]{24}) \/\* (.*?) \*\/ \= \{\Z/) { | ||
97 | my %newhash = (); | ||
98 | $pbxgroups{$1} = \%newhash; | ||
99 | $thispbxgroup = \%newhash; | ||
100 | $pubheaders_group_hash = $1 if $2 eq 'Public Headers'; | ||
101 | $libsrc_group_hash = $1 if $2 eq 'Library Source'; | ||
102 | $pbxgroup_state++; | ||
103 | } elsif (/\A\/\* End PBXGroup section \*\/\Z/) { | ||
104 | last; | ||
105 | } else { | ||
106 | die("Expected pbxgroup obj on '$pbxprojfname' line $lineno\n"); | ||
107 | } | ||
108 | } elsif ($pbxgroup_state == 2) { | ||
109 | if (/\A\t\t\tisa \= PBXGroup;\Z/) { | ||
110 | $pbxgroup_state++; | ||
111 | } else { | ||
112 | die("Expected pbxgroup obj's isa field on '$pbxprojfname' line $lineno\n"); | ||
113 | } | ||
114 | } elsif ($pbxgroup_state == 3) { | ||
115 | if (/\A\t\t\tchildren \= \(\Z/) { | ||
116 | my %newhash = (); | ||
117 | $$thispbxgroup{'children'} = \%newhash; | ||
118 | $pbxgroup_children = \%newhash; | ||
119 | $pbxgroup_state++; | ||
120 | } else { | ||
121 | die("Expected pbxgroup obj's children field on '$pbxprojfname' line $lineno\n"); | ||
122 | } | ||
123 | } elsif ($pbxgroup_state == 4) { | ||
124 | if (/\A\t\t\t\t([A-F0-9]{24}) \/\* (.*?) \*\/,\Z/) { | ||
125 | $$pbxgroup_children{$1} = $2; | ||
126 | } elsif (/\A\t\t\t\);\Z/) { | ||
127 | $pbxgroup_state++; | ||
128 | } else { | ||
129 | die("Expected pbxgroup obj's children element on '$pbxprojfname' line $lineno\n"); | ||
130 | } | ||
131 | } elsif ($pbxgroup_state == 5) { | ||
132 | if (/\A\t\t\t(.*?) \= (.*?);\Z/) { | ||
133 | $$thispbxgroup{$1} = $2; | ||
134 | } elsif (/\A\t\t\};\Z/) { | ||
135 | $pbxgroup_state = 1; | ||
136 | } else { | ||
137 | die("Expected pbxgroup obj field on '$pbxprojfname' line $lineno\n"); | ||
138 | } | ||
139 | } else { | ||
140 | die("bug in this script."); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | die("Didn't see PBXGroup section in '$pbxprojfname'. Bug?\n") if $pbxgroup_state == 0; | ||
145 | die("Didn't see Public Headers PBXGroup in '$pbxprojfname'. Bug?\n") if $pubheaders_group_hash eq ''; | ||
146 | die("Didn't see Library Source PBXGroup in '$pbxprojfname'. Bug?\n") if $libsrc_group_hash eq ''; | ||
147 | |||
148 | # Some debug log dumping... | ||
149 | if (0) { | ||
150 | foreach (keys %pbxgroups) { | ||
151 | my $k = $_; | ||
152 | my $g = $pbxgroups{$k}; | ||
153 | print("$_:\n"); | ||
154 | foreach (keys %$g) { | ||
155 | print(" $_:\n"); | ||
156 | if ($_ eq 'children') { | ||
157 | my $kids = $$g{$_}; | ||
158 | foreach (keys %$kids) { | ||
159 | print(" $_ -> " . $$kids{$_} . "\n"); | ||
160 | } | ||
161 | } else { | ||
162 | print(' ' . $$g{$_} . "\n"); | ||
163 | } | ||
164 | } | ||
165 | print("\n"); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | # Get some unique IDs for our new thing. | ||
170 | my $fileref = generate_xcode_id(); | ||
171 | my $buildfileref = generate_xcode_id(); | ||
172 | |||
173 | |||
174 | # Figure out what group to insert this into (or what groups to make) | ||
175 | my $add_to_group_fileref = $fileref; | ||
176 | my $add_to_group_addfname = $addfname; | ||
177 | my $newgrptext = ''; | ||
178 | my $grphash = ''; | ||
179 | if ($is_public_header) { | ||
180 | $grphash = $pubheaders_group_hash; # done! | ||
181 | } else { | ||
182 | $grphash = $libsrc_group_hash; | ||
183 | my @splitpath = split(/\//, dirname($addpath)); | ||
184 | if ($splitpath[0] eq 'src') { | ||
185 | shift @splitpath; | ||
186 | } | ||
187 | while (my $elem = shift(@splitpath)) { | ||
188 | my $g = $pbxgroups{$grphash}; | ||
189 | my $kids = $$g{'children'}; | ||
190 | my $found = 0; | ||
191 | foreach (keys %$kids) { | ||
192 | my $hash = $_; | ||
193 | my $fname = $$kids{$hash}; | ||
194 | if (uc($fname) eq uc($elem)) { | ||
195 | $grphash = $hash; | ||
196 | $found = 1; | ||
197 | last; | ||
198 | } | ||
199 | } | ||
200 | unshift(@splitpath, $elem), last if (not $found); | ||
201 | } | ||
202 | |||
203 | if (@splitpath) { # still elements? We need to build groups. | ||
204 | my $newgroupref = generate_xcode_id(); | ||
205 | |||
206 | $add_to_group_fileref = $newgroupref; | ||
207 | $add_to_group_addfname = $splitpath[0]; | ||
208 | |||
209 | while (my $elem = shift(@splitpath)) { | ||
210 | my $lastelem = @splitpath ? 0 : 1; | ||
211 | my $childhash = $lastelem ? $fileref : generate_xcode_id(); | ||
212 | my $childpath = $lastelem ? $addfname : $splitpath[0]; | ||
213 | $newgrptext .= "\t\t$newgroupref /* $elem */ = {\n"; | ||
214 | $newgrptext .= "\t\t\tisa = PBXGroup;\n"; | ||
215 | $newgrptext .= "\t\t\tchildren = (\n"; | ||
216 | $newgrptext .= "\t\t\t\t$childhash /* $childpath */,\n"; | ||
217 | $newgrptext .= "\t\t\t);\n"; | ||
218 | $newgrptext .= "\t\t\tpath = $elem;\n"; | ||
219 | $newgrptext .= "\t\t\tsourceTree = \"<group>\";\n"; | ||
220 | $newgrptext .= "\t\t};\n"; | ||
221 | $newgroupref = $childhash; | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | my $tmpfname = "$pbxprojfname.tmp"; | ||
227 | open $fh, '>', $tmpfname or die("Failed to open '$tmpfname': $!\n"); | ||
228 | |||
229 | my $add_to_this_group = 0; | ||
230 | $pbxgroup_state = 0; | ||
231 | $lineno = 0; | ||
232 | foreach (@pbxproj) { | ||
233 | $lineno++; | ||
234 | if ($pbxgroup_state == 0) { | ||
235 | # Drop in new references at the end of their sections... | ||
236 | if (/\A\/\* End PBXBuildFile section \*\/\Z/) { | ||
237 | print $fh "\t\t$buildfileref /* $addfname in $srcs_or_headers */ = {isa = PBXBuildFile; fileRef = $fileref /* $addfname */;"; | ||
238 | if ($is_public_header) { | ||
239 | print $fh " settings = {ATTRIBUTES = (Public, ); };"; | ||
240 | } | ||
241 | print $fh " };\n"; | ||
242 | } elsif (/\A\/\* End PBXFileReference section \*\/\Z/) { | ||
243 | print $fh "\t\t$fileref /* $addfname */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = $addfiletype; name = $addfname; path = $filerefpath; sourceTree = \"<group>\"; };\n"; | ||
244 | } elsif (/\A\/\* Begin PBXGroup section \*\/\Z/) { | ||
245 | $pbxgroup_state = 1; | ||
246 | } elsif (/\A\/\* Begin PBXSourcesBuildPhase section \*\/\Z/) { | ||
247 | $pbxgroup_state = 5; | ||
248 | } | ||
249 | } elsif ($pbxgroup_state == 1) { | ||
250 | if (/\A\t\t([A-F0-9]{24}) \/\* (.*?) \*\/ \= \{\Z/) { | ||
251 | $pbxgroup_state++; | ||
252 | $add_to_this_group = $1 eq $grphash; | ||
253 | } elsif (/\A\/\* End PBXGroup section \*\/\Z/) { | ||
254 | print $fh $newgrptext; | ||
255 | $pbxgroup_state = 0; | ||
256 | } | ||
257 | } elsif ($pbxgroup_state == 2) { | ||
258 | if (/\A\t\t\tchildren \= \(\Z/) { | ||
259 | $pbxgroup_state++; | ||
260 | } | ||
261 | } elsif ($pbxgroup_state == 3) { | ||
262 | if (/\A\t\t\t\);\Z/) { | ||
263 | if ($add_to_this_group) { | ||
264 | print $fh "\t\t\t\t$add_to_group_fileref /* $add_to_group_addfname */,\n"; | ||
265 | } | ||
266 | $pbxgroup_state++; | ||
267 | } | ||
268 | } elsif ($pbxgroup_state == 4) { | ||
269 | if (/\A\t\t\};\Z/) { | ||
270 | $add_to_this_group = 0; | ||
271 | } | ||
272 | $pbxgroup_state = 1; | ||
273 | } elsif ($pbxgroup_state == 5) { | ||
274 | if (/\A\t\t\t\);\Z/) { | ||
275 | if ($srcs_or_headers eq 'Sources') { | ||
276 | print $fh "\t\t\t\t$buildfileref /* $addfname in $srcs_or_headers */,\n"; | ||
277 | } | ||
278 | $pbxgroup_state = 0; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | print $fh "$_\n"; | ||
283 | } | ||
284 | |||
285 | close($fh); | ||
286 | rename($tmpfname, $pbxprojfname); | ||
287 | } | ||
288 | |||
289 | my %visualc_references = (); | ||
290 | sub generate_visualc_id { # these are just standard Windows GUIDs. | ||
291 | my @chars = ('0'..'9', 'a'..'f'); | ||
292 | my $str; | ||
293 | |||
294 | do { | ||
295 | my $len = 24; | ||
296 | $str = '0000'; # start and end with '0000' so we know we added it. | ||
297 | while ($len--) { | ||
298 | $str .= $chars[rand @chars] | ||
299 | }; | ||
300 | $str .= '0000'; # start and end with '0000' so we know we added it. | ||
301 | $str =~ s/\A(........)(....)(....)(............)\Z/$1-$2-$3-$4/; # add dashes in the appropriate places. | ||
302 | } while (defined($visualc_references{$str})); | ||
303 | |||
304 | $visualc_references{$str} = 1; # so future calls can't generate this one. | ||
305 | |||
306 | return $str; | ||
307 | } | ||
308 | |||
309 | |||
310 | sub process_visualstudio { | ||
311 | my $addpath = shift; | ||
312 | my $vcxprojfname = shift; | ||
313 | my $lineno; | ||
314 | |||
315 | %visualc_references = (); | ||
316 | |||
317 | my $is_public_header = ($addpath =~ /\Ainclude\/SDL3\//) ? 1 : 0; | ||
318 | |||
319 | my $addfname = basename($addpath); | ||
320 | my $addext = ''; | ||
321 | if ($addfname =~ /\.(.*?)\Z/) { | ||
322 | $addext = $1; | ||
323 | } | ||
324 | |||
325 | my $isheader = 0; | ||
326 | if ($addext eq 'c') { | ||
327 | $isheader = 0; | ||
328 | } elsif ($addext eq 'm') { | ||
329 | return; # don't add Objective-C files to Visual Studio projects! | ||
330 | } elsif ($addext eq 'h') { | ||
331 | $isheader = 1; | ||
332 | } else { | ||
333 | die("Unexpected file extension '$addext'\n"); | ||
334 | } | ||
335 | |||
336 | my $fh; | ||
337 | |||
338 | open $fh, '<', $vcxprojfname or die("Failed to open '$vcxprojfname': $!\n"); | ||
339 | chomp(my @vcxproj = <$fh>); | ||
340 | close($fh); | ||
341 | |||
342 | my $vcxgroup_state; | ||
343 | |||
344 | my $rawaddvcxpath = "$addpath"; | ||
345 | $rawaddvcxpath =~ s/\//\\/g; | ||
346 | |||
347 | # Figure out relative path from vcxproj file... | ||
348 | my $addvcxpath = ''; | ||
349 | my @subdirs = split(/\//, $vcxprojfname); | ||
350 | pop @subdirs; | ||
351 | foreach (@subdirs) { | ||
352 | $addvcxpath .= "..\\"; | ||
353 | } | ||
354 | $addvcxpath .= $rawaddvcxpath; | ||
355 | |||
356 | my $prevname = undef; | ||
357 | |||
358 | my $tmpfname; | ||
359 | |||
360 | $tmpfname = "$vcxprojfname.tmp"; | ||
361 | open $fh, '>', $tmpfname or die("Failed to open '$tmpfname': $!\n"); | ||
362 | |||
363 | my $added = 0; | ||
364 | |||
365 | $added = 0; | ||
366 | $vcxgroup_state = 0; | ||
367 | $prevname = undef; | ||
368 | $lineno = 0; | ||
369 | foreach (@vcxproj) { | ||
370 | $lineno++; | ||
371 | if ($vcxgroup_state == 0) { | ||
372 | if (/\A \<ItemGroup\>\Z/) { | ||
373 | $vcxgroup_state = 1; | ||
374 | $prevname = undef; | ||
375 | } | ||
376 | } elsif ($vcxgroup_state == 1) { | ||
377 | if (/\A \<ClInclude .*\Z/) { | ||
378 | $vcxgroup_state = 2 if $isheader; | ||
379 | } elsif (/\A \<ClCompile .*\Z/) { | ||
380 | $vcxgroup_state = 3 if not $isheader; | ||
381 | } elsif (/\A \<\/ItemGroup\>\Z/) { | ||
382 | $vcxgroup_state = 0; | ||
383 | $prevname = undef; | ||
384 | } | ||
385 | } | ||
386 | |||
387 | # Don't do elsif, we need to check this line again. | ||
388 | if ($vcxgroup_state == 2) { | ||
389 | if (/\A <ClInclude Include="(.*?)" \/\>\Z/) { | ||
390 | my $nextname = $1; | ||
391 | if ((not $added) && (((not defined $prevname) || (uc($prevname) lt uc($addvcxpath))) && (uc($nextname) gt uc($addvcxpath)))) { | ||
392 | print $fh " <ClInclude Include=\"$addvcxpath\" />\n"; | ||
393 | $vcxgroup_state = 0; | ||
394 | $added = 1; | ||
395 | } | ||
396 | $prevname = $nextname; | ||
397 | } elsif (/\A \<\/ItemGroup\>\Z/) { | ||
398 | if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { | ||
399 | print $fh " <ClInclude Include=\"$addvcxpath\" />\n"; | ||
400 | $vcxgroup_state = 0; | ||
401 | $added = 1; | ||
402 | } | ||
403 | } | ||
404 | } elsif ($vcxgroup_state == 3) { | ||
405 | if (/\A <ClCompile Include="(.*?)" \/\>\Z/) { | ||
406 | my $nextname = $1; | ||
407 | if ((not $added) && (((not defined $prevname) || (uc($prevname) lt uc($addvcxpath))) && (uc($nextname) gt uc($addvcxpath)))) { | ||
408 | print $fh " <ClCompile Include=\"$addvcxpath\" />\n"; | ||
409 | $vcxgroup_state = 0; | ||
410 | $added = 1; | ||
411 | } | ||
412 | $prevname = $nextname; | ||
413 | } elsif (/\A \<\/ItemGroup\>\Z/) { | ||
414 | if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { | ||
415 | print $fh " <ClCompile Include=\"$addvcxpath\" />\n"; | ||
416 | $vcxgroup_state = 0; | ||
417 | $added = 1; | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | |||
422 | print $fh "$_\n"; | ||
423 | } | ||
424 | |||
425 | close($fh); | ||
426 | rename($tmpfname, $vcxprojfname); | ||
427 | |||
428 | my $vcxfiltersfname = "$vcxprojfname.filters"; | ||
429 | open $fh, '<', $vcxfiltersfname or die("Failed to open '$vcxfiltersfname': $!\n"); | ||
430 | chomp(my @vcxfilters = <$fh>); | ||
431 | close($fh); | ||
432 | |||
433 | my $newgrptext = ''; | ||
434 | my $filter = ''; | ||
435 | if ($is_public_header) { | ||
436 | $filter = 'API Headers'; | ||
437 | } else { | ||
438 | $filter = lc(dirname($addpath)); | ||
439 | $filter =~ s/\Asrc\///; # there's no filter for the base "src/" dir, where SDL.c and friends live. | ||
440 | $filter =~ s/\//\\/g; | ||
441 | $filter = '' if $filter eq 'src'; | ||
442 | |||
443 | if ($filter ne '') { | ||
444 | # see if the filter already exists, otherwise add it. | ||
445 | my %existing_filters = (); | ||
446 | my $current_filter = ''; | ||
447 | my $found = 0; | ||
448 | foreach (@vcxfilters) { | ||
449 | # These lines happen to be unique, so we don't have to parse down to find this section. | ||
450 | if (/\A \<Filter Include\="(.*?)"\>\Z/) { | ||
451 | $current_filter = lc($1); | ||
452 | if ($current_filter eq $filter) { | ||
453 | $found = 1; | ||
454 | } | ||
455 | } elsif (/\A \<UniqueIdentifier\>\{(.*?)\}\<\/UniqueIdentifier\>\Z/) { | ||
456 | $visualc_references{$1} = $current_filter; # gather up existing GUIDs to avoid duplicates. | ||
457 | $existing_filters{$current_filter} = $1; | ||
458 | } | ||
459 | } | ||
460 | |||
461 | if (not $found) { # didn't find it? We need to build filters. | ||
462 | my $subpath = ''; | ||
463 | my @splitpath = split(/\\/, $filter); | ||
464 | while (my $elem = shift(@splitpath)) { | ||
465 | $subpath .= "\\" if ($subpath ne ''); | ||
466 | $subpath .= $elem; | ||
467 | if (not $existing_filters{$subpath}) { | ||
468 | my $newgroupref = generate_visualc_id(); | ||
469 | $newgrptext .= " <Filter Include=\"$subpath\">\n"; | ||
470 | $newgrptext .= " <UniqueIdentifier>{$newgroupref}</UniqueIdentifier>\n"; | ||
471 | $newgrptext .= " </Filter>\n" | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | } | ||
476 | } | ||
477 | |||
478 | $tmpfname = "$vcxfiltersfname.tmp"; | ||
479 | open $fh, '>', $tmpfname or die("Failed to open '$tmpfname': $!\n"); | ||
480 | |||
481 | $added = 0; | ||
482 | $vcxgroup_state = 0; | ||
483 | $prevname = undef; | ||
484 | $lineno = 0; | ||
485 | foreach (@vcxfilters) { | ||
486 | $lineno++; | ||
487 | |||
488 | # We cheat here, because these lines are unique, we don't have to fully parse this file. | ||
489 | if ($vcxgroup_state == 0) { | ||
490 | if (/\A \<Filter Include\="(.*?)"\>\Z/) { | ||
491 | if ($newgrptext ne '') { | ||
492 | $vcxgroup_state = 1; | ||
493 | $prevname = undef; | ||
494 | } | ||
495 | } elsif (/\A \<ClInclude .*\Z/) { | ||
496 | if ($isheader) { | ||
497 | $vcxgroup_state = 2; | ||
498 | $prevname = undef; | ||
499 | } | ||
500 | } elsif (/\A \<ClCompile .*\Z/) { | ||
501 | if (not $isheader) { | ||
502 | $vcxgroup_state = 3; | ||
503 | $prevname = undef; | ||
504 | } | ||
505 | } | ||
506 | } | ||
507 | |||
508 | # Don't do elsif, we need to check this line again. | ||
509 | if ($vcxgroup_state == 1) { | ||
510 | if (/\A \<\/ItemGroup\>\Z/) { | ||
511 | print $fh $newgrptext; | ||
512 | $newgrptext = ''; | ||
513 | $vcxgroup_state = 0; | ||
514 | } | ||
515 | } elsif ($vcxgroup_state == 2) { | ||
516 | if (/\A <ClInclude Include="(.*?)"/) { | ||
517 | my $nextname = $1; | ||
518 | if ((not $added) && (((not defined $prevname) || (uc($prevname) lt uc($addvcxpath))) && (uc($nextname) gt uc($addvcxpath)))) { | ||
519 | print $fh " <ClInclude Include=\"$addvcxpath\""; | ||
520 | if ($filter ne '') { | ||
521 | print $fh ">\n"; | ||
522 | print $fh " <Filter>$filter</Filter>\n"; | ||
523 | print $fh " </ClInclude>\n"; | ||
524 | } else { | ||
525 | print $fh " />\n"; | ||
526 | } | ||
527 | $added = 1; | ||
528 | } | ||
529 | $prevname = $nextname; | ||
530 | } elsif (/\A \<\/ItemGroup\>\Z/) { | ||
531 | if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { | ||
532 | print $fh " <ClInclude Include=\"$addvcxpath\""; | ||
533 | if ($filter ne '') { | ||
534 | print $fh ">\n"; | ||
535 | print $fh " <Filter>$filter</Filter>\n"; | ||
536 | print $fh " </ClInclude>\n"; | ||
537 | } else { | ||
538 | print $fh " />\n"; | ||
539 | } | ||
540 | $added = 1; | ||
541 | } | ||
542 | $vcxgroup_state = 0; | ||
543 | } | ||
544 | } elsif ($vcxgroup_state == 3) { | ||
545 | if (/\A <ClCompile Include="(.*?)"/) { | ||
546 | my $nextname = $1; | ||
547 | if ((not $added) && (((not defined $prevname) || (uc($prevname) lt uc($addvcxpath))) && (uc($nextname) gt uc($addvcxpath)))) { | ||
548 | print $fh " <ClCompile Include=\"$addvcxpath\""; | ||
549 | if ($filter ne '') { | ||
550 | print $fh ">\n"; | ||
551 | print $fh " <Filter>$filter</Filter>\n"; | ||
552 | print $fh " </ClCompile>\n"; | ||
553 | } else { | ||
554 | print $fh " />\n"; | ||
555 | } | ||
556 | $added = 1; | ||
557 | } | ||
558 | $prevname = $nextname; | ||
559 | } elsif (/\A \<\/ItemGroup\>\Z/) { | ||
560 | if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { | ||
561 | print $fh " <ClCompile Include=\"$addvcxpath\""; | ||
562 | if ($filter ne '') { | ||
563 | print $fh ">\n"; | ||
564 | print $fh " <Filter>$filter</Filter>\n"; | ||
565 | print $fh " </ClCompile>\n"; | ||
566 | } else { | ||
567 | print $fh " />\n"; | ||
568 | } | ||
569 | $added = 1; | ||
570 | } | ||
571 | $vcxgroup_state = 0; | ||
572 | } | ||
573 | } | ||
574 | |||
575 | print $fh "$_\n"; | ||
576 | } | ||
577 | |||
578 | close($fh); | ||
579 | rename($tmpfname, $vcxfiltersfname); | ||
580 | } | ||
581 | |||
582 | |||
583 | # Mainline! | ||
584 | |||
585 | chdir(dirname($0)); # assumed to be in build-scripts | ||
586 | chdir('..'); # head to root of source tree. | ||
587 | |||
588 | foreach (@ARGV) { | ||
589 | s/\A\.\///; # Turn "./path/to/file.txt" into "path/to/file.txt" | ||
590 | my $arg = $_; | ||
591 | process_xcode($arg, 'Xcode/SDL/SDL.xcodeproj/project.pbxproj'); | ||
592 | process_visualstudio($arg, 'VisualC/SDL/SDL.vcxproj'); | ||
593 | process_visualstudio($arg, 'VisualC-GDK/SDL/SDL.vcxproj'); | ||
594 | } | ||
595 | |||
596 | print("Done. Please run `git diff` and make sure this looks okay!\n"); | ||
597 | |||
598 | exit(0); | ||
599 | |||