#!/usr/bin/perl

# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer. 
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution. 
# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
#     its contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission. 
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# "check-for-exit-time-destructors" script for WebKit Open Source Project

# Intended to be invoked from an Xcode build step to check if there are
# any exit-time destructors in a target.

use warnings;
use strict;

use File::Basename;

sub touch($);
sub printFunctions($$);

my $arch = $ENV{'CURRENT_ARCH'};
my $configuration = $ENV{'CONFIGURATION'};
my $target = $ENV{'TARGET_NAME'};
my $variant = $ENV{'CURRENT_VARIANT'};
my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'};
my $debugRoot = $ENV{'WEBKIT_DEBUG_ROOT'};

$arch = $ENV{'NATIVE_ARCH'} if !$arch; # for Xcode 2.1, which does not have CURRENT_ARCH
$variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT

my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";

my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . ".timestamp";
my $buildTimestampAge = -M $buildTimestampPath;
my $scriptAge = -M $0;

my $list = $ENV{"LINK_FILE_LIST_${variant}_${arch}"};

if (!open LIST, $list) {
    print "ERROR: Could not open $list\n";
    exit 1;
}

my @files = <LIST>;
chomp @files;
close LIST;

my $sawError = 0;

for my $file (sort @files) {
    if (defined $buildTimestampAge && $buildTimestampAge < $scriptAge) {
        my $fileAge = -M $file;
        next if defined $fileAge && $fileAge > $buildTimestampAge;
    }
    if (!open NM, "(nm '$file' | sed 's/^/STDOUT:/') 2>&1 |") {
        print "ERROR: Could not open $file\n";
        $sawError = 1;
        next;
    }
    my $sawAtExit = 0;
    while (<NM>) {
        if (/^STDOUT:/) {
            $sawAtExit = 1 if /___cxa_atexit/;
        } else {
            print STDERR if $_ ne "nm: no name list\n";
        }
    }
    close NM;
    next unless $sawAtExit;

    my $shortName = $file;
    $shortName =~ s/.*\///;

    $sawError = 1 if printFunctions($shortName, $file);
}

if ($sawError and !$coverageBuild) {
    print "ERROR: Use DEFINE_STATIC_LOCAL from <wtf/StdLibExtras.h>\n";
    unlink $executablePath;
    exit 1;
}

touch($buildTimestampPath);
exit 0;

sub touch($)
{
    my ($path) = @_;
    open(TOUCH, ">", $path) or die "$!";
    close(TOUCH);
}

sub demangle($)
{
    my ($symbol) = @_;
    if (!open FILT, "c++filt $symbol |") {
        print "ERROR: Could not open c++filt\n";
        return;
    }
    my $result = <FILT>;
    close FILT;
    chomp $result;
    return $result;
}

sub printFunctions($$)
{
    my ($shortName, $path) = @_;
    if (!open OTOOL, "otool -tV '$path' |") {
        print "WARNING: Could not open $path\n";
        return 0;
    }
    my %functions;
    my $currentSymbol = "";
    while (<OTOOL>) {
        $currentSymbol = $1 if /^(\w+):$/;
        next unless $currentSymbol;
        $functions{demangle($currentSymbol)} = 1 if /___cxa_atexit/;
    }
    close OTOOL;
    my $result = 0;
    for my $function (sort keys %functions) {
        if (!$result) {
            print "ERROR: $shortName has exit time destructors in it! ($path)\n";
            $result = 1;
        }
        print "ERROR: In function $function\n";
    }
    return $result;
}
