1 #!/usr/bin/perl 2 3 # Copyright (C) 2006, 2007, 2008, 2010, 2011 Apple Inc. All rights reserved. 4 # 5 # Redistribution and use in source and binary forms, with or without 6 # modification, are permitted provided that the following conditions 7 # are met: 8 # 1. Redistributions of source code must retain the above copyright 9 # notice, this list of conditions and the following disclaimer. 10 # 2. Redistributions in binary form must reproduce the above copyright 11 # notice, this list of conditions and the following disclaimer in the 12 # documentation and/or other materials provided with the distribution. 13 # 14 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 18 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 # THE POSSIBILITY OF SUCH DAMAGE. 25 26 # "check-for-inappropriate-objc-class-names" script for WebKit Open Source Project 27 28 # Intended to be invoked from an Xcode build step to check if a framework 29 # defines any Objective-C class whose name does not have one of the prefixes 30 # the framework is allowed to use. 31 32 use warnings; 33 use strict; 34 35 use File::Basename; 36 37 sub touch($); 38 39 my @allowedPrefixes = @ARGV; 40 41 # Xcode will automatically link ObjC binaries against libarclite in some cases, which defines a class called __ARCLite__. 42 push(@allowedPrefixes, "__ARCLite"); 43 44 die "No allowed prefixes passed on the command line" if !@allowedPrefixes; 45 46 my $arch = $ENV{'CURRENT_ARCH'}; 47 my $target = $ENV{'TARGET_NAME'}; 48 my $variant = $ENV{'CURRENT_VARIANT'}; 49 my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'}; 50 51 my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}"; 52 53 my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . join('-', @allowedPrefixes) . ".timestamp"; 54 my $buildTimestampAge = -M $buildTimestampPath; 55 my $executablePathAge = -M $executablePath; 56 my $scriptAge = -M $0; 57 58 my $pattern = "^(" . join('|', @allowedPrefixes) . ")"; 59 60 my $sawError = 0; 61 62 if (!defined $executablePathAge || !defined $buildTimestampAge || $executablePathAge < $buildTimestampAge || $scriptAge < $buildTimestampAge) { 63 if (!open NM, "(nm -Ugjp '$executablePath' | sed 's/^/STDOUT:/') 2>&1 |") { 64 print "ERROR: Could not open $executablePath\n"; 65 $sawError = 1; 66 next; 67 } 68 my @badNames; 69 while (<NM>) { 70 if (/^STDOUT:/) { 71 next unless /^STDOUT:_OBJC_CLASS_\$_/; 72 chomp; 73 my $className = substr($_, 21); 74 push(@badNames, $className) unless $className =~ /$pattern/; 75 } else { 76 print STDERR if $_ ne "nm: no name list\n"; 77 } 78 } 79 close NM; 80 81 if (@badNames) { 82 83 my $shortName = $executablePath; 84 $shortName =~ s/.*\///; 85 86 print "ERROR: $shortName defines one or more Objective-C classes with inappropriate names. ($executablePath)\n"; 87 for my $className (@badNames) { 88 print "ERROR: Inappropriate Objective-C class name: $className.\n"; 89 } 90 91 if (@allowedPrefixes > 1) { 92 print "ERROR: Objective-C class names in $target must have one of these prefixes: " . join(", ", map('"' . $_ . '"', @allowedPrefixes)) . ".\n"; 93 } else { 94 print "ERROR: Objective-C class names in $target must have the prefix \"" . $allowedPrefixes[0] . "\".\n"; 95 } 96 97 $sawError = 1; 98 } 99 } 100 101 if ($sawError and !$coverageBuild) { 102 unlink $executablePath; 103 exit 1; 104 } 105 106 touch($buildTimestampPath); 107 exit 0; 108 109 sub touch($) 110 { 111 my ($path) = @_; 112 open(TOUCH, ">", $path) or die "$!"; 113 close(TOUCH); 114 } 115