2 # Copyright © 2012-2015 Jamie Zawinski <jwz@jwz.org>
4 # Permission to use, copy, modify, distribute, and sell this software and its
5 # documentation for any purpose is hereby granted without fee, provided that
6 # the above copyright notice appear in all copies and that both that
7 # copyright notice and this permission notice appear in supporting
8 # documentation. No representations are made about the suitability of this
9 # software for any purpose. It is provided "as is" without express or
12 # Generates a .c file that lists all the function tables we use, because
13 # CFBundleGetDataPointerForName doesn't work in "Archive" builds.
14 # What a crock of shit.
16 # There's no real way to integrate this into the Xcode build system, so
17 # run this manually each time a new saver is added to the iOS app.
19 # Created: 14-Jul-2012.
22 #use diagnostics; # Fails on some MacOS 10.5 systems
25 my $progname = $0; $progname =~ s@.*/@@g;
26 my ($version) = ('$Revision: 1.5 $' =~ m/\s(\d[.\d]+)\s/s);
30 # List of savers not included in the iOS build.
40 # Parse the RETIRED_EXES variable from the Makefiles to populate %disable.
41 # Duplicated in ../hacks/munge-ad.pl.
43 sub parse_makefiles() {
44 foreach my $mf ( "../hacks/Makefile.in", "../hacks/glx/Makefile.in" ) {
45 open (my $in, '<', $mf) || error ("$mf: $!");
46 print STDERR "$progname: reading $mf\n" if ($verbose > 1);
47 local $/ = undef; # read entire file
52 my ($var) = ($body =~ m/^RETIRED_EXES\s*=\s*(.*)$/mi);
53 my ($var2) = ($body =~ m/^RETIRED_GL_EXES\s*=\s*(.*)$/mi);
54 error ("no RETIRED_EXES in $mf") unless $var;
55 $var .= " $var2" if $var2;
56 foreach my $hack (split (/\s+/, $var)) {
68 my @schemes = glob('xscreensaver.xcodeproj/xcuserdata/' .
69 '*.xcuserdatad/xcschemes/*.xcscheme');
70 error ("no scheme files") unless (@schemes);
74 foreach my $s (@schemes) {
75 open (my $in, '<', $s) || error ("$s: $!");
76 local $/ = undef; # read entire file
79 my ($name) = ($body =~ m@BuildableName *= *"([^\"<>]+?)\.saver"@s);
82 if ($disable{$name}) {
83 print STDERR "$progname: skipping $name\n" if ($verbose > 1);
86 print STDERR "$progname: found $name\n" if ($verbose > 1);
90 my @names = sort (keys %names);
91 error ("too few names") if (@names < 100);
93 my $suf = 'xscreensaver_function_table';
95 my $body = ("/* Generated file, do not edit.\n" .
96 " Created: " . localtime() . " by $progname $version.\n" .
99 "#import <Foundation/Foundation.h>\n" .
100 "#import <UIKit/UIKit.h>\n" .
102 "extern NSDictionary *make_function_table_dict(void);\n" .
105 $body .= "extern struct $suf";
106 foreach my $s (@names, 'testx11') {
107 $body .= "\n ${s}_${suf},";
109 $body =~ s/,\s*$/;/s;
113 return "\t[NSValue valueWithPointer:&${s}_${suf}], @\"${s}\",\n";
117 "NSDictionary *make_function_table_dict(void)\n{\n" .
118 " return\n [NSDictionary dictionaryWithObjectsAndKeys:\n" .
120 "#if defined(APPLE2_ONLY)\n" .
121 " " . line('apple2', $suf) .
122 "#elif defined(PHOSPHOR_ONLY)\n" .
123 " " . line('phosphor', $suf) .
124 "#elif defined(TESTX11_ONLY)\n" .
125 " " . line('testx11', $suf) .
127 foreach my $s (@names) { $body .= line($s, $suf); }
128 $body .= ("#endif\n" .
133 if (open (my $in, '<', $outfile)) {
134 local $/ = undef; # read entire file
139 # strip comments/date for diff.
140 my ($body2, $obody2) = ($body, $obody);
141 foreach ($body2, $obody2) { s@/\*.*?\*/@@gs; }
143 if ($body2 eq $obody2) {
144 print STDERR "$progname: $outfile: unchanged\n" if ($verbose > 1);
146 my $file_tmp = "$outfile.tmp";
147 open (my $out, '>', $file_tmp) || error ("$file_tmp: $!");
148 print $out $body || error ("$file_tmp: $!");
149 close $out || error ("$file_tmp: $!");
151 if (!rename ("$file_tmp", "$outfile")) {
153 error ("mv \"$file_tmp\" \"$outfile\": $!");
155 print STDERR "$progname: wrote $outfile\n" if ($verbose);
162 print STDERR "$progname: $err\n";
167 print STDERR "usage: $progname [--verbose] output.c\n";
174 while ($_ = $ARGV[0]) {
176 if (m/^--?verbose$/s) { $verbose++; }
177 elsif (m/^-v+$/) { $verbose += length($_)-1; }
178 elsif (m/^--?q(uiet)?$/s) { $verbose = 0; }
179 elsif (m/^-/s) { usage(); }
180 elsif (! $out) { $out = $_; }
183 usage() unless ($out);