mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
merge fx-team to m-c
This commit is contained in:
commit
86ea298eb5
@ -592,8 +592,8 @@ NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
|
||||
if (aThisEvent->mPackedEvent) {
|
||||
aThisEvent->mPackedEvent->mEventType =
|
||||
aThisEvent->mPackedEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
|
||||
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_ADD) :
|
||||
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_REMOVE);
|
||||
nsIAccessibleEvent::EVENT_SELECTION_ADD :
|
||||
nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
|
||||
|
||||
aThisEvent->mPackedEvent->mEventRule =
|
||||
AccEvent::eCoalesceSelectionChange;
|
||||
@ -603,8 +603,8 @@ NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
|
||||
|
||||
aThisEvent->mEventType =
|
||||
aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
|
||||
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_ADD) :
|
||||
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_REMOVE);
|
||||
nsIAccessibleEvent::EVENT_SELECTION_ADD :
|
||||
nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -440,7 +440,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates
|
||||
kNoReqStates,
|
||||
eARIAOrientation
|
||||
},
|
||||
{
|
||||
"slider",
|
||||
@ -450,6 +451,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
eARIAOrientation,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
@ -649,8 +651,8 @@ nsStateMapEntry nsARIAMap::gWAIStateMap[] = {
|
||||
|
||||
// eARIAOrientation
|
||||
nsStateMapEntry(&nsGkAtoms::aria_orientation, eUseFirstState,
|
||||
"vertical", states::VERTICAL,
|
||||
"horizontal", states::HORIZONTAL),
|
||||
"horizontal", states::HORIZONTAL,
|
||||
"vertical", states::VERTICAL),
|
||||
|
||||
// eARIAPressed
|
||||
nsStateMapEntry(&nsGkAtoms::aria_pressed, kMixedType,
|
||||
|
@ -191,7 +191,7 @@ __try {
|
||||
if (aTargetIndex < 0 || aTargetIndex >= mTargets.Length() || !aTarget)
|
||||
return E_INVALIDARG;
|
||||
|
||||
mTargets[aTargetIndex]->QueryInterface((const nsID&) IID_IUnknown, (void**) aTarget);
|
||||
mTargets[aTargetIndex]->QueryNativeInterface(IID_IUnknown, (void**) aTarget);
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
|
@ -124,10 +124,16 @@
|
||||
testStates("aria_main_anchor", STATE_SELECTABLE);
|
||||
testStates("aria_navigation_anchor", STATE_SELECTABLE);
|
||||
|
||||
// scrollbar
|
||||
testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL);
|
||||
// aria-orientation (applied to scrollbar, separator, slider)
|
||||
testStates("aria_scrollbar", 0, EXT_STATE_HORIZONTAL);
|
||||
testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL);
|
||||
testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL);
|
||||
testStates("aria_separator", 0, EXT_STATE_HORIZONTAL);
|
||||
testStates("aria_hseparator", 0, EXT_STATE_HORIZONTAL);
|
||||
testStates("aria_vseparator", 0, EXT_STATE_VERTICAL);
|
||||
testStates("aria_slider", 0, EXT_STATE_HORIZONTAL);
|
||||
testStates("aria_hslider", 0, EXT_STATE_HORIZONTAL);
|
||||
testStates("aria_vslider", 0, EXT_STATE_VERTICAL);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
@ -160,6 +166,11 @@
|
||||
title="aria-autocomplete not supported on standard form text input controls">
|
||||
Mozilla Bug 681674
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674"
|
||||
title="aria-orientation should be applied to separator and slider roles">
|
||||
Mozilla Bug 681674
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -227,9 +238,15 @@
|
||||
<a id="aria_main_anchor" role="main" name="main_anchor">main</a>
|
||||
<a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
|
||||
|
||||
<!-- scrollbar -->
|
||||
<div id="aria_scrollbar" role="scrollbar">scrollbar</a>
|
||||
<div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</a>
|
||||
<div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</a>
|
||||
<!-- aria-orientation -->
|
||||
<div id="aria_scrollbar" role="scrollbar">scrollbar</div>
|
||||
<div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div>
|
||||
<div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</div>
|
||||
<div id="aria_separator" role="separator">separator</div>
|
||||
<div id="aria_hseparator" role="separator" aria-orientation="horizontal">horizontal separator</div>
|
||||
<div id="aria_vseparator" role="separator" aria-orientation="vertical">vertical separator</div>
|
||||
<div id="aria_slider" role="slider">slider</div>
|
||||
<div id="aria_hslider" role="slider" aria-orientation="horizontal">horizontal slider</div>
|
||||
<div id="aria_vslider" role="slider" aria-orientation="vertical">vertical slider</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -36,9 +36,9 @@
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
|
||||
// Bug 671101 - directly using webNavigation in this context
|
||||
// causes docshells to leak
|
||||
|
@ -260,10 +260,10 @@ var gTests = [
|
||||
function nextTest() {
|
||||
if (gTests.length) {
|
||||
var test = gTests.shift();
|
||||
info("Start of test: " + test.desc);
|
||||
test.run();
|
||||
|
||||
waitForFocus(nextTest);
|
||||
waitForFocus(function() {
|
||||
info("Start of test: " + test.desc);
|
||||
test.run();
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Collapse the personal toolbar if needed.
|
||||
@ -283,6 +283,6 @@ function test() {
|
||||
if (wasCollapsed)
|
||||
setToolbarVisibility(toolbar, true);
|
||||
|
||||
waitForFocus(nextTest);
|
||||
nextTest();
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const Cu = Components.utils;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import("resource:///modules/tabview/utils.jsm");
|
||||
|
||||
|
@ -56,6 +56,7 @@ endif
|
||||
DIRS += pgo
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += autoconf/test
|
||||
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
||||
DIRS += mobile/sutagent/android \
|
||||
mobile/sutagent/android/watcher \
|
||||
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env perl
|
||||
#!/usr/bin/env perl
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
@ -16,10 +16,12 @@
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1999
|
||||
# Portions created by the Initial Developer are Copyright (C) 1999-2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Steve Lamm <slamm@netscape.com>
|
||||
# Joey Armstrong <joey@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -35,29 +37,81 @@
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# make-makefiles - Quickly create Makefiles for subdirectories.
|
||||
# Also, creates any needed subdirectories.
|
||||
#
|
||||
# usage: make-makefiles [ -t <topsrcdir> -p <print_topsrcdir> -d <depth> ] [ <subdir> | <subdir>/Makefile ] ...
|
||||
##----------------------------##
|
||||
##---] CORE/CPAN INCLUDES [---##
|
||||
##----------------------------##
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
# Send comments, improvements, bugs to Steve Lamm (slamm@netscape.com).
|
||||
use Benchmark;
|
||||
use Cwd;
|
||||
use File::Basename;
|
||||
use File::Copy;
|
||||
use File::Path qw{mkpath};
|
||||
|
||||
#$debug = 1;
|
||||
##-------------------##
|
||||
##---] EXPORTS [---##
|
||||
##-------------------##
|
||||
our $VERSION = qw(2.0);
|
||||
|
||||
if ($^O eq 'msys') {
|
||||
$pwdcmd = 'pwd -W';
|
||||
##--------------------##
|
||||
##---] INCLUDES [---##
|
||||
##--------------------##
|
||||
|
||||
##############################################################
|
||||
# pymake: special case path handling for windows cmd shell.
|
||||
# if invoked by cmd.exe and msys-perl is in play
|
||||
# $0 may contain a drive letter
|
||||
# modules use-or-expect msys/unix paths
|
||||
# adjust $0 => C:/foo => /c/foo so string tests and
|
||||
# manipulation can by applied properly.
|
||||
##############################################################
|
||||
sub BEGIN
|
||||
{
|
||||
if ($^O eq 'msys' && $ENV{PATH} =~ m!\w:/!)
|
||||
{
|
||||
$0 =~ s!^(\w):!/$1!;
|
||||
}
|
||||
eval 'use FindBin';
|
||||
die $@ if ($@);
|
||||
}
|
||||
else {
|
||||
$pwdcmd = 'pwd';
|
||||
|
||||
use lib $FindBin::Bin;
|
||||
use makemakefile;
|
||||
|
||||
##-------------------##
|
||||
##---] GLOBALS [---##
|
||||
##-------------------##
|
||||
my %argv;
|
||||
|
||||
my $t0 = Benchmark->new();
|
||||
sub END
|
||||
{
|
||||
if ($argv{bench})
|
||||
{
|
||||
my $t1 = Benchmark->new();
|
||||
my $delta = timediff($t1, $t0);
|
||||
print STDERR timestr($delta), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
##----------------##
|
||||
##---] MAIN [---##
|
||||
##----------------##
|
||||
umask 0;
|
||||
|
||||
my $debug = $argv{debug} || 0;
|
||||
|
||||
my $pwdcmd = ($^O eq 'msys') ? 'pwd -W' : 'pwd';
|
||||
|
||||
# Determine various tree path variables
|
||||
#
|
||||
($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments(@ARGV);
|
||||
my ($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments(@ARGV);
|
||||
|
||||
$object_fullpath = `$pwdcmd`;
|
||||
my $object_fullpath = `$pwdcmd`; # Cwd::getcwd()
|
||||
chdir $depth;
|
||||
$object_root = `$pwdcmd`;
|
||||
my $object_root = `$pwdcmd`; # Cwd::getcwd()
|
||||
chomp $object_fullpath;
|
||||
chomp $object_root;
|
||||
|
||||
@ -65,24 +119,23 @@ chomp $object_root;
|
||||
# 'make-makefile' was called. For example, if make-makefile was
|
||||
# called from "mozilla/gfx/src", then $source_subdir would be
|
||||
# "gfx/src/".
|
||||
$source_subdir = "$object_fullpath/";
|
||||
my $source_subdir = "$object_fullpath/";
|
||||
my $quoted_object_root = quotemeta($object_root);
|
||||
$source_subdir =~ s|^$quoted_object_root/||;
|
||||
|
||||
# Prefix makefiles with $source_subdir so that paths
|
||||
# will be relative to the top of the object tree.
|
||||
#
|
||||
for $makefile (@makefiles) {
|
||||
my $makefile;
|
||||
for $makefile (@makefiles) { # dead code ?
|
||||
$makefile = "$source_subdir$makefile";
|
||||
}
|
||||
|
||||
create_directories(@makefiles);
|
||||
|
||||
# Find the path to the source directory based on how 'make-makefile'
|
||||
# was invoked. The path is either relative to the object directory
|
||||
# or an absolute path.
|
||||
$given_srcdir = find_srcdir($topsrcdir, $depth);
|
||||
$pgiven_srcdir = find_srcdir($ptopsrcdir, $depth);
|
||||
my $given_srcdir = find_srcdir($topsrcdir, $depth);
|
||||
my $pgiven_srcdir = find_srcdir($ptopsrcdir, $depth);
|
||||
|
||||
if ($debug) {
|
||||
warn "object_fullpath = $object_fullpath\n";
|
||||
@ -92,18 +145,21 @@ if ($debug) {
|
||||
warn "given_srcdir = $given_srcdir\n";
|
||||
}
|
||||
|
||||
@unhandled = update_makefiles($given_srcdir, $pgiven_srcdir, @makefiles);
|
||||
my @errors;
|
||||
my @unhandled = update_makefiles_legacy($given_srcdir, $pgiven_srcdir, @makefiles);
|
||||
push(@errors, $@) if ($@);
|
||||
|
||||
run_config_status(@unhandled);
|
||||
push(@errors, $@) if ($@ && $argv{'no-warnings'});
|
||||
|
||||
exit scalar(@errors);
|
||||
|
||||
# end of Main
|
||||
############################################################
|
||||
|
||||
sub dirname {
|
||||
return $_[0] =~ /(.*)\/.*/ ? "$1" : '.';
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# find_depth: Pull the value of DEPTH out of a Makefile (or Makefile.in)
|
||||
###########################################################################
|
||||
sub find_depth {
|
||||
my $depth = '';
|
||||
open(MAKEFILE, "<$_[0]") || die "Unable to open $_[0]: $!\n";
|
||||
@ -116,39 +172,115 @@ sub find_depth {
|
||||
return $depth;
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
## Intent: Parse command line arguments and assign values
|
||||
###########################################################################
|
||||
sub parse_arguments {
|
||||
my @args = @_;
|
||||
my $depth = '';
|
||||
my $topsrcdir = '';
|
||||
my $ptopsrcdir;
|
||||
my @makefiles = ();
|
||||
|
||||
while (1) {
|
||||
if ($args[0] eq '-d') {
|
||||
$depth = $args[1];
|
||||
shift @args;
|
||||
shift @args;
|
||||
} elsif ($args[0] eq '-t') {
|
||||
$topsrcdir = $args[1];
|
||||
shift @args;
|
||||
shift @args;
|
||||
} elsif ($args[0] eq '-p') {
|
||||
$ptopsrcdir = $args[1];
|
||||
shift @args;
|
||||
shift @args;
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
my @arglist = qw(badtokens! bench
|
||||
chdir=s
|
||||
debug
|
||||
depth|d=s
|
||||
enhanced
|
||||
obj=s top|t=s ptop|p=s
|
||||
src=s dst=s
|
||||
);
|
||||
unless(GetOptions(\%argv, @arglist))
|
||||
{
|
||||
my $script = join('/', $FindBin::RealBin, $FindBin::Script);
|
||||
system("perldoc $script </dev/null");
|
||||
exit
|
||||
}
|
||||
@args = @ARGV;
|
||||
|
||||
my $topsrcdir = $argv{top} || '';
|
||||
if (! $topsrcdir)
|
||||
{
|
||||
$topsrcdir = $argv{top} = getTopDir();
|
||||
}
|
||||
|
||||
if ($topsrcdir eq '') {
|
||||
$topsrcdir = $0; # Figure out topsrcdir based on program name.
|
||||
$topsrcdir =~ s|/?build/autoconf/.*$||;
|
||||
my $ptopsrcdir ||= $argv{ptop} || $topsrcdir || '';
|
||||
|
||||
## Init --no- switch values
|
||||
foreach my $var (qw(badtokens exclusions warnings))
|
||||
{
|
||||
$argv{"no-${var}"} = $argv{$var} || 0;
|
||||
}
|
||||
if ($ptopsrcdir eq '') {
|
||||
$ptopsrcdir = $topsrcdir;
|
||||
# Propogate parsed arguments for module use [--debug, --verbose]
|
||||
while (my($k, $v) = each %argv)
|
||||
{
|
||||
$main::argv{$k} = $v;
|
||||
}
|
||||
if ($depth eq '') {
|
||||
|
||||
if ($argv{chdir})
|
||||
{
|
||||
chdir $argv{chdir} || die "chdir $argv{chdir} failed: $!";
|
||||
}
|
||||
|
||||
##############################################################
|
||||
## Arguments allowing make-makefile to be invoked from $topsrc
|
||||
##############################################################
|
||||
if (!$argv{top} || !$argv{obj})
|
||||
{
|
||||
}
|
||||
## Limit access to container makefiles for now
|
||||
elsif ($argv{enhanced})
|
||||
{
|
||||
my @errors;
|
||||
|
||||
## iterate over @ARGV to preserve original filename for 'unhandled'
|
||||
my @files = map{ getRelPath($_) } @ARGV;
|
||||
|
||||
my $top = getTopDir();
|
||||
my $obj = getObjDir();
|
||||
|
||||
mkdirr(map{ "$obj/$_" } @files);
|
||||
push(@errors, $@) if ($@); # legacy behavior: do not exit with status
|
||||
|
||||
my $exclude = join('/', $FindBin::RealBin, $FindBin::Script);
|
||||
$exclude .= '.excl'; # $argv{exclude}
|
||||
my %exclude = getExclusions($exclude);
|
||||
my @unhandled;
|
||||
foreach my $relpath (@files)
|
||||
{
|
||||
my $rel = join('/', $relpath, 'Makefile.in');
|
||||
my $mf = join('/', $top, $rel);
|
||||
next if ($exclude{$rel});
|
||||
print STDERR " ** relpath=[$relpath], mf=[$mf]\n" if ($main::argv{debug});
|
||||
|
||||
my $rc = updateMakefiles($relpath, {depth=>$depth, obj=>$obj, top=>$top});
|
||||
if ($@)
|
||||
{
|
||||
push(@errors, $@);
|
||||
}
|
||||
elsif ($rc eq 'badtokens')
|
||||
{
|
||||
push(@unhandled, $mf);
|
||||
}
|
||||
}
|
||||
|
||||
run_config_status(@unhandled);
|
||||
push(@errors, $@) if ($@ && $argv{'no-warnings'});
|
||||
exit scalar(@errors);
|
||||
}
|
||||
|
||||
|
||||
my $depth = $argv{depth} || '';
|
||||
if (! $depth)
|
||||
{
|
||||
foreach my $fyl (@args)
|
||||
{
|
||||
if (my $tmp = find_depth($fyl))
|
||||
{
|
||||
$depth = $tmp;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! $depth) {
|
||||
# Use $(DEPTH) in the Makefile or Makefile.in to determine the depth
|
||||
if (-e "Makefile.in") {
|
||||
$depth = find_depth("Makefile.in");
|
||||
@ -166,34 +298,21 @@ sub parse_arguments {
|
||||
# Build the list of makefiles to generate
|
||||
#
|
||||
@makefiles = ();
|
||||
my $makefile;
|
||||
foreach $makefile (@args) {
|
||||
$makefile =~ s/\.in$//;
|
||||
$makefile =~ s/\/$//;
|
||||
$makefile =~ /Makefile$/
|
||||
or $makefile =~ /^\.\//
|
||||
or $makefile .= "/Makefile";
|
||||
while (@args)
|
||||
{
|
||||
next unless my $makefile = shift @args;
|
||||
$makefile =~ s/\.in$//;
|
||||
$makefile =~ s/\/$//;
|
||||
$makefile =~ /Makefile$/
|
||||
or $makefile =~ /^\.\//
|
||||
or $makefile .= "/Makefile";
|
||||
push @makefiles, "$makefile";
|
||||
}
|
||||
@makefiles = "Makefile" unless @args;
|
||||
@makefiles = "Makefile" unless @makefiles;
|
||||
|
||||
return ($topsrcdir, $ptopsrcdir, $depth, @makefiles);
|
||||
}
|
||||
|
||||
|
||||
# Create all the directories at once.
|
||||
# This can be much faster than calling mkdir() for each one.
|
||||
sub create_directories {
|
||||
my @makefiles = @_;
|
||||
my @dirs = ();
|
||||
my $ac_file;
|
||||
foreach $ac_file (@makefiles) {
|
||||
push @dirs, dirname($ac_file);
|
||||
}
|
||||
# Call mkdir with the directories sorted by subdir count (how many /'s)
|
||||
system "mkdir -p ". join(' ', map("\"$_\"", @dirs)) if @dirs;
|
||||
}
|
||||
|
||||
# Find the top of the source directory
|
||||
# (Assuming that the executable is in $top_srcdir/build/autoconf)
|
||||
sub find_srcdir {
|
||||
@ -214,111 +333,146 @@ sub find_srcdir {
|
||||
return $ac_given_srcdir;
|
||||
}
|
||||
|
||||
# Output the makefiles.
|
||||
#
|
||||
sub update_makefiles {
|
||||
my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
|
||||
my @unhandled=();
|
||||
1;
|
||||
###########################################################################
|
||||
## perldoc
|
||||
###########################################################################
|
||||
__END__
|
||||
|
||||
my $ac_file;
|
||||
foreach $ac_file (@makefiles) {
|
||||
my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
|
||||
my $ac_dir = dirname($ac_file);
|
||||
my $ac_dots = '';
|
||||
my $ac_dir_suffix = '';
|
||||
my $srcdir = '.';
|
||||
my $top_srcdir = '.';
|
||||
=head1 NAME
|
||||
|
||||
# Determine $srcdir and $top_srcdir
|
||||
#
|
||||
if ($ac_dir ne '.') {
|
||||
$ac_dir_suffix = "/$ac_dir";
|
||||
$ac_dir_suffix =~ s%^/\./%/%;
|
||||
$ac_dots = $ac_dir_suffix;
|
||||
# Remove .. components from the provided dir suffix, and
|
||||
# also the forward path components they were reversing.
|
||||
my $backtracks = $ac_dots =~ s%\.\.(/|$)%%g;
|
||||
while ($backtracks--) {
|
||||
$ac_dots =~ s%/[^/]*%%;
|
||||
}
|
||||
$ac_dots =~ s%/[^/]*%../%g;
|
||||
}
|
||||
if ($ac_given_srcdir eq '.') {
|
||||
if ($ac_dots ne '') {
|
||||
$top_srcdir = $ac_dots;
|
||||
$top_srcdir =~ s%/$%%;
|
||||
}
|
||||
} elsif ($pac_given_srcdir =~ m%^/% or $pac_given_srcdir =~ m%^.:/%) {
|
||||
$srcdir = "$pac_given_srcdir$ac_dir_suffix";
|
||||
$top_srcdir = "$pac_given_srcdir";
|
||||
} else {
|
||||
if ($debug) {
|
||||
print "ac_dots = $ac_dots\n";
|
||||
print "ac_dir_suffix = $ac_dir_suffix\n";
|
||||
}
|
||||
$srcdir = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
|
||||
$top_srcdir = "$ac_dots$ac_given_srcdir";
|
||||
}
|
||||
make-makefile - Generate a Makefile from a F<Makefile.in> template
|
||||
|
||||
if ($debug) {
|
||||
print "ac_dir = $ac_dir\n";
|
||||
print "ac_file = $ac_file\n";
|
||||
print "ac_file_in = $ac_file_in\n";
|
||||
print "srcdir = $srcdir\n";
|
||||
print "top_srcdir = $top_srcdir\n";
|
||||
print "cwd = " . `$pwdcmd` . "\n";
|
||||
}
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# Copy the file and make substitutions.
|
||||
# @srcdir@ -> value of $srcdir
|
||||
# @top_srcdir@ -> value of $top_srcdir
|
||||
#
|
||||
if (-e $ac_file) {
|
||||
next if -M _ < -M $ac_file_in; # Next if Makefile is up-to-date.
|
||||
warn "updating $ac_file\n";
|
||||
} else {
|
||||
warn "creating $ac_file\n";
|
||||
}
|
||||
make-makefile [--top t] [--obj o] [--depth d] foo/bar/Makefile.in tans/fans/Makefile foo/bar
|
||||
|
||||
open INFILE, "<$ac_file_in" or do {
|
||||
warn "$0: Cannot read $ac_file_in: No such file or directory\n";
|
||||
next;
|
||||
};
|
||||
open OUTFILE, ">$ac_file" or do {
|
||||
warn "$0: Unable to create $ac_file\n";
|
||||
next;
|
||||
};
|
||||
=head1 DESCRIPTION
|
||||
|
||||
while (<INFILE>) {
|
||||
#if (/\@[_a-zA-Z]*\@.*\@[_a-zA-Z]*\@/) {
|
||||
# #warn "Two defines on a line:$ac_file:$.:$_";
|
||||
# push @unhandled, $ac_file;
|
||||
# last;
|
||||
#}
|
||||
Given options and makefile path arguments determine path to the template
|
||||
F<Makefile.in> beneath a source directory and path to generated F<Makefile>
|
||||
beneath $MOZ_OBJDIR. DEPTH from destination directory to the 'root' will
|
||||
also be determined. F<Makefile.in> will be read in, template strings of the
|
||||
gorm @token@ will be replaced with derived values and a generated makefile
|
||||
will be written out as F<Makefile>.
|
||||
|
||||
s/\@srcdir\@/$srcdir/g;
|
||||
s/\@top_srcdir\@/$top_srcdir/g;
|
||||
Makefile DEPTH= can be determined in a few different ways:
|
||||
o The string C<DEPTH=../../..> may be embedded within F<Makefile.in>.
|
||||
o Search parent directories for F<Makefile.in> and use it to assign the child.
|
||||
|
||||
if (/\@[_a-zA-Z]*\@/) {
|
||||
#warn "Unknown variable:$ac_file:$.:$_";
|
||||
push @unhandled, $ac_file;
|
||||
last;
|
||||
}
|
||||
print OUTFILE;
|
||||
}
|
||||
close INFILE;
|
||||
close OUTFILE;
|
||||
}
|
||||
return @unhandled;
|
||||
}
|
||||
|
||||
sub run_config_status {
|
||||
my @unhandled = @_;
|
||||
=head2 Option List
|
||||
|
||||
# Run config.status with any unhandled files.
|
||||
#
|
||||
if (@unhandled) {
|
||||
$ENV{CONFIG_FILES}= join ' ', @unhandled;
|
||||
system "./config.status";
|
||||
}
|
||||
}
|
||||
=over 4
|
||||
|
||||
=item --chdir
|
||||
|
||||
Move to this directory before doing anything else
|
||||
|
||||
=item -d, --depth
|
||||
|
||||
Explicitly specify the relative path from directory containing Makefile.in
|
||||
to the top sandbox directory. memory/makefile, DEPTH=../.., js/src/config, DEPTH=..
|
||||
|
||||
=item --enhanced
|
||||
|
||||
Use alternate/simplified path construction when options --top and --obj are
|
||||
passed. This feature will be used by container makefiles to support makefile
|
||||
generation while cd'd into the sandbox top directory.
|
||||
|
||||
=item -t, --top
|
||||
|
||||
Path the root of a development sandbox.
|
||||
|
||||
=item --obj
|
||||
|
||||
Path to object directory where generated makefile will be written ($MOZ_OBJDIR).
|
||||
|
||||
=item --ptop
|
||||
|
||||
Print top source dir
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 Options List DEBUG
|
||||
|
||||
=over 4
|
||||
|
||||
=item --bench
|
||||
|
||||
Enable script benchmarking, report elapsed runtime.
|
||||
|
||||
=item --debug
|
||||
|
||||
Enable script debug mode.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 Options List --NO-
|
||||
|
||||
=over 4
|
||||
|
||||
=item --no-badtokens (wip)
|
||||
|
||||
Handle unexpanded @token@ makefile tokens as an error condition.
|
||||
Do not rely on system(config.status) to externally supply values.
|
||||
|
||||
=item --no-excludes
|
||||
|
||||
Ignore file entries on the exclusion list, generate everything.
|
||||
|
||||
=item --no-warnings
|
||||
|
||||
Warnings are handled as an error condition.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 Examples
|
||||
|
||||
=over 4
|
||||
|
||||
=item * make-makefile -t /mozilla/nightly -d . memory/mozalloc
|
||||
|
||||
cd $MOZ_OBJDIR;
|
||||
--top and --depth are explicitly set for generting memory/mozalloc/Makefile.
|
||||
|
||||
=item * make-makefile -t /mozilla/nightly -d ../../../.. html5lib_tree_construction/Makefile
|
||||
|
||||
cd $MOZ_OBJDIR/parser/htmlparser/tests/mochitest
|
||||
|
||||
--top and --depth are explicitly set for generting a makefile from within
|
||||
a subdirectory of $MOZ_OBJDIR
|
||||
|
||||
=item * make-makefile --top /mozilla/nightly --obj /mozilla/nightly/obj memory/mozalloc
|
||||
|
||||
With --top and --obj explicitly set generate $MOZ_OBJDIR/memory/mozalloc/Makefile
|
||||
while sitting in the sandbox root.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 Work In Progress
|
||||
|
||||
=over 4
|
||||
|
||||
=item --no-badtokens
|
||||
|
||||
Fail on unexpanded @foo@ makefile tokens. Any tokens that can be expanded
|
||||
directly by make-makefile will avoid config.status shell overhead.
|
||||
|
||||
=item Depth from delta(--obj, --top)
|
||||
|
||||
If DEPTH= has not been embedded within a makefile the value could
|
||||
be set directly if --top and --obj are specified and the paths overlap.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<config/rules.mk>
|
||||
|
||||
=cut
|
||||
|
5
build/autoconf/make-makefile.excl
Normal file
5
build/autoconf/make-makefile.excl
Normal file
@ -0,0 +1,5 @@
|
||||
###########################################################################
|
||||
## Intent: Exclusion list for container make builds
|
||||
###########################################################################
|
||||
|
||||
# EOF
|
745
build/autoconf/makemakefile.pm
Normal file
745
build/autoconf/makemakefile.pm
Normal file
@ -0,0 +1,745 @@
|
||||
package makemakefile;
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1999-2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Steve Lamm <slamm@netscape.com>
|
||||
# Joey Armstrong <joey@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
##----------------------------##
|
||||
##---] CORE/CPAN INCLUDES [---##
|
||||
##----------------------------##
|
||||
use strict;
|
||||
use warnings;
|
||||
# use feature 'state'; 5.10+ not available everywhere
|
||||
|
||||
##-------------------##
|
||||
##---] EXPORTS [---##
|
||||
##-------------------##
|
||||
our $VERSION = qw(2.0);
|
||||
use Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(dirname_legacy
|
||||
getConfig getDepth getRelPath getObjDir getTopDir mkdirr
|
||||
getExclusions
|
||||
run_config_status
|
||||
updateMakefiles
|
||||
update_makefiles_legacy
|
||||
);
|
||||
|
||||
##--------------------##
|
||||
##---] INCLUDES [---##
|
||||
##--------------------##
|
||||
use Cwd;
|
||||
use Cwd qw{abs_path};
|
||||
use FindBin;
|
||||
use File::Basename;
|
||||
use File::Copy;
|
||||
|
||||
##-------------------##
|
||||
##---] GLOBALS [---##
|
||||
##-------------------##
|
||||
umask 0;
|
||||
my $cwd = Cwd::abs_path('.');
|
||||
my %argv;
|
||||
|
||||
|
||||
###########################################################################
|
||||
## Intent: Helper function, retrieve contents of a file with error checking
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## scalar path to input file
|
||||
## Returns:
|
||||
## array contents of the given file
|
||||
## $@ set on error
|
||||
###########################################################################
|
||||
sub cat
|
||||
{
|
||||
my $fyl = shift || '';
|
||||
$@ = '';
|
||||
my @data;
|
||||
|
||||
local *FYL;
|
||||
if (!open(FYL, $fyl))
|
||||
{
|
||||
$@ = "open($fyl) failed: $!";
|
||||
}
|
||||
else
|
||||
{
|
||||
@data = <FYL>;
|
||||
close(FYL);
|
||||
}
|
||||
return @data;
|
||||
} # cat
|
||||
|
||||
###########################################################################
|
||||
## Intent: Return directory path for a given argument
|
||||
## -----------------------------------------------------------------------
|
||||
## -----------------------------------------------------------------------
|
||||
## Todo:
|
||||
## o Check if function can be replaced by File::Basename::dirname()
|
||||
###########################################################################
|
||||
sub dirname_legacy
|
||||
{
|
||||
my $str = (@_ && defined($_[0])) ? shift : '';
|
||||
return $str =~ /(.*)\/.*/ ? "$1" : '.';
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
## Intent: Given a list of makefile paths recursively create all
|
||||
## directories between file and the root
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## array A list of makefiles
|
||||
## fargs Function arguments
|
||||
## mode Filesystem mode used for directory creation
|
||||
## Returns:
|
||||
## $@ Set on error
|
||||
## 0 on success
|
||||
## -----------------------------------------------------------------------
|
||||
## Note:
|
||||
## Reporting directory creation can be enabled by the --verbose
|
||||
## command line argument.
|
||||
###########################################################################
|
||||
sub mkdirr
|
||||
{
|
||||
my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
|
||||
my $mode = $fargs{mode} || 0755;
|
||||
my $verbose = $main::argv{verbose} || 0;
|
||||
$@ = '' unless ($fargs{recursive});
|
||||
$fargs{recursive} = 1;
|
||||
|
||||
my @errors;
|
||||
push(@errors, $@) if ($@);
|
||||
foreach my $path (@_)
|
||||
{
|
||||
(my $dir = $path) =~ s%/?Makefile[^/]*$%%o;
|
||||
next unless (length($dir));
|
||||
next if (-e $dir);
|
||||
mkdirr( dirname($dir), \%fargs);
|
||||
eval{ File::Path::mkpath($dir, $verbose, 0755); };
|
||||
push(@errors, $@) if ($@);
|
||||
}
|
||||
$@ = join("\n", @errors);
|
||||
return $@ ? 0 : 1;
|
||||
} # mkdirr
|
||||
|
||||
###########################################################################
|
||||
## Intent: Read in configure values and return a hash of key/value pairs
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## fargs Function arguments
|
||||
## reset clear value storage and repopulate
|
||||
## Returns:
|
||||
## hash configure data to use for makefile substitutions
|
||||
## -----------------------------------------------------------------------
|
||||
## Todo: wrapper for reading config* and run_config_status
|
||||
###########################################################################
|
||||
my %_CONFIG_; # todo: state %config; w/5.10
|
||||
sub getConfig
|
||||
{
|
||||
my %fargs = (@_ && ref($_[$#_]) eq 'HASH') ? %{ (pop) } : ();
|
||||
if ($fargs{reset})
|
||||
{
|
||||
%_CONFIG_ = ();
|
||||
shift;
|
||||
}
|
||||
|
||||
#my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
|
||||
#my $ac_dir = dirname_legacy($ac_file);
|
||||
#my $ac_dots = '';
|
||||
#my $ac_dir_suffix = '';
|
||||
#my $srcdir = '.';
|
||||
#my $top_srcdir = '.';
|
||||
unless (%_CONFIG_)
|
||||
{
|
||||
while (@_)
|
||||
{
|
||||
my ($k, $v) = splice(@_, 0, 2);
|
||||
$_CONFIG_{$k} = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return %_CONFIG_;
|
||||
} # getConfig
|
||||
|
||||
###########################################################################
|
||||
## Intent: Determine path depth between leaf and root directory.
|
||||
## o DEPTH= may be set by makefile content
|
||||
## o DEPTH= may be set by Makefile in a parent
|
||||
## o Manually determine by relpath form leaf to sandbox top
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## scalar Path to makefile or directory to determine DEPTH for
|
||||
## Returns:
|
||||
## scalar Relative path from leaf to root directory
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
sub getDepth($)
|
||||
{
|
||||
my $fyl = shift || '';
|
||||
|
||||
my @path = split(m%/%o, $fyl);
|
||||
pop(@path) if ('Makefile' eq substr($path[$#path], 0, 8));
|
||||
my $depth;
|
||||
my @depth;
|
||||
|
||||
my $top = getTopDir();
|
||||
my @top = split(m%/%o, $top);
|
||||
my @pathNoTop = @path;
|
||||
splice(@pathNoTop, 0, scalar(@top));
|
||||
|
||||
SEARCH:
|
||||
while (@path)
|
||||
{
|
||||
## Search for a file containing DEPTH=../..
|
||||
foreach my $fyl ( qw{Makefile.in Makefile} )
|
||||
{
|
||||
my $path = join('/', @path, $fyl);
|
||||
local *FYL;
|
||||
if (!open(FYL, $path)) {} # NOP
|
||||
elsif (my @tmp = map{ /^\s*DEPTH\s*=\s*([\.\/]+)/o ? $1 : () } <FYL>)
|
||||
{
|
||||
$depth = join('/', @depth, shift @tmp);
|
||||
last SEARCH;
|
||||
}
|
||||
close(FYL);
|
||||
}
|
||||
pop @path;
|
||||
pop @pathNoTop;
|
||||
|
||||
if (0 == scalar(@pathNoTop))
|
||||
{
|
||||
$depth = join('/', @depth);
|
||||
last;
|
||||
}
|
||||
|
||||
## Construct path manually
|
||||
push(@depth, '..');
|
||||
}
|
||||
return $depth;
|
||||
} # getDepth
|
||||
|
||||
###########################################################################
|
||||
## Intent: Read in the exclusion file
|
||||
###########################################################################
|
||||
sub getExclusions
|
||||
{
|
||||
my $file = shift || '';
|
||||
|
||||
return () if ($main::argv{'no-exclusions'});
|
||||
|
||||
my %exclude;
|
||||
if ($file)
|
||||
{
|
||||
my @data = cat($file);
|
||||
foreach (@data)
|
||||
{
|
||||
next unless ($_);
|
||||
next if (/^\s*\#/o);
|
||||
next unless (m%/%);
|
||||
chomp;
|
||||
$exclude{$_}++;
|
||||
}
|
||||
}
|
||||
return %exclude;
|
||||
} # getExclusions
|
||||
|
||||
###########################################################################
|
||||
## Intent: Given the path to a makefile beneath either src or obj
|
||||
## derive the relative path prefix between makefile and root.
|
||||
###########################################################################
|
||||
sub getRelPath
|
||||
{
|
||||
my $path0 = shift;
|
||||
my $abspath;
|
||||
|
||||
# Determine type and orientation
|
||||
my $name = basename($path0);
|
||||
my $haveMF = ($name eq 'Makefile.in') ? 1
|
||||
: ($name eq 'Makefile') ? -1
|
||||
: 0
|
||||
;
|
||||
|
||||
####################################################
|
||||
## Prep work: form a relative path with ../ removed
|
||||
####################################################
|
||||
my $top = getTopDir();
|
||||
my $obj = getObjDir();
|
||||
## If the same Makefile will be created alongside Makefile.in
|
||||
my $topQM = quotemeta($top);
|
||||
my $objQM = quotemeta($obj);
|
||||
|
||||
if ('..' eq substr($path0, 0, 2))
|
||||
{
|
||||
my @cwd = split(m%/%, $cwd);
|
||||
my @pth = split(m%/%, $path0);
|
||||
while (@pth && $pth[0] eq '..')
|
||||
{
|
||||
pop(@cwd);
|
||||
shift @pth;
|
||||
}
|
||||
$path0 = join('/', @cwd, @pth);
|
||||
$abspath = $path0;
|
||||
}
|
||||
|
||||
if ('/' eq substr($path0, 0, 1))
|
||||
{
|
||||
$path0 =~ s%^$objQM\/?%%;
|
||||
$path0 =~ s%^$topQM\/?%%;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
## Build a list of directories to search. Input source will be one
|
||||
## of path to Makefile.in, path to Makefile, directory, file within
|
||||
## a directory or relative path from cwd.
|
||||
#######################################################################
|
||||
my @subdirs;
|
||||
my $path = (0 == $haveMF) ? $path0 : dirname($path0);
|
||||
push(@subdirs, $path); # containing directory
|
||||
push(@subdirs, dirname($path)) if (0 == $haveMF && -f $path); # Arg is file within a directory
|
||||
push(@subdirs, $cwd); # relative to pwd
|
||||
|
||||
# obj - path to generated makefile
|
||||
# top - path to Makefile.in source template
|
||||
my @prefixes = ('/' ne substr($path0, 0, 1))
|
||||
? (&getTopDir, &getObjDir)
|
||||
: ()
|
||||
;
|
||||
|
||||
ON_SAFARI:
|
||||
for my $prefix (@prefixes)
|
||||
{
|
||||
next unless ($prefix); # no command line not passed
|
||||
foreach my $subdir (@subdirs)
|
||||
{
|
||||
foreach my $mf ('Makefile.in', 'Makefile')
|
||||
{
|
||||
my $path = join('/', $prefix, $subdir, $mf);
|
||||
if (-e $path)
|
||||
{
|
||||
$name = $mf;
|
||||
$haveMF = ($mf eq 'Makefile.in') ? 1 : -1;
|
||||
$abspath = $path;
|
||||
last ON_SAFARI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
## Generated makefile does not yet exist or path is invalid.
|
||||
## Should this conditon be handled to detect non-existent Makefile.in:
|
||||
## Makefile.am => Makefile.in => Makefile but Makefile.in
|
||||
#######################################################################
|
||||
if (!$abspath && -1 == $haveMF && $obj)
|
||||
{
|
||||
$abspath = ('/' eq substr($path0, 0, 1))
|
||||
? $path0
|
||||
: join('/', $obj, $path0)
|
||||
;
|
||||
}
|
||||
|
||||
########################################################
|
||||
## If --top and/or --obj specified extract relative path
|
||||
########################################################
|
||||
my $relpath;
|
||||
if (! $abspath)
|
||||
{
|
||||
# Error, fall through
|
||||
}
|
||||
elsif (1 == $haveMF) # Makefile.in
|
||||
{
|
||||
## err w/o --top
|
||||
(my $tmp = $abspath) =~ s%^$topQM/?%%;
|
||||
$relpath = dirname($tmp) unless ($tmp eq $abspath);
|
||||
}
|
||||
elsif (-1 == $haveMF) # Makefile
|
||||
{
|
||||
## err w/o --obj
|
||||
(my $tmp = $abspath) =~ s%^$objQM/?%%;
|
||||
$relpath = dirname($tmp) unless ($tmp eq $abspath);
|
||||
}
|
||||
|
||||
$relpath ||= '';
|
||||
$relpath =~ s%/./%/%og; # filter ./
|
||||
|
||||
$@ = ($relpath) ? '' : "ERROR($path0): Unable to locate sources";
|
||||
return $relpath || '';
|
||||
} # getRelPath
|
||||
|
||||
###########################################################################
|
||||
## Intent: Determine sandbox root from script startup directory
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## _set_ optional, if passed use the given value as path
|
||||
## _reset_ clear cached directory path to reassign
|
||||
## Returns:
|
||||
## scalar - absolute path to the sandbox root directory
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
my $gtd_dir;
|
||||
sub getTopDir
|
||||
{
|
||||
if (@_) # testing override
|
||||
{
|
||||
$gtd_dir = abs_path($_[1] || '.') if ($_[0] eq '_set_');
|
||||
$gtd_dir = '' if ($_[0] eq '_reset_');
|
||||
}
|
||||
|
||||
unless ($gtd_dir)
|
||||
{
|
||||
## Set by command line
|
||||
if ($main::argv{top})
|
||||
{
|
||||
$gtd_dir = $main::argv{top};
|
||||
}
|
||||
else
|
||||
{
|
||||
my $path = abs_path($FindBin::RealBin);
|
||||
my @path = split(m%/%o, $path);
|
||||
## --2 memory/mozalloc/Makefile.in
|
||||
## --3 was this for FindBin::Script ?
|
||||
splice(@path, -2);
|
||||
$gtd_dir = join('/', @path);
|
||||
}
|
||||
}
|
||||
return $gtd_dir;
|
||||
} # getTopDir
|
||||
|
||||
###########################################################################
|
||||
## Intent: Determine path to MOZ_OBJDIR/object directory
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## _set_ optional testing arg, if passed re-compute cached value
|
||||
## Returns:
|
||||
## scalar - absolute path to the sandbox object directory
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
my $god_dir;
|
||||
sub getObjDir
|
||||
{
|
||||
if (@_) # testing override
|
||||
{
|
||||
if ($_[0] eq '_reset_')
|
||||
{
|
||||
$god_dir = '';
|
||||
shift;
|
||||
}
|
||||
elsif ($_[0] eq '_set_')
|
||||
{
|
||||
shift;
|
||||
my $path = $_[0] || '.';
|
||||
$god_dir = abs_path($path);
|
||||
shift;
|
||||
}
|
||||
}
|
||||
|
||||
## extract $obj from given path
|
||||
unless ($god_dir)
|
||||
{
|
||||
if ($main::argv{obj})
|
||||
{
|
||||
$god_dir = $main::argv{obj};
|
||||
}
|
||||
elsif (@_ && 'Makefile' eq substr($_, -8))
|
||||
{
|
||||
$god_dir = abs_path(shift);
|
||||
}
|
||||
else # assume we are sitting in moz_objdir
|
||||
{
|
||||
$god_dir = abs_path('.');
|
||||
}
|
||||
}
|
||||
|
||||
return $god_dir;
|
||||
} # getObjDir
|
||||
|
||||
###########################################################################
|
||||
## Intent: Generate Makefile from a given Makefile.in template
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## scalar Relative path to a directory containing a makefile
|
||||
## fargs Hash ref of function arguments.
|
||||
## obj Absolute path to MOZ_OBJ/a destination directory
|
||||
## top Absolute path to the sandbox root
|
||||
## Returns:
|
||||
## $@ Set on error
|
||||
## scalar
|
||||
## 1 True if the makefile was updated
|
||||
## 0 Otherwise
|
||||
## badtokens - If the makefile contains unexpandable @token@ strings
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
sub updateMakefiles
|
||||
{
|
||||
my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
|
||||
local $_;
|
||||
$@ = '';
|
||||
|
||||
my $top = $fargs{top};
|
||||
my $obj = $fargs{obj};
|
||||
|
||||
my $relpath = shift || '';
|
||||
my $src = join('/', $top, $relpath, 'Makefile.in');
|
||||
my $depth = getDepth($src);
|
||||
|
||||
my @src = cat($src);
|
||||
return 0 if ($@);
|
||||
|
||||
my $dst = join('/', $obj, $relpath, 'Makefile');
|
||||
my @dst = cat($dst);
|
||||
$@ = '';
|
||||
|
||||
my $dstD = dirname($dst);
|
||||
mkdirr($dstD);
|
||||
return 0 if ($@);
|
||||
|
||||
my %data =
|
||||
( getConfig(),
|
||||
depth => $depth,
|
||||
srcdir => join('/', $top, $relpath),
|
||||
top_srcdir => $top,
|
||||
);
|
||||
|
||||
my $line = 0;
|
||||
my @data;
|
||||
while (scalar @src)
|
||||
{
|
||||
$line++;
|
||||
$_ = shift(@src);
|
||||
|
||||
## Expand embedded @foo@
|
||||
while (/\@[^\@\s\$]+\@/go)
|
||||
{
|
||||
my $end = pos($_);
|
||||
my $val = $&;
|
||||
my $len = length($val);
|
||||
$val =~ s/^\@\s*//o;
|
||||
$val =~ s/\s*\@$//o;
|
||||
|
||||
## Identify expansions to see if we can avoid shell overhead
|
||||
if (!defined $data{$val} && !$argv{'no-badtokens'})
|
||||
{
|
||||
if (1) # warnings
|
||||
{
|
||||
print STDERR "WARNING: token $val not defined\n";
|
||||
print STDERR " line $line, src: $src\n";
|
||||
}
|
||||
return 'badtokens';
|
||||
}
|
||||
|
||||
# Insert $(error txt) makefile macros for invalid tokens
|
||||
my $val1 = defined($data{$val})
|
||||
? $data{$val}
|
||||
: "\$(error $FindBin::Script: variable ${val} is undefined)"
|
||||
;
|
||||
substr($_, ($end-$len), $len, $val1);
|
||||
}
|
||||
push(@data, $_);
|
||||
}
|
||||
|
||||
if (("@data" eq "@dst") && scalar(@data))
|
||||
{
|
||||
print "Skipping up2date makefile: $dst\n" if ($argv{verbose});
|
||||
}
|
||||
else
|
||||
{
|
||||
my $action = (scalar @dst) ? 'Updating' : 'Creating';
|
||||
print "$action makefile: $dst\n";
|
||||
|
||||
my $tmp = join('.', $dst, "tmp_$$");
|
||||
if (!open(FYL, "> $tmp"))
|
||||
{
|
||||
$@ = "open($tmp) failed: $!";
|
||||
}
|
||||
else
|
||||
{
|
||||
print FYL @data;
|
||||
close(FYL);
|
||||
|
||||
## Install the new makefile
|
||||
File::Copy::move($tmp, $dst)
|
||||
|| ($@ = "move($tmp, $dst) failed: $!");
|
||||
}
|
||||
}
|
||||
|
||||
return $@ ? 0 : 1;
|
||||
} # updateMakefiles
|
||||
|
||||
# Output the makefiles.
|
||||
#
|
||||
sub update_makefiles_legacy {
|
||||
my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
|
||||
my $debug = $main::argv{debug} || 0;
|
||||
my $pwdcmd = ($^O eq 'msys') ? 'pwd -W' : 'pwd';
|
||||
my @unhandled=();
|
||||
|
||||
my @warn;
|
||||
|
||||
my $ac_file;
|
||||
foreach $ac_file (@makefiles) {
|
||||
my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
|
||||
my $ac_dir = dirname_legacy($ac_file);
|
||||
my $ac_dots = '';
|
||||
my $ac_dir_suffix = '';
|
||||
my $srcdir = '.';
|
||||
my $top_srcdir = '.';
|
||||
|
||||
# Determine $srcdir and $top_srcdir
|
||||
#
|
||||
if ($ac_dir ne '.') {
|
||||
$ac_dir_suffix = "/$ac_dir";
|
||||
$ac_dir_suffix =~ s%^/\./%/%;
|
||||
$ac_dots = $ac_dir_suffix;
|
||||
# Remove .. components from the provided dir suffix, and
|
||||
# also the forward path components they were reversing.
|
||||
my $backtracks = $ac_dots =~ s%\.\.(/|$)%%g;
|
||||
while ($backtracks--) {
|
||||
$ac_dots =~ s%/[^/]*%%;
|
||||
}
|
||||
$ac_dots =~ s%/[^/]*%../%g;
|
||||
}
|
||||
if ($ac_given_srcdir eq '.') {
|
||||
if ($ac_dots ne '') {
|
||||
$top_srcdir = $ac_dots;
|
||||
$top_srcdir =~ s%/$%%;
|
||||
}
|
||||
} elsif ($pac_given_srcdir =~ m%^/% or $pac_given_srcdir =~ m%^.:/%) {
|
||||
$srcdir = "$pac_given_srcdir$ac_dir_suffix";
|
||||
$top_srcdir = "$pac_given_srcdir";
|
||||
} else {
|
||||
if ($debug) {
|
||||
print "ac_dots = $ac_dots\n";
|
||||
print "ac_dir_suffix = $ac_dir_suffix\n";
|
||||
}
|
||||
$srcdir = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
|
||||
$top_srcdir = "$ac_dots$ac_given_srcdir";
|
||||
}
|
||||
|
||||
if ($debug) {
|
||||
print "ac_dir = $ac_dir\n";
|
||||
print "ac_file = $ac_file\n";
|
||||
print "ac_file_in = $ac_file_in\n";
|
||||
print "srcdir = $srcdir\n";
|
||||
print "top_srcdir = $top_srcdir\n";
|
||||
print "cwd = " . `$pwdcmd` . "\n";
|
||||
}
|
||||
|
||||
# Copy the file and make substitutions.
|
||||
# @srcdir@ -> value of $srcdir
|
||||
# @top_srcdir@ -> value of $top_srcdir
|
||||
#
|
||||
if (-e $ac_file) {
|
||||
next if -M _ < -M $ac_file_in; # Next if Makefile is up-to-date.
|
||||
warn "updating $ac_file\n";
|
||||
} else {
|
||||
warn "creating $ac_file\n";
|
||||
}
|
||||
|
||||
mkdirr(dirname($ac_file));
|
||||
|
||||
open INFILE, "<$ac_file_in" or do {
|
||||
warn "$0: Cannot read $ac_file_in: No such file or directory\n";
|
||||
next;
|
||||
};
|
||||
open OUTFILE, ">$ac_file" or do {
|
||||
warn "$0: Unable to create $ac_file\n";
|
||||
next;
|
||||
};
|
||||
|
||||
while (<INFILE>) {
|
||||
s/\@srcdir\@/$srcdir/g;
|
||||
s/\@top_srcdir\@/$top_srcdir/g;
|
||||
|
||||
if (/\@[_a-zA-Z]*\@/) {
|
||||
#warn "Unknown variable:$ac_file:$.:$_";
|
||||
push @unhandled, $ac_file;
|
||||
last;
|
||||
}
|
||||
print OUTFILE;
|
||||
}
|
||||
close INFILE;
|
||||
close OUTFILE;
|
||||
}
|
||||
return @unhandled;
|
||||
} # update_makefiles_legacy
|
||||
|
||||
###########################################################################
|
||||
## Intent: Invoke config.status for unknown makefiles to create
|
||||
## directory hierarchy for the tree.
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## array an optional list of makefiles to process
|
||||
## Returns:
|
||||
## 0 on success
|
||||
## $# set on error
|
||||
## -----------------------------------------------------------------------
|
||||
## Note: Is this function needed anymore ? Undefined tokens should fail
|
||||
## at time of expansion rather than having to source config.status.
|
||||
## Also config.status could be parsed to define values and avoide the
|
||||
## shell overhead altogether.
|
||||
###########################################################################
|
||||
sub run_config_status {
|
||||
my @unhandled = @_;
|
||||
|
||||
# Run config.status with any unhandled files.
|
||||
#
|
||||
my @errors;
|
||||
if (@unhandled) {
|
||||
local $ENV{CONFIG_FILES}= join ' ', @unhandled;
|
||||
|
||||
my $conf = 'config.status';
|
||||
if (! -e $conf) # legacy behavior, warn rather than err
|
||||
{
|
||||
my $cwd = cwd();
|
||||
my $err = "$FindBin::Script ERROR: Config file $conf does not exist, cwd=$cwd";
|
||||
push(@errors, $err);
|
||||
}
|
||||
elsif (0 != system("./config.status"))
|
||||
{
|
||||
my $cwd = cwd();
|
||||
push(@errors, "config.status failed \$?=$?, \$!=$!, cwd: $cwd");
|
||||
}
|
||||
}
|
||||
$@ = join("\n", @errors);
|
||||
|
||||
## Legacy behavior: config.status problems are not fatal {yet}.
|
||||
## Display warning since caller will not be calling die.
|
||||
warn $@ if ($@ && $argv{'no-warnings'});
|
||||
return $@ ? 1 : 0;
|
||||
}
|
||||
|
||||
1;
|
94
build/autoconf/test/Makefile.in
Normal file
94
build/autoconf/test/Makefile.in
Normal file
@ -0,0 +1,94 @@
|
||||
# -*- makefile -*-
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Joey Armstrong <joey@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
##################################################
|
||||
## Gather a list of tests, generate timestamp deps
|
||||
##################################################
|
||||
TS=.ts
|
||||
ifneq (,$(findstring check,$(MAKECMDGOALS)))
|
||||
allsrc = $(wildcard $(srcdir)/*)
|
||||
tests2run = $(notdir $(filter %.tpl,$(allsrc)))
|
||||
tests2run += $(notdir $(filter %.tpm,$(allsrc)))
|
||||
check_targets += $(addprefix $(TS)/,$(tests2run))
|
||||
endif
|
||||
|
||||
all_nop: # export, libs and tools are not needed
|
||||
|
||||
check:: $(TS) $(check_targets)
|
||||
|
||||
#############################################
|
||||
# Only invoke tests when sources have changed
|
||||
#############################################
|
||||
$(TS)/%: $(srcdir)/%
|
||||
$(PERL) $(srcdir)/runtest $<
|
||||
@touch $@
|
||||
|
||||
parent = $(patsubst %/,%,$(dir $(srcdir)))
|
||||
$(TS)/make-makefile.tpl: \
|
||||
$(srcdir)/make-makefile.tpl\
|
||||
$(parent)/makemakefile.pm\
|
||||
$(NULL)
|
||||
$(PERL) $(srcdir)/runtest $<
|
||||
@touch $@
|
||||
|
||||
$(TS)/makemakefile.tpm: \
|
||||
$(srcdir)/makemakefile.tpm \
|
||||
$(parent)/makemakefile.pm \
|
||||
$(NULL)
|
||||
$(PERL) $(srcdir)/runtest $<
|
||||
@touch $@
|
||||
|
||||
#####################################################
|
||||
## Extra dep needed to synchronize parallel execution
|
||||
#####################################################
|
||||
$(TS): $(TS)/.done
|
||||
$(TS)/.done:
|
||||
$(MKDIR) -p $(dir $@)
|
||||
touch $@
|
||||
|
||||
GARBAGE_DIRS += $(TS)
|
||||
|
||||
# EOF
|
4
build/autoconf/test/data/mf.notokens
Normal file
4
build/autoconf/test/data/mf.notokens
Normal file
@ -0,0 +1,4 @@
|
||||
jsautocfg.h: jscpucfg$(HOST_BIN_SUFFIX)
|
||||
@$(RM) $@ jsautocfg.tmp
|
||||
./jscpucfg > jsautocfg.tmp
|
||||
mv jsautocfg.tmp $@
|
4
build/autoconf/test/data/mf.notokens.exp
Normal file
4
build/autoconf/test/data/mf.notokens.exp
Normal file
@ -0,0 +1,4 @@
|
||||
jsautocfg.h: jscpucfg$(HOST_BIN_SUFFIX)
|
||||
@$(RM) $@ jsautocfg.tmp
|
||||
./jscpucfg > jsautocfg.tmp
|
||||
mv jsautocfg.tmp $@
|
8
build/autoconf/test/make-makefile.excl
Normal file
8
build/autoconf/test/make-makefile.excl
Normal file
@ -0,0 +1,8 @@
|
||||
###########################################################################
|
||||
## Intent: Exclusion list for container make builds
|
||||
###########################################################################
|
||||
|
||||
/dev/null
|
||||
/foo/bar
|
||||
/a/b/c
|
||||
/a/b/d
|
436
build/autoconf/test/make-makefile.tpl
Normal file
436
build/autoconf/test/make-makefile.tpl
Normal file
@ -0,0 +1,436 @@
|
||||
#!/usr/bin/env perl
|
||||
###########################################################################
|
||||
## Intent: Unit test to verify make-makefile.tpl
|
||||
###########################################################################
|
||||
|
||||
##----------------------------##
|
||||
##---] CORE/CPAN INCLUDES [---##
|
||||
##----------------------------##
|
||||
use strict;
|
||||
use warnings;
|
||||
#use feature 'state'; # 5.10+ not installed everywhere
|
||||
use Getopt::Long;
|
||||
|
||||
use Cwd;
|
||||
use Cwd qw{abs_path};
|
||||
use File::Basename;
|
||||
use File::Copy;
|
||||
use File::Path;
|
||||
use File::Temp qw{ tempdir };
|
||||
|
||||
use Test;
|
||||
sub BEGIN { plan tests => 4 };
|
||||
my @workdirs;
|
||||
sub END { system("/bin/rm -fr @workdirs"); } # cleanup behind interrupts
|
||||
|
||||
##-------------------##
|
||||
##---] EXPORTS [---##
|
||||
##-------------------##
|
||||
use FindBin;
|
||||
our $VERSION = qw(1.0);
|
||||
|
||||
##------------------##
|
||||
##---] INCLUDES [---##
|
||||
##------------------##
|
||||
use FindBin;
|
||||
use lib "$FindBin::RealBin/..";
|
||||
use makemakefile;
|
||||
|
||||
##-------------------##
|
||||
##---] GLOBALS [---##
|
||||
##-------------------##
|
||||
my %argv;
|
||||
|
||||
###########################################################################
|
||||
## Intent: Create a temp sandbox populated with sources
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## array a list of file paths to copy
|
||||
## Returns:
|
||||
## $@ set on error
|
||||
## scalar path to scratch sandbox
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
my $root; # state $root not available
|
||||
sub createSandbox
|
||||
{
|
||||
my @errors;
|
||||
|
||||
unless ($root)
|
||||
{
|
||||
my @tmp = split(m%/%, $FindBin::RealBin);
|
||||
splice(@tmp, -3);
|
||||
$root = join('/', @tmp);
|
||||
}
|
||||
|
||||
my $work = tempdir();
|
||||
push(@workdirs, $work);
|
||||
my @dirs = map{ join('/', $work, dirname($_)) } @_;
|
||||
mkdirr(@dirs);
|
||||
push(@errors, "createSandbox: $@") if ($@);
|
||||
|
||||
foreach (@_)
|
||||
{
|
||||
## Copy sources into the temp source directory
|
||||
my $src = join('/', $root, $_);
|
||||
my $dst = join('/', $work, $_);
|
||||
unless (copy($src, $dst))
|
||||
{
|
||||
push(@errors, "copy($src, $dst) failed: $!");
|
||||
}
|
||||
}
|
||||
print STDERR "createSandbox: $work\n" if ($main::argv{debug});
|
||||
$@ = join('', map{ "$_\n" } @errors);
|
||||
$work;
|
||||
} # createSandbox
|
||||
|
||||
###########################################################################
|
||||
## Intent: wrapper to run the make-makefile command.
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## array command line arguments passed to make-makefile
|
||||
## Returns:
|
||||
## array command output
|
||||
## $@ set by shell exit status, empty string on success
|
||||
## $? command shell exit status
|
||||
###########################################################################
|
||||
my $mm; # state $mm not available
|
||||
sub makemakefile
|
||||
{
|
||||
my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
|
||||
$mm ||= join('/', dirname($FindBin::Bin), 'make-makefile'); # cmd in parent of test/
|
||||
my $cmd = join(' ', $mm, @_);
|
||||
print "RUNNING: $cmd\n" if ($fargs{debug});
|
||||
my @out = `$cmd 2>&1`;
|
||||
print STDERR map{ "out> $_" } @out if ($argv{verbose});
|
||||
$@ = (0 == $?) ? '' : "Command failed: $cmd\n@out";
|
||||
@out;
|
||||
} # makemakefile
|
||||
|
||||
###########################################################################
|
||||
## Intent: Helper function, display the contents of a given sandbox
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## scalar Path to sandbox
|
||||
## Returns:
|
||||
## none
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
sub find_ls
|
||||
{
|
||||
my $path = shift || '';
|
||||
|
||||
# Assuming dot contributes to cryptic problems
|
||||
die "find_ls: a path is required" unless ($path);
|
||||
|
||||
my $cmd = "find $path -ls";
|
||||
print "\nRunning: $cmd\n";
|
||||
print '=' x 75, "\n";
|
||||
print `$cmd`;
|
||||
} # myls
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify make-makefile is able to digest paths and generate
|
||||
## makefiles when object directory is a child of top.
|
||||
###########################################################################
|
||||
sub check_makemakefile
|
||||
{
|
||||
my $work = createSandbox
|
||||
(
|
||||
'memory/mozalloc/Makefile.in',
|
||||
'toolkit/system/windowsproxy/Makefile.in',
|
||||
'toolkit/crashreporter/google-breakpad/src/client/Makefile.in',
|
||||
);
|
||||
|
||||
|
||||
my $workdir = createSandbox();
|
||||
my $top = $workdir;
|
||||
chdir $top;
|
||||
|
||||
my $objA = 'obj-arch-dir';
|
||||
my $obj = join('/', $top, $objA);
|
||||
|
||||
# getTopDir()
|
||||
local $main::argv{top} = $work;
|
||||
local $main::argv{obj} = $obj;
|
||||
getObjDir('_reset_');
|
||||
|
||||
my @root = split(m%/%, $FindBin::RealBin);
|
||||
splice(@root, -3);
|
||||
my $root = join('/', @root);
|
||||
my @args =
|
||||
(
|
||||
|
||||
[
|
||||
banner => "--top and --obj are impled, generate Makefile",
|
||||
rel => 'memory/mozalloc',
|
||||
cmd => join(' ',
|
||||
'--top', $top,
|
||||
'--obj', $obj,
|
||||
'memory/mozalloc/Makefile',
|
||||
),
|
||||
],
|
||||
|
||||
[
|
||||
banner => "--top and abs(obj) passed",
|
||||
rel => "toolkit/system/windowsproxy",
|
||||
cmd => join(' ',
|
||||
'--top', $top,
|
||||
"$obj/toolkit/system/windowsproxy/Makefile",
|
||||
),
|
||||
exp => "$obj/toolkit/system/windowsproxy/Makefile",
|
||||
skip => 1, #
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
banner => "--obj and abs(top) passed",
|
||||
rel => "toolkit/crashreporter/google-breakpad/src/client",
|
||||
cmd => join(' ',
|
||||
'--obj', $obj,
|
||||
"$top/toolkit/crashreporter/google-breakpad/src/client/Makefile.in",
|
||||
),
|
||||
exp => "$top/toolkit/crashreporter/google-breakpad/src/client/Makefile.in",
|
||||
skip => 1, #
|
||||
],
|
||||
|
||||
);
|
||||
|
||||
foreach (@args)
|
||||
{
|
||||
my %rec = @{ $_ };
|
||||
next if ($rec{skip});
|
||||
next unless ($rec{rel});
|
||||
|
||||
my $srcR = join('/', $top, $rec{rel});
|
||||
my $dstR = join('/', $obj, $rec{rel});
|
||||
|
||||
my $src = join('/', $top, $rec{rel}, 'Makefile.in');
|
||||
my $dst = join('/', $obj, $rec{rel}, 'Makefile');
|
||||
|
||||
# Use distinct sources to avoid cleanup overhead between tests
|
||||
die "Test source already used: $dstR" if (-d $dstR);
|
||||
|
||||
## Copy sources into the temp source directory
|
||||
my $rootR = join('/', $root, $rec{rel});
|
||||
my $rootS = join('/', $root, $rec{rel}, 'Makefile.in');
|
||||
File::Path::mkpath($srcR, 0, 0700);
|
||||
copy($rootS, $src) or die "copy($rootS, $src) failed: $!";
|
||||
|
||||
die "source does not exist: $src" unless (-e $src);
|
||||
|
||||
######################
|
||||
## Generate and verify
|
||||
######################
|
||||
print STDERR "RUNNING: $rec{banner}\n" if ($argv{debug});
|
||||
my @errs;
|
||||
makemakefile('--enhanced', $rec{cmd}, {verbose=>1});
|
||||
if ($@)
|
||||
{
|
||||
push(@errs, "\$@ should not be set: $@\n");
|
||||
}
|
||||
elsif (! -e $dst)
|
||||
{
|
||||
push(@errs, "Generated makefile does not exist: $dst, banner: $rec{banner}\n");
|
||||
}
|
||||
|
||||
ok(scalar(@errs), 0, "Errors detected:\n" . join(" $_", @errs));
|
||||
find_ls($top) if (@errs);
|
||||
}
|
||||
|
||||
} # check_makemakefile
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify make-makefile is able to digest paths and generate
|
||||
## makefiles when top/MOZ_OBJDIR are not parent/child directories
|
||||
## ---------------------------------------------------------------------------
|
||||
## Args:
|
||||
## none
|
||||
## Returns:
|
||||
## none
|
||||
## ---------------------------------------------------------------------------
|
||||
###########################################################################
|
||||
sub check_makemakefile_distinct
|
||||
{
|
||||
my $workdir = createSandbox();
|
||||
# my $workdir = tempdir();
|
||||
|
||||
###############################################
|
||||
## Now update when top/obj are not parent/child
|
||||
###############################################
|
||||
my $top = join('/', $workdir, 'top');
|
||||
my $obj = join('/', $workdir, 'obj');
|
||||
|
||||
$main::argv{top} = $top;
|
||||
$main::argv{obj} = $obj; # test afterward, using undef ?
|
||||
|
||||
my @sbxroot = split(m%/%, $FindBin::RealBin);
|
||||
splice(@sbxroot, -2);
|
||||
my $sbxroot = join('/', @sbxroot);
|
||||
|
||||
## Copy in a makefile template to to convert
|
||||
File::Path::mkpath(["$top/memory/mozalloc"], 0, 0700);
|
||||
copy("$sbxroot/memory/mozalloc/Makefile.in", "$top/memory/mozalloc/Makefile.in");
|
||||
|
||||
|
||||
# work/memory/mozalloc/Makefile.in
|
||||
|
||||
my @args =
|
||||
(
|
||||
[
|
||||
banner => '--top and --obj are distinct [1]',
|
||||
cmd => "--obj $obj memory/mozalloc/Makefile",
|
||||
exp => "$obj/memory/mozalloc/Makefile",
|
||||
],
|
||||
|
||||
[
|
||||
banner => "--top and --obj are distinct [2]",
|
||||
cmd => "--top $top memory/mozalloc/Makefile.in",
|
||||
exp => "$obj/memory/mozalloc/Makefile",
|
||||
skip => 1, # test problem: top != obj
|
||||
],
|
||||
|
||||
[
|
||||
banner => "--top and --obj are distinct [3]",
|
||||
cmd => join(' ',
|
||||
"--top $top",
|
||||
"--obj $obj",
|
||||
"memory/mozalloc/Makefile.in",
|
||||
),
|
||||
exp => "$obj/memory/mozalloc/Makefile",
|
||||
skip => 1, # test problem: top != obj
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
foreach (@args)
|
||||
{
|
||||
my %rec = @{ $_ };
|
||||
print STDERR "banner: $rec{banner}\n" if ($argv{debug});
|
||||
next if $rec{skip};
|
||||
|
||||
unlink $rec{exp};
|
||||
makemakefile('--enhanced', $rec{cmd});
|
||||
|
||||
my @errs;
|
||||
if ($@)
|
||||
{
|
||||
push(@errs, "\$@ should not be set: $@\n");
|
||||
}
|
||||
elsif (! -e $rec{exp})
|
||||
{
|
||||
push(@errs, "Makefile does not exist: $rec{exp}\n");
|
||||
}
|
||||
ok(scalar(@errs), 0, "Errors detected:\n" . join(" $_", @errs));
|
||||
}
|
||||
|
||||
} # check_makemakefile_distinct
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify legacy behavior, invoke make-makefile when cwd is
|
||||
## a subdirectory beneath MOZ_OBJDIR.
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## none
|
||||
## Returns:
|
||||
## none
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
sub check_makemakefile_legacy
|
||||
{
|
||||
my $work = createSandbox
|
||||
(
|
||||
'memory/mozalloc/Makefile.in',
|
||||
'parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile.in',
|
||||
);
|
||||
|
||||
my $obj = join('/', $work, 'obj');
|
||||
mkdir $obj;
|
||||
|
||||
my @args =
|
||||
(
|
||||
{
|
||||
banner => '-t path -d dot',
|
||||
cwd => $obj,
|
||||
cmd => "-t $work -d . memory/mozalloc/Makefile",
|
||||
exp => "$obj/memory/mozalloc/Makefile",
|
||||
skip => 0,
|
||||
},
|
||||
|
||||
{
|
||||
banner => '-t path -d relpath',
|
||||
cwd => join('/', $obj, 'parser/htmlparser/tests/mochitest'),
|
||||
cmd => "-t $work -d ../../../.. html5lib_tree_construction/Makefile",
|
||||
exp => "$obj/parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile",
|
||||
skip => 0,
|
||||
},
|
||||
);
|
||||
|
||||
foreach (@args)
|
||||
{
|
||||
my %rec = %{ $_ };
|
||||
next if ($rec{skip});
|
||||
|
||||
## make-make while sitting in $objdir
|
||||
mkdirr($rec{cwd});
|
||||
chdir $rec{cwd} || die "chdir $rec{cwd} failed; $!";
|
||||
|
||||
makemakefile($rec{cmd});
|
||||
my @errs;
|
||||
if ($@)
|
||||
{
|
||||
push(@errs, "make-makefile $rec{cmd} failed: $@");
|
||||
}
|
||||
elsif (! -e $rec{exp})
|
||||
{
|
||||
push(@errs, "generated makefile does not exist: $rec{exp}");
|
||||
}
|
||||
ok(scalar(@errs), 0, "Errors detected: @errs");
|
||||
find_ls($work) if (@errs);
|
||||
}
|
||||
chdir $FindBin::RealBin;
|
||||
} # check_makemakefile_legacy
|
||||
|
||||
###########################################################################
|
||||
## Intent: Smoke tests for the unittests module
|
||||
###########################################################################
|
||||
sub smoke
|
||||
{
|
||||
print STDERR "Running test: smoke()\n" if ($argv{debug});
|
||||
} # smoke()
|
||||
|
||||
###########################################################################
|
||||
## Intent: Intitialize global test objects and consts
|
||||
###########################################################################
|
||||
sub init
|
||||
{
|
||||
print "Running: init()\n" if ($argv{debug});
|
||||
# testplan(24, 0);
|
||||
} # init()
|
||||
|
||||
##----------------##
|
||||
##---] MAIN [---##
|
||||
##----------------##
|
||||
unless(GetOptions(\%argv,
|
||||
qw(
|
||||
debug|d
|
||||
manual
|
||||
test=s@
|
||||
verbose
|
||||
)))
|
||||
{
|
||||
print "USAGE: $0\n";
|
||||
print " --debug Enable script debug mode\n";
|
||||
print " --manual Also run disabled tests\n";
|
||||
print " --smoke Run smoke tests then exit\n";
|
||||
print " --test Run a list of tests by function name\n";
|
||||
print " --verbose Enable script verbose mode\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
init();
|
||||
smoke();
|
||||
|
||||
check_makemakefile();
|
||||
check_makemakefile_distinct();
|
||||
check_makemakefile_legacy();
|
519
build/autoconf/test/makemakefile.tpm
Normal file
519
build/autoconf/test/makemakefile.tpm
Normal file
@ -0,0 +1,519 @@
|
||||
#!/usr/bin/env perl
|
||||
###########################################################################
|
||||
## Intent: Unit test to verify the makemakefile.pm module
|
||||
###########################################################################
|
||||
|
||||
##----------------------------##
|
||||
##---] CORE/CPAN INCLUDES [---##
|
||||
##----------------------------##
|
||||
use strict;
|
||||
use warnings;
|
||||
#use feature 'state';
|
||||
use Getopt::Long;
|
||||
|
||||
use FindBin;
|
||||
use Cwd qw{abs_path};
|
||||
use File::Basename;
|
||||
use File::Compare;
|
||||
use File::Copy;
|
||||
use File::Temp qw{tempdir};
|
||||
|
||||
use Test;
|
||||
sub BEGIN { plan tests => 36 };
|
||||
my @workdirs;
|
||||
sub END { system("/bin/rm -fr @workdirs"); } # cleanup behind interrupts
|
||||
|
||||
##-------------------##
|
||||
##---] EXPORTS [---##
|
||||
##-------------------##
|
||||
our $VERSION = qw(1.0);
|
||||
|
||||
##------------------##
|
||||
##---] INCLUDES [---##
|
||||
##------------------##
|
||||
use FindBin;
|
||||
use lib "$FindBin::RealBin/..";
|
||||
use makemakefile;
|
||||
|
||||
##-------------------##
|
||||
##---] GLOBALS [---##
|
||||
##-------------------##
|
||||
my %argv;
|
||||
|
||||
###########################################################################
|
||||
## Intent: Create a temp sandbox populated with sources
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## array files to copy into the temporary sandbox
|
||||
## Returns:
|
||||
## $@ set on error
|
||||
## array
|
||||
## top - path to temp sandbox root
|
||||
## obj - path to temp sandbox moz_obj directory
|
||||
## -----------------------------------------------------------------------
|
||||
###########################################################################
|
||||
my $_root_; # state $root
|
||||
sub createSandbox
|
||||
{
|
||||
# state $root;
|
||||
my @errors;
|
||||
|
||||
unless ($_root_)
|
||||
{
|
||||
my @tmp = split(m%/%, $FindBin::RealBin);
|
||||
splice(@tmp, -3);
|
||||
$_root_ = join('/', @tmp);
|
||||
}
|
||||
|
||||
my $work = tempdir(CLEANUP=>1);
|
||||
push(@workdirs, $work);
|
||||
my @dirs = map{ join('/', $work, dirname($_)) } @_;
|
||||
mkdirr(@dirs);
|
||||
push(@errors, "createSandbox: $@") if ($@);
|
||||
|
||||
foreach (@_)
|
||||
{
|
||||
## Copy sources into the temp source directory
|
||||
my $src = join('/', $_root_, $_);
|
||||
my $dst = join('/', $work, $_);
|
||||
unless (copy($src, $dst))
|
||||
{
|
||||
push(@errors, "copy($src, $dst) failed: $!");
|
||||
}
|
||||
}
|
||||
print STDERR "createSandbox: $work\n" if ($main::argv{debug});
|
||||
$@ = join('', map{ "$_\n" } @errors);
|
||||
$work;
|
||||
} # createSandbox
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify legacy dirname function
|
||||
###########################################################################
|
||||
sub check_dirname_legacy
|
||||
{
|
||||
print "Running: check_dirname_legacy\n" if ($main::argv{debug});
|
||||
|
||||
foreach (
|
||||
['/dev/null', '/dev'],
|
||||
['/foo/bar/Makefile', '/foo/bar'],
|
||||
)
|
||||
{
|
||||
my ($src, $exp) = @{ $_ };
|
||||
my $dir = dirname_legacy($src);
|
||||
ok($dir, $exp, "dirname_legacy($src) failed");
|
||||
}
|
||||
|
||||
my $path = dirname_legacy(undef);
|
||||
ok($path ? 1 : 0, 1, "dirname('') should expand to cwd");
|
||||
} # check_dirname_legacy
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify topdir lookup function
|
||||
###########################################################################
|
||||
sub check_getTopDir
|
||||
{
|
||||
print "Running: check_getTopDir\n" if ($main::argv{debug});
|
||||
|
||||
my $path = getTopDir();
|
||||
|
||||
## Unit test is special, cmd not invoked from the same directory
|
||||
## as the makemakefile.pm module.
|
||||
ok($path ? 1 : 0, 1, "getTopDir failed");
|
||||
ok(-d $path ? 1 : 0, 1, "getTopDir: directory $path does not exist");
|
||||
ok($FindBin::RealBin =~ m%$path/% ? 1 : 0, 1, 'Invalid topdir path');
|
||||
ok(-e "$path/client.mk" ? 1 : 0, 1, "client.mk not found in $path");
|
||||
} # check_getTopDir
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify objdir lookup function
|
||||
###########################################################################
|
||||
sub check_getObjDir
|
||||
{
|
||||
print "Running: check_getObjDir\n" if ($main::argv{debug});
|
||||
local $main::argv{obj} = '/bin';
|
||||
my $path = getObjDir('_reset_');
|
||||
ok($path ? 1 : 0, 1, "getObjDir failed");
|
||||
ok(-d $path ? 1 : 0, 1, "getObjDir: directory $path does not exist");
|
||||
|
||||
my $top = getTopDir();
|
||||
$main::argv{obj} = join('/', $top, 'browser'); # use existing path so file can be resolved
|
||||
my $obj = getObjDir('_reset_');
|
||||
ok($top ne $obj ? 1 : 0, 1, "top and object directory paths should not match");
|
||||
|
||||
## If we fail for /bin use here getObjDir() was not reset
|
||||
my $client = join('/', $obj, '..', 'client.mk');
|
||||
ok(-e $client ? 1 : 0, 1, "client.mk not found in parent of $path, $client");
|
||||
getObjDir('_set_'); # clear cached value and recompute
|
||||
|
||||
foreach my $file ("$top/memory/mozalloc/Makefile")
|
||||
{
|
||||
my $obj = getObjDir('_reset_', $file);
|
||||
ok($obj ne $file ? 1 : 0, 1, "getObjDir($file) failed")
|
||||
}
|
||||
} # check_getObjDir
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify rel-path-to-root/getdepth function
|
||||
###########################################################################
|
||||
sub check_getDepth
|
||||
{
|
||||
my @tmp = split(m%/%o, $FindBin::Bin);
|
||||
splice(@tmp, -3);
|
||||
my $root = abs_path( join('/', @tmp) );
|
||||
|
||||
my %data =
|
||||
(
|
||||
$root => '.',
|
||||
join('/', $root, 'netwerk/Makefile.in') => '..',
|
||||
|
||||
join('/', $root, 'browser/components/privatebrowsing/test/browser/Makefile.in') => '../../../../..',
|
||||
join('/', $root, 'browser/components/privatebrowsing/test/browser/') => '../../../../..',
|
||||
join('/', $root, 'browser/components/privatebrowsing/test/browser') => '../../../../..',
|
||||
join('/', $root, 'browser/components/privatebrowsing/test') => '../../../..',
|
||||
);
|
||||
|
||||
while (my($k, $v) = each %data)
|
||||
{
|
||||
my $depth = makemakefile::getDepth($k);
|
||||
ok($depth, $v, "getDepth($k) failed");
|
||||
}
|
||||
} # check_getDepth
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify reading the exclusion file
|
||||
###########################################################################
|
||||
sub check_getExclusions
|
||||
{
|
||||
my $cfg = join('/', $FindBin::RealBin, 'make-makefile.excl');
|
||||
my %excl = getExclusions($cfg);
|
||||
ok($@, '', '$@ should not be set');
|
||||
|
||||
my @excl = sort keys %excl;
|
||||
ok(scalar @excl, 4, "Exclusion file is invalid: \@excl=@excl");
|
||||
} # check_getExclusions
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify rel-path-to-root function
|
||||
## -----------------------------------------------------------------------
|
||||
## Args:
|
||||
## none
|
||||
## Returns:
|
||||
## none
|
||||
## -----------------------------------------------------------------------
|
||||
## Note:
|
||||
## String test only, top and obj paths are bogus for this test
|
||||
###########################################################################
|
||||
sub check_getRelPath
|
||||
{
|
||||
my @tmp = split(m%/%o, $FindBin::Bin);
|
||||
splice(@tmp, -3);
|
||||
my $root = abs_path( join('/', @tmp) );
|
||||
my $obj0 = 'obj-arch';
|
||||
my $obj = join('/', $root, $obj0);
|
||||
|
||||
local $main::argv{top} = $root;
|
||||
local $main::argv{obj} = $obj;
|
||||
getTopDir('_reset_');
|
||||
getObjDir('_set_', $obj);
|
||||
|
||||
## Cannot test relative paths with objdir beneath /tmp
|
||||
## Commented paths are needed for full test coverage
|
||||
## but are not currently supported by all module functions.
|
||||
my %data =
|
||||
(
|
||||
# Relative - path correct for build directory but
|
||||
'profile/dirserviceprovider/public/Makefile.in' => 'profile/dirserviceprovider/public',
|
||||
|
||||
join('/', $root, 'profile/dirserviceprovider/public/Makefile.in') => 'profile/dirserviceprovider/public',
|
||||
|
||||
# File search
|
||||
'profile/dirserviceprovider/public' => 'profile/dirserviceprovider/public',
|
||||
|
||||
# cwd + cleanup
|
||||
# '../../../profile/dirserviceprovider/public/Makefile.in' => 'profile/dirserviceprovider/public',
|
||||
# "../../../${obj0}/profile/dirserviceprovider/public/Makefile.in" => 'profile/dirserviceprovider/public',
|
||||
|
||||
## Special case: This could be handled but permutations of non-existent files, non-overlapping paths
|
||||
## and relative paths containing partial subdirectories will compilicate the logic. Wait until needed.
|
||||
## Relative path: $root + obj + subdir
|
||||
# "${obj0}/profile/dirserviceprovider/public/Makefile" => 'profile/dirserviceprovider/public',
|
||||
join('/', $obj, 'profile/dirserviceprovider/public/Makefile') => 'profile/dirserviceprovider/public',
|
||||
|
||||
# $RealBin, -d ../../..
|
||||
# top and obj not subdirectories of each other: /foo/x, /bar/y
|
||||
);
|
||||
|
||||
while (my($k, $v) = each %data)
|
||||
{
|
||||
my $dir = getRelPath($k);
|
||||
ok($@, '', '$@ should not be set');
|
||||
ok($dir, $v, "ERROR[$k]: exp[$v] != found=[$dir]");
|
||||
}
|
||||
|
||||
|
||||
my $top = '/tmp/foo';
|
||||
my $tmp = '/tmp/bar';
|
||||
local $main::argv{top} = $tmp;
|
||||
local $main::argv{obj} = $obj;
|
||||
|
||||
%data =
|
||||
(
|
||||
# "$top/profile/dirserviceprovider/public/Makefile.in" => 'profile/dirserviceprovider/public',
|
||||
"$obj/profile/dirserviceprovider/public/Makefile" => 'profile/dirserviceprovider/public',
|
||||
);
|
||||
|
||||
while (my($k, $v) = each %data)
|
||||
{
|
||||
my $dir = getRelPath($k);
|
||||
ok($dir, $v, "ERROR[$k]: exp[$v] != found=[$dir]");
|
||||
}
|
||||
} # check_getRelPath
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify rel-path-to-root directory creation
|
||||
###########################################################################
|
||||
sub check_mkdirr
|
||||
{
|
||||
if (-w '/bin') # cygwin may be writable
|
||||
{
|
||||
ok(1, 1, 'bogus test to maintain count');
|
||||
} else {
|
||||
mkdirr('/bin/invalid/Makefile');
|
||||
ok($@ ? 1 : 0, 1, '$@ should be set');
|
||||
}
|
||||
|
||||
my $work = createSandbox();
|
||||
my @paths = map{ join('/', $work, $_, 'Makefile.in') } qw (xyz/abc foo/bar a/b/c/d/e);
|
||||
mkdirr(@paths);
|
||||
ok($@ ? 1 : 0, 0, '$@ should not be set');
|
||||
|
||||
push(@paths, '/bin');
|
||||
|
||||
my @errors;
|
||||
foreach (@paths)
|
||||
{
|
||||
my $dir = dirname($_);
|
||||
next if (-d $dir);
|
||||
push(@errors, "mkdirr($dir) failed\n");
|
||||
}
|
||||
ok(scalar @errors, 0, "Errors detected: @errors");
|
||||
} # check_mkdirr
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify permutations for system("config.status")
|
||||
###########################################################################
|
||||
sub check_run_config_status
|
||||
{
|
||||
print STDERR "Running: check_run_config_status()\n"
|
||||
if ($main::argv{debug});
|
||||
|
||||
my $work = createSandbox();
|
||||
chdir $work;
|
||||
run_config_status();
|
||||
ok($@ ? 1 : 0, '$@ should be set, config.status does not exist');
|
||||
|
||||
my $cfg = join('/', $work, 'config.status');
|
||||
local *CFG;
|
||||
open(CFG, "> $cfg") && close(CFG);
|
||||
run_config_status();
|
||||
ok($@, qr/config.status failed/, '$@ should be set, config.status is not executabl');
|
||||
|
||||
open(CFG, "> $cfg");
|
||||
print CFG join("\n",
|
||||
'#!/bin/sh',
|
||||
'',
|
||||
'true',
|
||||
'');
|
||||
close(CFG);
|
||||
chmod 0555, $cfg;
|
||||
run_config_status();
|
||||
ok($@, qr/config.status failed/, '$@ should not be set');
|
||||
|
||||
} # check_run_config_status
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify makefile generation by legacy make-makefile functions
|
||||
## o make-makefile -t /x/y -d ..
|
||||
###########################################################################
|
||||
sub check_update_makefiles_legacy
|
||||
{
|
||||
print STDERR "Running: check_update_makefiles_legacy()\n"
|
||||
if ($main::argv{debug});
|
||||
|
||||
return unless ($argv{legacy});
|
||||
print STDERR "check_update_makefiles_legacy: not yet implemented\n";
|
||||
|
||||
} # check_update_makefiles_legacy
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify updateMakefiles()
|
||||
## o a makefile is generated when none exists.
|
||||
## o a makefile will only be updated when the templates changes.
|
||||
## o existing makefiles will be updated when the template changes.
|
||||
## o @foo@ tokens have been expanded
|
||||
###########################################################################
|
||||
sub check_updateMakefiles
|
||||
{
|
||||
my @errors;
|
||||
|
||||
print STDERR "Running: check_updateMakefiles()\n"
|
||||
if ($main::argv{debug});
|
||||
|
||||
my $mf = 'memory/mozalloc/Makefile.in';
|
||||
|
||||
my $work = createSandbox($mf);
|
||||
my $obj = join('/', $work, 'obj');
|
||||
my %args =
|
||||
(
|
||||
top => $work,
|
||||
obj => $obj,
|
||||
);
|
||||
|
||||
my $mf_src = join('/', $work, 'memory/mozalloc/Makefile.in');
|
||||
my $mf_dst = join('/', $obj, 'memory/mozalloc/Makefile');
|
||||
|
||||
updateMakefiles('memory/mozalloc', \%args);
|
||||
my $tlm0 = (stat $mf_dst)[9] || 0;
|
||||
ok(-e $mf_dst ? 1 : 0, 1, "failed to generate makefile: $mf_dst");
|
||||
|
||||
#############################
|
||||
## Regeneration will be a nop
|
||||
#############################
|
||||
updateMakefiles('memory/mozalloc', \%args);
|
||||
my $tlm1 = (stat $mf_dst)[9] || -1;
|
||||
ok($tlm1, $tlm0, "makefile should not have been modified");
|
||||
|
||||
#####################################################
|
||||
## Modify template to verify makefile will regenerate
|
||||
#####################################################
|
||||
local *MF;
|
||||
if (open(MF, ">> $mf_src"))
|
||||
{
|
||||
print MF map{ "# MODIFIED MAKEFILE\n" } 0..4;
|
||||
close(MF);
|
||||
}
|
||||
updateMakefiles('memory/mozalloc', \%args);
|
||||
my @data = makemakefile::cat($mf_dst);
|
||||
## Check content to avoid a silly 'sleep [n]' call here
|
||||
ok(grep(/^\# MODIFIED MAKEFILE/o, @data) ? 1 : 0,
|
||||
1,
|
||||
"template modified, makefile should have regenerated");
|
||||
|
||||
## VERIFY template expansion
|
||||
my @gen = makemakefile::cat($mf_dst);
|
||||
push(@errors, $@) if ($@);
|
||||
|
||||
foreach (@gen)
|
||||
{
|
||||
if (/\@[^\@]+\@/o)
|
||||
{
|
||||
push(@errors, join("\n",
|
||||
"Unexpanded template string detected [$_]",
|
||||
"Makefile: $mf_src",
|
||||
));
|
||||
last;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ok(scalar(@errors), 0, "Errors detected: @errors");
|
||||
} # check_updateMakefiles
|
||||
|
||||
###########################################################################
|
||||
## Intent: Verify makefile generation by updateMakefiles() when
|
||||
## command line arguments --top and --obj were passed.
|
||||
###########################################################################
|
||||
sub check_updateMakefilesByTopObj
|
||||
{
|
||||
my @errors;
|
||||
|
||||
print STDERR "Running: check_updateMakefilesByTopObj()\n"
|
||||
if ($main::argv{debug});
|
||||
|
||||
my $work = createSandbox();
|
||||
my %args =
|
||||
(
|
||||
top => $work,
|
||||
obj => $work,
|
||||
);
|
||||
|
||||
## Grab a list of makefile templates to generate
|
||||
my @all = glob('data/mf.*');
|
||||
my @src = map{ /\.exp$/o ? () : $_ } @all;
|
||||
|
||||
foreach my $src (@src)
|
||||
{
|
||||
my $dst = join('/', $work, 'Makefile');
|
||||
unlink $dst;
|
||||
copy($src, "$work/Makefile.in");
|
||||
updateMakefiles('.', \%args);
|
||||
ok($@, '', '$@ should not be set');
|
||||
|
||||
my @dst = makemakefile::cat($dst);
|
||||
|
||||
my $exp = join('.', $src, 'exp');
|
||||
my @exp = makemakefile::cat($exp);
|
||||
ok("@dst", "@exp", "updateMakefile($dst) failed");
|
||||
}
|
||||
return;
|
||||
} # check_updateMakefilesByTopObj
|
||||
|
||||
###########################################################################
|
||||
## Intent: Smoke tests for the unittests module
|
||||
###########################################################################
|
||||
sub smoke
|
||||
{
|
||||
print STDERR "Running test: smoke()\n" if ($argv{debug});
|
||||
} # smoke()
|
||||
|
||||
###########################################################################
|
||||
## Intent: Intitialize global test objects and consts
|
||||
###########################################################################
|
||||
sub init
|
||||
{
|
||||
print "Running: init()\n" if ($argv{debug});
|
||||
# testplan(24, 0);
|
||||
|
||||
my @path = split(m%/%, $FindBin::RealBin);
|
||||
splice(@path, -3);
|
||||
my $top = join('/', @path);
|
||||
## Top set based on make-makefile startup directory so adjust for test/ use
|
||||
getTopDir('_set_', $top);
|
||||
|
||||
} # init()
|
||||
|
||||
##----------------##
|
||||
##---] MAIN [---##
|
||||
##----------------##
|
||||
unless(GetOptions(\%argv,
|
||||
qw(
|
||||
debug|d
|
||||
manual
|
||||
test=s@
|
||||
verbose
|
||||
)))
|
||||
{
|
||||
print "USAGE: $0\n";
|
||||
print " --debug Enable script debug mode\n";
|
||||
print " --manual Also run disabled tests\n";
|
||||
print " --smoke Run smoke tests then exit\n";
|
||||
print " --test Run a list of tests by function name\n";
|
||||
print " --verbose Enable script verbose mode\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
init();
|
||||
smoke();
|
||||
|
||||
check_dirname_legacy();
|
||||
|
||||
check_getTopDir();
|
||||
check_getObjDir();
|
||||
check_getDepth();
|
||||
check_getExclusions();
|
||||
check_getRelPath();
|
||||
check_mkdirr();
|
||||
|
||||
check_updateMakefiles();
|
||||
check_update_makefiles_legacy();
|
||||
check_updateMakefilesByTopObj();
|
95
build/autoconf/test/runtest
Normal file
95
build/autoconf/test/runtest
Normal file
@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env perl
|
||||
###########################################################################
|
||||
## Intent:
|
||||
## Test::Harness is a testing wrapper that will process output
|
||||
## from Test.pm module tests. Sumarize results, report stats
|
||||
## and exit with overall status for the testing suites.
|
||||
##
|
||||
## Run testing suite:
|
||||
## % make clean test
|
||||
## % perl runtest
|
||||
##
|
||||
## Run Individual tests
|
||||
## % perl tUtils0
|
||||
###########################################################################
|
||||
|
||||
##----------------------------##
|
||||
##---] CORE/CPAN INCLUDES [---##
|
||||
##----------------------------##
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
use Test::Harness;
|
||||
|
||||
##-------------------##
|
||||
##---] EXPORTS [---##
|
||||
##-------------------##
|
||||
our $VERSION = qw(1.0);
|
||||
use FindBin;
|
||||
|
||||
##-------------------##
|
||||
##---] GLOBALS [---##
|
||||
##-------------------##
|
||||
my %argv;
|
||||
|
||||
##----------------##
|
||||
##---] MAIN [---##
|
||||
##----------------##
|
||||
unless(GetOptions(\%argv,
|
||||
qw(debug|d)
|
||||
))
|
||||
{
|
||||
print "Usage: $0\n";
|
||||
print " --debug Enable debug mode\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if (2 > $Test::Harness::VERSION)
|
||||
{
|
||||
print "Unit tests will not be run, Test::Harness is too old\n"
|
||||
if ($argv{debug});
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
my @tests;
|
||||
|
||||
########################################
|
||||
## Gather a list of tests if none passed
|
||||
########################################
|
||||
unless (@tests = @ARGV)
|
||||
{
|
||||
local *D;
|
||||
opendir(D, '.');
|
||||
while($_ = readdir(D)) {
|
||||
next unless /.t\S+$/;
|
||||
next if (/\.ts$/);
|
||||
push(@tests, $_);
|
||||
}
|
||||
closedir(D);
|
||||
}
|
||||
|
||||
###############################################
|
||||
## Glob a list of tests when directories passed
|
||||
###############################################
|
||||
my @tmp;
|
||||
foreach (@tests)
|
||||
{
|
||||
local *D;
|
||||
if (-d $_ && (my $dir = $_))
|
||||
{
|
||||
opendir(D, $_) || die "opendir(D) failed: $!";
|
||||
my @tests = grep(/\.t[^\.\s]+/o, readdir(D));
|
||||
closedir(D);
|
||||
push(@tmp, map{ join('/', $dir, $_); } @tests);
|
||||
} else {
|
||||
push(@tmp, $_);
|
||||
}
|
||||
}
|
||||
@tests = @tmp;
|
||||
|
||||
print "$0: @ARGV\n" if ($argv{debug});
|
||||
runtests(@tests);
|
||||
|
||||
# EOF
|
@ -16,5 +16,6 @@
|
||||
__malloc_hook;
|
||||
__realloc_hook;
|
||||
__memalign_hook;
|
||||
_IO_stdin_used;
|
||||
local: *;
|
||||
};
|
||||
|
@ -109,3 +109,10 @@ endif
|
||||
|
||||
endif # ! MOZ_DEBUG
|
||||
endif # WIN32_REDIST_DIR
|
||||
|
||||
# run the binscope tool to make sure the binary and all libraries
|
||||
# are using all available Windows OS-level security mechanisms
|
||||
check::
|
||||
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/firefox.exe $(DIST)/crashreporter-symbols/
|
||||
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/plugin-container.exe $(DIST)/crashreporter-symbols/
|
||||
|
||||
|
108
build/win32/autobinscope.py
Normal file
108
build/win32/autobinscope.py
Normal file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# imelven@mozilla.com
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# run Microsoft's Binscope tool (http://www.microsoft.com/download/en/details.aspx?id=11910)
|
||||
# against a fresh Windows build. output a 'binscope.log' file with full details
|
||||
# of the run and appropriate strings to integrate with the buildbots
|
||||
|
||||
# from the docs : "The error code returned when running under the command line is equal
|
||||
# to the number of failures the tool reported plus the number of errors. BinScope will return
|
||||
# 0 only if there are no errors or failures."
|
||||
|
||||
# the symbol dir should point to the symbol dir hierarchy created
|
||||
# via running make buildsymbols in a windows build's objdir
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
BINSCOPE_OUTPUT_LOGFILE = r".\binscope_xml_output.log"
|
||||
|
||||
# usage
|
||||
if len(sys.argv) < 3:
|
||||
print """usage : autobinscope.by path_to_binary path_to_symbols [log_file_path]"
|
||||
log_file_path is optional, log will be written to .\binscope_xml_output.log by default"""
|
||||
sys.exit(0)
|
||||
|
||||
binary_path = sys.argv[1]
|
||||
symbol_path = sys.argv[2]
|
||||
|
||||
if len(sys.argv) == 4:
|
||||
log_file_path = sys.argv[3]
|
||||
else:
|
||||
log_file_path = BINSCOPE_OUTPUT_LOGFILE
|
||||
|
||||
# execute binscope against the binary, using the BINSCOPE environment
|
||||
# variable as the path to binscope.exe
|
||||
try:
|
||||
binscope_path = os.environ['BINSCOPE']
|
||||
except KeyError:
|
||||
print "BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status."
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
proc = subprocess.Popen([binscope_path, "/target", binary_path,
|
||||
"/output", log_file_path, "/sympath", symbol_path,
|
||||
"/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "FunctionPointersCheck",
|
||||
"/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck",
|
||||
"/c", "GSCheck", "/c", "GSFunctionSafeBuffersCheck", "/c", "GSFriendlyInitCheck",
|
||||
"/c", "CompilerVersionCheck", "/c", "SafeSEHCheck", "/c", "SNCheck",
|
||||
"/c", "DBCheck"], stdout=subprocess.PIPE)
|
||||
|
||||
except WindowsError, (errno, strerror):
|
||||
if errno != 2 and errno != 3:
|
||||
print "Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n"
|
||||
sys.exit(0)
|
||||
else:
|
||||
print "Could not locate binscope at location : %s\n" % binscope_path
|
||||
print "Binscope wasn't installed or the BINSCOPE env variable wasn't set correctly, skipping this check and exiting..."
|
||||
sys.exit(0)
|
||||
|
||||
proc.wait()
|
||||
|
||||
output = proc.communicate()[0]
|
||||
|
||||
# is this a PASS or a FAIL ?
|
||||
if proc.returncode != 0:
|
||||
print "TEST-UNEXPECTED-FAIL | autobinscope.py | %s is missing a needed Windows protection, such as /GS or ASLR" % binary_path
|
||||
else:
|
||||
print "TEST-PASS | autobinscope.py | %s succeeded" % binary_path
|
||||
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
if not sys.platform == "win32":
|
||||
raise Exception("This script was only meant for Windows.")
|
||||
|
||||
import os
|
||||
|
||||
def dos2unix(path):
|
||||
print "dos2unix: %s" % path
|
||||
|
||||
inf = open(path, "r")
|
||||
data = inf.read()
|
||||
inf.close()
|
||||
|
||||
|
||||
outf = open(path, "wb")
|
||||
outf.write(data)
|
||||
outf.close()
|
||||
|
||||
adminfiles = [
|
||||
"Root",
|
||||
"Repository",
|
||||
"Entries",
|
||||
"Entries.Log",
|
||||
"Entries.Static",
|
||||
"Tag",
|
||||
"Notify",
|
||||
"Template"
|
||||
]
|
||||
|
||||
def walkdirectory(path):
|
||||
if not os.path.exists(os.path.join(path, "CVS")):
|
||||
return
|
||||
|
||||
print "Directory: %s" % path
|
||||
|
||||
for f in adminfiles:
|
||||
cvsf = os.path.join(path, "CVS", f)
|
||||
if os.path.exists(cvsf):
|
||||
dos2unix(cvsf)
|
||||
|
||||
entries = open(os.path.join(path, "CVS", "Entries"), "r")
|
||||
for entry in entries:
|
||||
if entry == "D\n":
|
||||
continue
|
||||
|
||||
(type, filename, rev, date, flags, extra) = entry.split('/')
|
||||
if type == "D" or flags == "-kb" or rev[0] == "-":
|
||||
continue
|
||||
|
||||
dos2unix(os.path.join(path, filename))
|
||||
|
||||
# Now walk subdirectories
|
||||
for entry in os.listdir(path):
|
||||
subdir = os.path.join(path, entry)
|
||||
if os.path.isdir(subdir):
|
||||
walkdirectory(subdir)
|
||||
|
||||
topsrcdir = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-3])
|
||||
|
||||
print """This command will convert the source tree at
|
||||
%s
|
||||
to an MSYS-compatible (unix mode) source tree. You can run this
|
||||
command multiple times safely. Are you sure you want to continue (Y/N)? """ % topsrcdir,
|
||||
sys.stdout.flush()
|
||||
print
|
||||
|
||||
ask = raw_input()
|
||||
if len(ask) == 0 or (ask[0] != "y" and ask[0] != "Y"):
|
||||
raise Exception("User aborted action.")
|
||||
|
||||
walkdirectory(topsrcdir)
|
@ -140,6 +140,7 @@ MOZ_UPDATE_PACKAGING = @MOZ_UPDATE_PACKAGING@
|
||||
MOZ_DISABLE_PARENTAL_CONTROLS = @MOZ_DISABLE_PARENTAL_CONTROLS@
|
||||
NS_ENABLE_TSF = @NS_ENABLE_TSF@
|
||||
MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
|
||||
MOZ_ANDROID_HISTORY = @MOZ_ANDROID_HISTORY@
|
||||
MOZ_JAVA_COMPOSITOR = @MOZ_JAVA_COMPOSITOR@
|
||||
MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
|
||||
MOZ_FEEDS = @MOZ_FEEDS@
|
||||
|
@ -122,6 +122,19 @@ testxpcobjdir = $(DEPTH)/_tests/xpcshell
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
|
||||
# Add test directories to the regular directories list. TEST_DIRS should
|
||||
# arguably have the same status as TOOL_DIRS and other *_DIRS variables. It is
|
||||
# coded this way until Makefiles stop using the "ifdef ENABLE_TESTS; DIRS +="
|
||||
# convention.
|
||||
#
|
||||
# The current developer workflow expects tests to be updated when processing
|
||||
# the default target. If we ever change this implementation, the behavior
|
||||
# should be preserved or the change should be widely communicated. A
|
||||
# consequence of not processing test dir targets during the default target is
|
||||
# that changes to tests may not be updated and code could assume to pass
|
||||
# locally against non-current test code.
|
||||
DIRS += $(TEST_DIRS)
|
||||
|
||||
ifdef XPCSHELL_TESTS
|
||||
ifndef relativesrcdir
|
||||
$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
|
||||
|
@ -4681,7 +4681,7 @@ NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciw
|
||||
USE_ARM_KUSER=
|
||||
BUILD_CTYPES=1
|
||||
MOZ_USE_NATIVE_POPUP_WINDOWS=
|
||||
|
||||
MOZ_ANDROID_HISTORY=
|
||||
|
||||
case "${target}" in
|
||||
*android*|*darwin*)
|
||||
@ -8464,6 +8464,7 @@ AC_SUBST(MOZ_D3DCOMPILER_CAB)
|
||||
AC_SUBST(MOZ_D3DX9_DLL)
|
||||
AC_SUBST(MOZ_D3DCOMPILER_DLL)
|
||||
|
||||
AC_SUBST(MOZ_ANDROID_HISTORY)
|
||||
AC_SUBST(ENABLE_STRIP)
|
||||
AC_SUBST(PKG_SKIP_STRIP)
|
||||
AC_SUBST(USE_ELF_DYNSTR_GC)
|
||||
|
@ -245,7 +245,7 @@ protected:
|
||||
friend class DataOwnerAdapter; // Needs to see DataOwner
|
||||
class DataOwner {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(DataOwner)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataOwner)
|
||||
DataOwner(void* aMemoryBuffer)
|
||||
: mData(aMemoryBuffer)
|
||||
{
|
||||
|
@ -819,9 +819,7 @@ nsContentSink::ProcessLink(nsIContent* aElement,
|
||||
const nsSubstring& aRel, const nsSubstring& aTitle,
|
||||
const nsSubstring& aType, const nsSubstring& aMedia)
|
||||
{
|
||||
// XXX seems overkill to generate this string array
|
||||
nsTArray<nsString> linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(aRel, linkTypes);
|
||||
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(aRel);
|
||||
|
||||
// The link relation may apply to a different resource, specified
|
||||
// in the anchor parameter. For the link relations supported so far,
|
||||
@ -831,22 +829,22 @@ nsContentSink::ProcessLink(nsIContent* aElement,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
|
||||
bool hasPrefetch = linkTypes & PREFETCH;
|
||||
// prefetch href if relation is "next" or "prefetch"
|
||||
if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
|
||||
if (hasPrefetch || (linkTypes & NEXT)) {
|
||||
PrefetchHref(aHref, aElement, hasPrefetch);
|
||||
}
|
||||
|
||||
if ((!aHref.IsEmpty()) && linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
|
||||
if (!aHref.IsEmpty() && (linkTypes & DNS_PREFETCH)) {
|
||||
PrefetchDNS(aHref);
|
||||
}
|
||||
|
||||
// is it a stylesheet link?
|
||||
if (!linkTypes.Contains(NS_LITERAL_STRING("stylesheet"))) {
|
||||
if (!(linkTypes & STYLESHEET)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool isAlternate = linkTypes.Contains(NS_LITERAL_STRING("alternate"));
|
||||
bool isAlternate = linkTypes & ALTERNATE;
|
||||
return ProcessStyleLink(aElement, aHref, isAlternate, aTitle, aType,
|
||||
aMedia);
|
||||
}
|
||||
|
@ -1782,31 +1782,38 @@ IdentifierMapEntryTraverse(nsIdentifierMapEntry *aEntry, void *aArg)
|
||||
}
|
||||
|
||||
static const char* kNSURIs[] = {
|
||||
" ([none])",
|
||||
" (xmlns)",
|
||||
" (xml)",
|
||||
" (xhtml)",
|
||||
" (XLink)",
|
||||
" (XSLT)",
|
||||
" (XBL)",
|
||||
" (MathML)",
|
||||
" (RDF)",
|
||||
" (XUL)"
|
||||
"([none])",
|
||||
"(xmlns)",
|
||||
"(xml)",
|
||||
"(xhtml)",
|
||||
"(XLink)",
|
||||
"(XSLT)",
|
||||
"(XBL)",
|
||||
"(MathML)",
|
||||
"(RDF)",
|
||||
"(XUL)"
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
if (NS_UNLIKELY(cb.WantDebugInfo())) {
|
||||
char name[512];
|
||||
nsCAutoString loadedAsData;
|
||||
if (tmp->IsLoadedAsData()) {
|
||||
loadedAsData.AssignLiteral("data");
|
||||
} else {
|
||||
loadedAsData.AssignLiteral("normal");
|
||||
}
|
||||
PRUint32 nsid = tmp->GetDefaultNamespaceID();
|
||||
nsCAutoString uri;
|
||||
if (tmp->mDocumentURI)
|
||||
tmp->mDocumentURI->GetSpec(uri);
|
||||
if (nsid < ArrayLength(kNSURIs)) {
|
||||
PR_snprintf(name, sizeof(name), "nsDocument%s %s", kNSURIs[nsid],
|
||||
uri.get());
|
||||
PR_snprintf(name, sizeof(name), "nsDocument %s %s %s",
|
||||
loadedAsData.get(), kNSURIs[nsid], uri.get());
|
||||
}
|
||||
else {
|
||||
PR_snprintf(name, sizeof(name), "nsDocument %s", uri.get());
|
||||
PR_snprintf(name, sizeof(name), "nsDocument %s %s",
|
||||
loadedAsData.get(), uri.get());
|
||||
}
|
||||
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsDocument), name);
|
||||
}
|
||||
@ -8428,7 +8435,7 @@ nsIDocument::SizeOf() const
|
||||
}
|
||||
|
||||
static void
|
||||
DispatchFullScreenChange(nsINode* aTarget)
|
||||
DispatchFullScreenChange(nsIDocument* aTarget)
|
||||
{
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(aTarget,
|
||||
@ -8652,7 +8659,7 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
||||
// element, and the full-screen-ancestor styles on ancestors of the element
|
||||
// in this document.
|
||||
if (SetFullScreenState(aElement, true)) {
|
||||
DispatchFullScreenChange(aElement);
|
||||
DispatchFullScreenChange(aElement->OwnerDoc());
|
||||
}
|
||||
|
||||
// Propagate up the document hierarchy, setting the full-screen element as
|
||||
@ -8665,7 +8672,7 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
||||
while ((parent = child->GetParentDocument())) {
|
||||
Element* element = parent->FindContentForSubDocument(child)->AsElement();
|
||||
if (::SetFullScreenState(parent, element, true)) {
|
||||
DispatchFullScreenChange(element);
|
||||
DispatchFullScreenChange(element->OwnerDoc());
|
||||
}
|
||||
child = parent;
|
||||
}
|
||||
|
@ -131,6 +131,8 @@ public:
|
||||
ViewConfig aConfig = ViewConfig())
|
||||
: mViewportSize(0, 0)
|
||||
, mContentSize(0, 0)
|
||||
, mParentScaleX(1.0)
|
||||
, mParentScaleY(1.0)
|
||||
, mFrameLoader(aFrameLoader)
|
||||
, mScrollId(aScrollId)
|
||||
, mConfig(aConfig)
|
||||
@ -150,6 +152,8 @@ public:
|
||||
|
||||
nsSize mViewportSize;
|
||||
nsSize mContentSize;
|
||||
float mParentScaleX;
|
||||
float mParentScaleY;
|
||||
|
||||
nsFrameLoader* mFrameLoader; // WEAK
|
||||
|
||||
|
@ -107,6 +107,7 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#endif
|
||||
|
||||
class nsAsyncInstantiateEvent : public nsRunnable {
|
||||
@ -1066,11 +1067,7 @@ nsObjectLoadingContent::ObjectState() const
|
||||
case eType_Image:
|
||||
return ImageState();
|
||||
case eType_Plugin:
|
||||
#ifdef ANDROID
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content)
|
||||
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
|
||||
#endif
|
||||
case eType_Document:
|
||||
case eType_Document:
|
||||
// These are OK. If documents start to load successfully, they display
|
||||
// something, and are thus not broken in this sense. The same goes for
|
||||
// plugins.
|
||||
@ -1966,8 +1963,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
||||
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content)
|
||||
return ePluginClickToPlay;
|
||||
// if plugins are disabled, don't show the click to play message
|
||||
if (!mozilla::Preferences::GetBool("plugin.disable", false) &&
|
||||
XRE_GetProcessType() == GeckoProcessType_Content)
|
||||
return ePluginClickToPlay;
|
||||
#endif
|
||||
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
||||
|
@ -153,24 +153,40 @@ nsStyleLinkElement::SetLineNumber(PRUint32 aLineNumber)
|
||||
mLineNumber = aLineNumber;
|
||||
}
|
||||
|
||||
void nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes,
|
||||
nsTArray<nsString>& aResult)
|
||||
PRUint32 ToLinkMask(const nsAString& aLink)
|
||||
{
|
||||
if (aLink.EqualsLiteral("prefetch"))
|
||||
return PREFETCH;
|
||||
else if (aLink.EqualsLiteral("dns-prefetch"))
|
||||
return DNS_PREFETCH;
|
||||
else if (aLink.EqualsLiteral("stylesheet"))
|
||||
return STYLESHEET;
|
||||
else if (aLink.EqualsLiteral("next"))
|
||||
return NEXT;
|
||||
else if (aLink.EqualsLiteral("alternate"))
|
||||
return ALTERNATE;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
||||
{
|
||||
PRUint32 linkMask = 0;
|
||||
nsAString::const_iterator start, done;
|
||||
aTypes.BeginReading(start);
|
||||
aTypes.EndReading(done);
|
||||
if (start == done)
|
||||
return;
|
||||
return linkMask;
|
||||
|
||||
nsAString::const_iterator current(start);
|
||||
bool inString = !nsCRT::IsAsciiSpace(*current);
|
||||
nsAutoString subString;
|
||||
|
||||
|
||||
while (current != done) {
|
||||
if (nsCRT::IsAsciiSpace(*current)) {
|
||||
if (inString) {
|
||||
ToLowerCase(Substring(start, current), subString);
|
||||
aResult.AppendElement(subString);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
inString = false;
|
||||
}
|
||||
}
|
||||
@ -184,8 +200,9 @@ void nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes,
|
||||
}
|
||||
if (inString) {
|
||||
ToLowerCase(Substring(start, current), subString);
|
||||
aResult.AppendElement(subString);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
}
|
||||
return linkMask;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -53,6 +53,12 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#define PREFETCH 0x00000001
|
||||
#define DNS_PREFETCH 0x00000002
|
||||
#define STYLESHEET 0x00000004
|
||||
#define NEXT 0x00000008
|
||||
#define ALTERNATE 0x00000010
|
||||
|
||||
class nsIDocument;
|
||||
|
||||
class nsStyleLinkElement : public nsIDOMLinkStyle,
|
||||
@ -80,8 +86,8 @@ public:
|
||||
virtual void OverrideBaseURI(nsIURI* aNewBaseURI);
|
||||
virtual void SetLineNumber(PRUint32 aLineNumber);
|
||||
|
||||
static void ParseLinkTypes(const nsAString& aTypes, nsTArray<nsString>& aResult);
|
||||
|
||||
static PRUint32 ParseLinkTypes(const nsAString& aTypes);
|
||||
|
||||
void UpdateStyleSheetInternal() { UpdateStyleSheetInternal(nsnull); }
|
||||
protected:
|
||||
/**
|
||||
|
@ -103,6 +103,7 @@
|
||||
#include "nsStringBuffer.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsIFileChannel.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -1485,6 +1486,8 @@ nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
|
||||
// No optional arguments were passed in. Default async to true.
|
||||
async = true;
|
||||
}
|
||||
Telemetry::Accumulate(Telemetry::XMLHTTPREQUEST_ASYNC_OR_SYNC,
|
||||
async ? 0 : 1);
|
||||
|
||||
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
|
@ -301,16 +301,17 @@ WebGLContext::WebGLContext()
|
||||
|
||||
mContextLost = false;
|
||||
mAllowRestore = false;
|
||||
mRobustnessTimerRunning = false;
|
||||
mDrawSinceRobustnessTimerSet = false;
|
||||
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
}
|
||||
|
||||
WebGLContext::~WebGLContext()
|
||||
{
|
||||
DestroyResourcesAndContext();
|
||||
WebGLMemoryReporter::RemoveWebGLContext(this);
|
||||
if (mContextRestorer) {
|
||||
mContextRestorer->Cancel();
|
||||
mContextRestorer = NULL;
|
||||
}
|
||||
TerminateRobustnessTimer();
|
||||
mContextRestorer = nsnull;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
@ -709,6 +710,8 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
mResetLayer = true;
|
||||
mOptionsFrozen = true;
|
||||
|
||||
mHasRobustness = gl->HasRobustness();
|
||||
|
||||
// increment the generation number
|
||||
++mGeneration;
|
||||
|
||||
@ -1147,13 +1150,8 @@ WebGLContext::EnsureBackbufferClearedAsNeeded()
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::Notify(nsITimer* timer)
|
||||
{
|
||||
TerminateRobustnessTimer();
|
||||
MaybeRestoreContext();
|
||||
|
||||
if (mContextRestorer) {
|
||||
mContextRestorer->Cancel();
|
||||
mContextRestorer = NULL;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1163,6 +1161,7 @@ WebGLContext::MaybeRestoreContext()
|
||||
if (mContextLost || mAllowRestore)
|
||||
return;
|
||||
|
||||
gl->MakeCurrent();
|
||||
GLContext::ContextResetARB resetStatus =
|
||||
(GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
|
||||
|
||||
@ -1174,6 +1173,11 @@ WebGLContext::MaybeRestoreContext()
|
||||
|
||||
switch (resetStatus) {
|
||||
case GLContext::CONTEXT_NO_ERROR:
|
||||
// If there has been activity since the timer was set, it's possible
|
||||
// that we did or are going to miss something, so clear this flag and
|
||||
// run it again some time later.
|
||||
if (mDrawSinceRobustnessTimerSet)
|
||||
SetupRobustnessTimer();
|
||||
return;
|
||||
case GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB:
|
||||
NS_WARNING("WebGL content on the page caused the graphics card to reset; not restoring the context");
|
||||
@ -1191,10 +1195,7 @@ WebGLContext::MaybeRestoreContext()
|
||||
void
|
||||
WebGLContext::ForceLoseContext()
|
||||
{
|
||||
if (mContextRestorer) {
|
||||
mContextRestorer->Cancel();
|
||||
mContextRestorer = NULL;
|
||||
}
|
||||
TerminateRobustnessTimer();
|
||||
|
||||
mWebGLError = LOCAL_GL_CONTEXT_LOST;
|
||||
|
||||
|
@ -449,17 +449,30 @@ public:
|
||||
// Sets up the GL_ARB_robustness timer if it isn't already, so that if the
|
||||
// driver gets restarted, the context may get reset with it.
|
||||
void SetupRobustnessTimer() {
|
||||
if (mContextLost)
|
||||
if (mContextLost || !mHasRobustness)
|
||||
return;
|
||||
|
||||
if (!mContextRestorer)
|
||||
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
// If the timer was already running, don't restart it here. Instead,
|
||||
// wait until the previous call is done, then fire it one more time.
|
||||
// This is an optimization to prevent unnecessary cross-communication
|
||||
// between threads.
|
||||
if (mRobustnessTimerRunning) {
|
||||
mDrawSinceRobustnessTimerSet = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// As long as there's still activity, we reset the timer each time that
|
||||
// this function gets called.
|
||||
mContextRestorer->InitWithCallback(static_cast<nsITimerCallback*>(this),
|
||||
PR_MillisecondsToInterval(1000),
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
mRobustnessTimerRunning = true;
|
||||
mDrawSinceRobustnessTimerSet = false;
|
||||
}
|
||||
|
||||
void TerminateRobustnessTimer() {
|
||||
if (mRobustnessTimerRunning) {
|
||||
mContextRestorer->Cancel();
|
||||
mRobustnessTimerRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -504,6 +517,7 @@ protected:
|
||||
bool mOptionsFrozen;
|
||||
bool mMinCapability;
|
||||
bool mDisableExtensions;
|
||||
bool mHasRobustness;
|
||||
|
||||
WebGLuint mActiveTexture;
|
||||
WebGLenum mWebGLError;
|
||||
@ -723,6 +737,8 @@ protected:
|
||||
nsCOMPtr<nsITimer> mContextRestorer;
|
||||
bool mContextLost;
|
||||
bool mAllowRestore;
|
||||
bool mRobustnessTimerRunning;
|
||||
bool mDrawSinceRobustnessTimerSet;
|
||||
|
||||
public:
|
||||
// console logging helpers
|
||||
|
@ -1622,8 +1622,6 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
|
||||
if (!ValidateBuffers(&maxAllowedCount, "drawArrays"))
|
||||
return NS_OK;
|
||||
|
||||
SetupRobustnessTimer();
|
||||
|
||||
CheckedInt32 checked_firstPlusCount = CheckedInt32(first) + count;
|
||||
|
||||
if (!checked_firstPlusCount.valid())
|
||||
@ -1645,6 +1643,7 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
|
||||
if (!DoFakeVertexAttrib0(checked_firstPlusCount.value()))
|
||||
return NS_OK;
|
||||
|
||||
SetupRobustnessTimer();
|
||||
gl->fDrawArrays(mode, first, count);
|
||||
|
||||
UndoFakeVertexAttrib0();
|
||||
@ -1675,8 +1674,6 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
SetupRobustnessTimer();
|
||||
|
||||
CheckedUint32 checked_byteCount;
|
||||
|
||||
if (type == LOCAL_GL_UNSIGNED_SHORT) {
|
||||
@ -1757,6 +1754,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
|
||||
if (!DoFakeVertexAttrib0(checked_maxIndexPlusOne.value()))
|
||||
return NS_OK;
|
||||
|
||||
SetupRobustnessTimer();
|
||||
gl->fDrawElements(mode, count, type, (GLvoid*) (byteOffset));
|
||||
|
||||
UndoFakeVertexAttrib0();
|
||||
|
@ -61,7 +61,7 @@ NS_IMETHODIMP
|
||||
WebGLExtensionLoseContext::LoseContext()
|
||||
{
|
||||
if (!mContext->LoseContext())
|
||||
return mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
|
||||
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -70,7 +70,7 @@ NS_IMETHODIMP
|
||||
WebGLExtensionLoseContext::RestoreContext()
|
||||
{
|
||||
if (!mContext->RestoreContext())
|
||||
return mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
|
||||
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -116,6 +116,7 @@
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "gfxWindowsPlatform.h"
|
||||
@ -989,9 +990,10 @@ nsresult
|
||||
NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
|
||||
if ((gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
|
||||
gfxWindowsPlatform::RENDER_DIRECT2D ||
|
||||
!gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
|
||||
!gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) &&
|
||||
!Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
#elif !defined(XP_MACOSX) && !defined(ANDROID)
|
||||
@ -3648,8 +3650,8 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
|
||||
return res.mIsStillLoading ? NS_OK : NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Ignore nsnull cairo surfaces! See bug 666312.
|
||||
if (!res.mSurface->CairoSurface()) {
|
||||
// Ignore cairo surfaces that are bad! See bug 666312.
|
||||
if (res.mSurface->CairoStatus()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,18 @@ function IsAzureEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
function IsAzureSkia() {
|
||||
var enabled = false;
|
||||
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var backend = Components.classes["@mozilla.org/gfx/info;1"].getService(Components.interfaces.nsIGfxInfo).getInfo().AzureBackend;
|
||||
enabled = (backend == "skia");
|
||||
} catch (e) { }
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
</script>
|
||||
<!-- Includes all the tests in the content/canvas/tests except for test_bug397524.html -->
|
||||
|
||||
@ -11985,7 +11997,7 @@ isPixel(ctx, 65,21, 0,255,0,255, 0);
|
||||
isPixel(ctx, 72,28, 0,255,0,255, 0);
|
||||
isPixel(ctx, 73,27, 0,255,0,255, 0);
|
||||
isPixel(ctx, 78,36, 0,255,0,255, 0);
|
||||
isPixel(ctx, 79,35, 0,255,0,255, 0);
|
||||
isPixel(ctx, 79,35, 0,255,0,255, IsAzureSkia() ? 1 : 0);
|
||||
isPixel(ctx, 80,44, 0,255,0,255, 0);
|
||||
isPixel(ctx, 80,45, 0,255,0,255, 0);
|
||||
isPixel(ctx, 80,46, 0,255,0,255, 0);
|
||||
@ -12032,11 +12044,11 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
isPixel(ctx, 55,19, 0,255,0,255, 0);
|
||||
isPixel(ctx, 55,20, 0,255,0,255, 0);
|
||||
isPixel(ctx, 55,21, 0,255,0,255, 0);
|
||||
isPixel(ctx, 64,22, 0,255,0,255, 0);
|
||||
isPixel(ctx, 64,22, 0,255,0,255, IsAzureSkia() ? 1 : 0);
|
||||
isPixel(ctx, 65,21, 0,255,0,255, 0);
|
||||
isPixel(ctx, 72,28, 0,255,0,255, 0);
|
||||
isPixel(ctx, 73,27, 0,255,0,255, 0);
|
||||
isPixel(ctx, 78,36, 0,255,0,255, 0);
|
||||
isPixel(ctx, 73,27, 0,255,0,255, IsAzureSkia() ? 1 : 0);
|
||||
isPixel(ctx, 78,36, 0,255,0,255, IsAzureSkia() ? 1 : 0);
|
||||
isPixel(ctx, 79,35, 0,255,0,255, 0);
|
||||
isPixel(ctx, 80,44, 0,255,0,255, 0);
|
||||
isPixel(ctx, 80,45, 0,255,0,255, 0);
|
||||
@ -14339,8 +14351,11 @@ ctx.lineTo(50, 25);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
|
||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
} else {
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -14412,7 +14427,11 @@ ctx.moveTo(50, 25);
|
||||
ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
|
||||
ctx.stroke();
|
||||
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
} else {
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -14445,8 +14464,11 @@ ctx.moveTo(50, 25);
|
||||
ctx.lineTo(50, 25);
|
||||
ctx.stroke();
|
||||
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
|
||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
} else {
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -14479,8 +14501,11 @@ ctx.stroke();
|
||||
|
||||
ctx.strokeRect(50, 25, 0, 0);
|
||||
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
|
||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
} else {
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -19185,7 +19210,7 @@ isPixel(ctx, 21,11, 0,255,0,255, 0);
|
||||
isPixel(ctx, 79,11, 0,255,0,255, 0);
|
||||
isPixel(ctx, 21,39, 0,255,0,255, 0);
|
||||
isPixel(ctx, 79,39, 0,255,0,255, 0);
|
||||
isPixel(ctx, 39,19, 0,255,0,255, 0);
|
||||
isPixel(ctx, 39,19, 0,255,0,255, IsAzureSkia() ? 1 : 0);
|
||||
isPixel(ctx, 61,19, 0,255,0,255, 0);
|
||||
isPixel(ctx, 39,31, 0,255,0,255, 0);
|
||||
isPixel(ctx, 61,31, 0,255,0,255, 0);
|
||||
@ -19393,7 +19418,7 @@ isPixel(ctx, 21,11, 0,255,0,255, 0);
|
||||
isPixel(ctx, 79,11, 0,255,0,255, 0);
|
||||
isPixel(ctx, 21,39, 0,255,0,255, 0);
|
||||
isPixel(ctx, 79,39, 0,255,0,255, 0);
|
||||
isPixel(ctx, 39,19, 0,255,0,255, 0);
|
||||
isPixel(ctx, 39,19, 0,255,0,255, IsAzureSkia() ? 1 : 0);
|
||||
isPixel(ctx, 61,19, 0,255,0,255, 0);
|
||||
isPixel(ctx, 39,31, 0,255,0,255, 0);
|
||||
isPixel(ctx, 61,31, 0,255,0,255, 0);
|
||||
|
@ -134,10 +134,9 @@ function testFailedRender(msg, ref, test, width, height)
|
||||
|
||||
testFailed(msg);
|
||||
|
||||
var data = 'REFTEST TEST-KNOWN-FAIL | ' + msg + ' | image comparison (==)\n' +
|
||||
var data = 'REFTEST TEST-DEBUG-INFO | ' + msg + ' | image comparison (==)\n' +
|
||||
'REFTEST IMAGE 1 (TEST): ' + testData + '\n' +
|
||||
'REFTEST IMAGE 2 (REFERENCE): ' + refData;
|
||||
dump('The following information is for debugging purposes only. It will always print TEST-KNOWN-FAIL, even if it is unexpected.');
|
||||
dump('FAIL: ' + data + '\n');
|
||||
dump('To view the differences between these image renderings, go to the following link: https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer.xhtml#log=' +
|
||||
encodeURIComponent(encodeURIComponent(data)) + '\n');
|
||||
|
@ -307,9 +307,8 @@ nsHTMLLinkElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
bool dropSheet = false;
|
||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::rel &&
|
||||
GetStyleSheet()) {
|
||||
nsAutoTArray<nsString, 4> linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(aValue, linkTypes);
|
||||
dropSheet = !linkTypes.Contains(NS_LITERAL_STRING("stylesheet"));
|
||||
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(aValue);
|
||||
dropSheet = !(linkTypes & STYLESHEET);
|
||||
}
|
||||
|
||||
UpdateStyleSheetInternal(nsnull,
|
||||
@ -413,11 +412,10 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
|
||||
*aIsAlternate = false;
|
||||
|
||||
nsAutoString rel;
|
||||
nsAutoTArray<nsString, 4> linkTypes;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
|
||||
nsStyleLinkElement::ParseLinkTypes(rel, linkTypes);
|
||||
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
|
||||
// Is it a stylesheet link?
|
||||
if (!linkTypes.Contains(NS_LITERAL_STRING("stylesheet"))) {
|
||||
if (!(linkTypes & STYLESHEET)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -427,7 +425,7 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
|
||||
aTitle.Assign(title);
|
||||
|
||||
// If alternate, does it have title?
|
||||
if (linkTypes.Contains(NS_LITERAL_STRING("alternate"))) {
|
||||
if (linkTypes & ALTERNATE) {
|
||||
if (aTitle.IsEmpty()) { // alternates must have title
|
||||
return;
|
||||
} else {
|
||||
|
@ -65,7 +65,7 @@ function fullScreenChange(event) {
|
||||
switch (fullScreenChangeCount) {
|
||||
case 0: {
|
||||
ok(document.mozFullScreen, "Should be in full-screen mode (first time)");
|
||||
is(event.target, fullScreenElement(), "Event target should be full-screen element");
|
||||
is(event.target, document, "Event target should be full-screen document #1");
|
||||
is(document.mozFullScreenElement, fullScreenElement(),
|
||||
"Full-screen element should be div element.");
|
||||
ok(document.mozFullScreenElement.mozMatchesSelector(":-moz-full-screen"),
|
||||
@ -83,7 +83,7 @@ function fullScreenChange(event) {
|
||||
}
|
||||
case 1: {
|
||||
ok(!document.mozFullScreen, "Should have left full-screen mode (first time)");
|
||||
is(event.target, document, "Event target should be document when we exit via removing from doc");
|
||||
is(event.target, document, "Event target should be full-screen document #2");
|
||||
is(document.mozFullScreenElement, null, "Full-screen element should be null.");
|
||||
iframe = document.createElement("iframe");
|
||||
iframe.mozAllowFullScreen = true;
|
||||
@ -93,8 +93,7 @@ function fullScreenChange(event) {
|
||||
}
|
||||
case 2: {
|
||||
ok(document.mozFullScreen, "Should be back in full-screen mode (second time)");
|
||||
is(event.target, iframe,
|
||||
"Event target should be full-screen element container");
|
||||
is(event.target, document, "Event target should be full-screen document #3");
|
||||
is(document.mozFullScreenElement, iframe,
|
||||
"Full-screen element should be iframe element.");
|
||||
|
||||
@ -126,8 +125,7 @@ function fullScreenChange(event) {
|
||||
}
|
||||
case 3: {
|
||||
ok(!document.mozFullScreen, "Should be back in non-full-screen mode (second time)");
|
||||
is(event.target, document,
|
||||
"Event target should be full-screen element container");
|
||||
is(event.target, document, "Event target should be full-screen document #4");
|
||||
is(document.mozFullScreenElement, null, "Full-screen element should be null.");
|
||||
document.body.removeChild(iframe);
|
||||
iframe = null;
|
||||
@ -155,7 +153,7 @@ function fullScreenChange(event) {
|
||||
}
|
||||
case 4: {
|
||||
ok(document.mozFullScreen, "Should still be in full-screen mode (third time)");
|
||||
is(event.target, inDocElement, "Event target should be inDocElement");
|
||||
is(event.target, document, "Event target should be full-screen document #5");
|
||||
ok(fullScreenErrorRun, "Should have run fullscreenerror handler from previous case.");
|
||||
is(document.mozFullScreenElement, inDocElement,
|
||||
"FSE should be inDocElement.");
|
||||
|
@ -2644,18 +2644,16 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
nsAutoString relVal;
|
||||
element->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
|
||||
if (!relVal.IsEmpty()) {
|
||||
// XXX seems overkill to generate this string array
|
||||
nsAutoTArray<nsString, 4> linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
|
||||
bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
|
||||
if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
|
||||
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
|
||||
bool hasPrefetch = linkTypes & PREFETCH;
|
||||
if (hasPrefetch || (linkTypes & NEXT)) {
|
||||
nsAutoString hrefVal;
|
||||
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
||||
if (!hrefVal.IsEmpty()) {
|
||||
PrefetchHref(hrefVal, element, hasPrefetch);
|
||||
}
|
||||
}
|
||||
if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
|
||||
if (linkTypes & DNS_PREFETCH) {
|
||||
nsAutoString hrefVal;
|
||||
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
||||
if (!hrefVal.IsEmpty()) {
|
||||
|
@ -950,6 +950,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
|
||||
// Set the parser as the stream listener for the document loader...
|
||||
if (mParser) {
|
||||
rv = NS_OK;
|
||||
nsCOMPtr<nsIStreamListener> listener = mParser->GetStreamListener();
|
||||
listener.forget(aDocListener);
|
||||
|
||||
|
@ -90,13 +90,12 @@ public:
|
||||
// nsScriptElement
|
||||
virtual bool HasScriptContent();
|
||||
|
||||
// nsSVGElement specializations:
|
||||
virtual void DidChangeString(PRUint8 aAttrEnum);
|
||||
|
||||
// nsIContent specializations:
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, bool aNotify);
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
@ -252,16 +251,6 @@ nsSVGScriptElement::HasScriptContent()
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGElement methods
|
||||
|
||||
void
|
||||
nsSVGScriptElement::DidChangeString(PRUint8 aAttrEnum)
|
||||
{
|
||||
nsSVGScriptElementBase::DidChangeString(aAttrEnum);
|
||||
|
||||
if (aAttrEnum == HREF) {
|
||||
MaybeProcessScript();
|
||||
}
|
||||
}
|
||||
|
||||
nsSVGElement::StringAttributesInfo
|
||||
nsSVGScriptElement::GetStringInfo()
|
||||
{
|
||||
@ -289,3 +278,13 @@ nsSVGScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGScriptElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, bool aNotify)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) {
|
||||
MaybeProcessScript();
|
||||
}
|
||||
return nsSVGScriptElementBase::AfterSetAttr(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
@ -646,18 +646,16 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|
||||
nsAutoString relVal;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
|
||||
if (!relVal.IsEmpty()) {
|
||||
// XXX seems overkill to generate this string array
|
||||
nsAutoTArray<nsString, 4> linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
|
||||
bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
|
||||
if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
|
||||
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
|
||||
bool hasPrefetch = linkTypes & PREFETCH;
|
||||
if (hasPrefetch || (linkTypes & NEXT)) {
|
||||
nsAutoString hrefVal;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
||||
if (!hrefVal.IsEmpty()) {
|
||||
PrefetchHref(hrefVal, aContent, hasPrefetch);
|
||||
}
|
||||
}
|
||||
if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
|
||||
if (linkTypes & DNS_PREFETCH) {
|
||||
nsAutoString hrefVal;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
||||
if (!hrefVal.IsEmpty()) {
|
||||
|
@ -106,10 +106,4 @@ public:
|
||||
static double toDouble(const nsAString& aStr);
|
||||
};
|
||||
|
||||
// XXX These should go away eventually.
|
||||
#define TxObject txObject
|
||||
typedef txDouble Double;
|
||||
|
||||
// XXX
|
||||
|
||||
#endif
|
||||
|
@ -50,20 +50,20 @@
|
||||
*/
|
||||
|
||||
//-- Initialize Double related constants
|
||||
const dpun Double::NaN = DOUBLE_NaN;
|
||||
const dpun txDouble::NaN = DOUBLE_NaN;
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
const dpun Double::POSITIVE_INFINITY = {{DOUBLE_HI32_EXPMASK, 0}};
|
||||
const dpun Double::NEGATIVE_INFINITY = {{DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT, 0}};
|
||||
const dpun txDouble::POSITIVE_INFINITY = {{DOUBLE_HI32_EXPMASK, 0}};
|
||||
const dpun txDouble::NEGATIVE_INFINITY = {{DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT, 0}};
|
||||
#else
|
||||
const dpun Double::POSITIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK}};
|
||||
const dpun Double::NEGATIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT}};
|
||||
const dpun txDouble::POSITIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK}};
|
||||
const dpun txDouble::NEGATIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT}};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determines whether the given double represents positive or negative
|
||||
* inifinity
|
||||
*/
|
||||
bool Double::isInfinite(double aDbl)
|
||||
bool txDouble::isInfinite(double aDbl)
|
||||
{
|
||||
return ((DOUBLE_HI32(aDbl) & ~DOUBLE_HI32_SIGNBIT) == DOUBLE_HI32_EXPMASK &&
|
||||
!DOUBLE_LO32(aDbl));
|
||||
@ -72,7 +72,7 @@ bool Double::isInfinite(double aDbl)
|
||||
/*
|
||||
* Determines whether the given double is NaN
|
||||
*/
|
||||
bool Double::isNaN(double aDbl)
|
||||
bool txDouble::isNaN(double aDbl)
|
||||
{
|
||||
return DOUBLE_IS_NaN(aDbl);
|
||||
}
|
||||
@ -80,7 +80,7 @@ bool Double::isNaN(double aDbl)
|
||||
/*
|
||||
* Determines whether the given double is negative
|
||||
*/
|
||||
bool Double::isNeg(double aDbl)
|
||||
bool txDouble::isNeg(double aDbl)
|
||||
{
|
||||
return (DOUBLE_HI32(aDbl) & DOUBLE_HI32_SIGNBIT) != 0;
|
||||
}
|
||||
@ -170,7 +170,7 @@ public:
|
||||
{
|
||||
if (mState == eIllegal || mBuffer.IsEmpty() ||
|
||||
(mBuffer.Length() == 1 && mBuffer[0] == '.')) {
|
||||
return Double::NaN;
|
||||
return txDouble::NaN;
|
||||
}
|
||||
return mSign*PR_strtod(mBuffer.get(), 0);
|
||||
}
|
||||
@ -189,7 +189,7 @@ private:
|
||||
} mSign;
|
||||
};
|
||||
|
||||
double Double::toDouble(const nsAString& aSrc)
|
||||
double txDouble::toDouble(const nsAString& aSrc)
|
||||
{
|
||||
txStringToDouble sink;
|
||||
nsAString::const_iterator fromBegin, fromEnd;
|
||||
@ -202,7 +202,7 @@ double Double::toDouble(const nsAString& aSrc)
|
||||
* The result into the destination String.
|
||||
* @return the given dest string
|
||||
*/
|
||||
void Double::toString(double aValue, nsAString& aDest)
|
||||
void txDouble::toString(double aValue, nsAString& aDest)
|
||||
{
|
||||
|
||||
// check for special cases
|
||||
|
@ -46,7 +46,7 @@ class txListIterator;
|
||||
/**
|
||||
* Represents an ordered list of Object pointers. Modeled after a Java 2 List.
|
||||
**/
|
||||
class txList : public TxObject {
|
||||
class txList : public txObject {
|
||||
|
||||
friend class txListIterator;
|
||||
|
||||
|
@ -82,7 +82,7 @@ class ProcessingInstruction;
|
||||
// Abstract Class defining the interface for a Node. See NodeDefinition below
|
||||
// for the actual implementation of the WC3 node.
|
||||
//
|
||||
class Node : public TxObject
|
||||
class Node : public txObject
|
||||
{
|
||||
public:
|
||||
//Node type constants
|
||||
|
@ -396,8 +396,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// check for NaN or +/-Inf
|
||||
if (Double::isNaN(start) ||
|
||||
Double::isInfinite(start) ||
|
||||
if (txDouble::isNaN(start) ||
|
||||
txDouble::isInfinite(start) ||
|
||||
start >= src.Length() + 0.5) {
|
||||
aContext->recycler()->getEmptyStringResult(aResult);
|
||||
|
||||
@ -412,7 +412,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
end += start;
|
||||
if (Double::isNaN(end) || end < 0) {
|
||||
if (txDouble::isNaN(end) || end < 0) {
|
||||
aContext->recycler()->getEmptyStringResult(aResult);
|
||||
|
||||
return NS_OK;
|
||||
@ -546,7 +546,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
nsAutoString resultStr;
|
||||
txXPathNodeUtils::appendNodeValue(aContext->getContextNode(),
|
||||
resultStr);
|
||||
res = Double::toDouble(resultStr);
|
||||
res = txDouble::toDouble(resultStr);
|
||||
}
|
||||
return aContext->recycler()->getNumberResult(res, aResult);
|
||||
}
|
||||
@ -556,8 +556,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
rv = evaluateToNumber(mParams[0], aContext, &dbl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
|
||||
if (Double::isNeg(dbl) && dbl >= -0.5) {
|
||||
if (!txDouble::isNaN(dbl) && !txDouble::isInfinite(dbl)) {
|
||||
if (txDouble::isNeg(dbl) && dbl >= -0.5) {
|
||||
dbl *= 0;
|
||||
}
|
||||
else {
|
||||
@ -573,9 +573,9 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
rv = evaluateToNumber(mParams[0], aContext, &dbl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!Double::isNaN(dbl) &&
|
||||
!Double::isInfinite(dbl) &&
|
||||
!(dbl == 0 && Double::isNeg(dbl))) {
|
||||
if (!txDouble::isNaN(dbl) &&
|
||||
!txDouble::isInfinite(dbl) &&
|
||||
!(dbl == 0 && txDouble::isNeg(dbl))) {
|
||||
dbl = floor(dbl);
|
||||
}
|
||||
|
||||
@ -587,8 +587,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
rv = evaluateToNumber(mParams[0], aContext, &dbl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
|
||||
if (Double::isNeg(dbl) && dbl > -1) {
|
||||
if (!txDouble::isNaN(dbl) && !txDouble::isInfinite(dbl)) {
|
||||
if (txDouble::isNeg(dbl) && dbl > -1) {
|
||||
dbl *= 0;
|
||||
}
|
||||
else {
|
||||
@ -610,7 +610,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
for (i = 0; i < nodes->size(); ++i) {
|
||||
nsAutoString resultStr;
|
||||
txXPathNodeUtils::appendNodeValue(nodes->get(i), resultStr);
|
||||
res += Double::toDouble(resultStr);
|
||||
res += txDouble::toDouble(resultStr);
|
||||
}
|
||||
return aContext->recycler()->getNumberResult(res, aResult);
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext,
|
||||
break;
|
||||
case Token::NUMBER:
|
||||
{
|
||||
expr = new txLiteralExpr(Double::toDouble(tok->Value()));
|
||||
expr = new txLiteralExpr(txDouble::toDouble(tok->Value()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -103,7 +103,7 @@ txLiteralExpr::toString(nsAString& aStr)
|
||||
}
|
||||
case txAExprResult::NUMBER:
|
||||
{
|
||||
Double::toString(mValue->numberValue(), aStr);
|
||||
txDouble::toString(mValue->numberValue(), aStr);
|
||||
return;
|
||||
}
|
||||
case txAExprResult::STRING:
|
||||
|
@ -501,7 +501,7 @@ txNodeSet::numberValue()
|
||||
nsAutoString str;
|
||||
stringValue(str);
|
||||
|
||||
return Double::toDouble(str);
|
||||
return txDouble::toDouble(str);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -86,7 +86,7 @@ txNodeSetAdaptor::ItemAsNumber(PRUint32 aIndex, double *aResult)
|
||||
nsAutoString result;
|
||||
txXPathNodeUtils::appendNodeValue(NodeSet()->get(aIndex), result);
|
||||
|
||||
*aResult = Double::toDouble(result);
|
||||
*aResult = txDouble::toDouble(result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -70,16 +70,16 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
if (rightDbl == 0) {
|
||||
#if defined(XP_WIN)
|
||||
/* XXX MSVC miscompiles such that (NaN == 0) */
|
||||
if (Double::isNaN(rightDbl))
|
||||
result = Double::NaN;
|
||||
if (txDouble::isNaN(rightDbl))
|
||||
result = txDouble::NaN;
|
||||
else
|
||||
#endif
|
||||
if (leftDbl == 0 || Double::isNaN(leftDbl))
|
||||
result = Double::NaN;
|
||||
else if (Double::isNeg(leftDbl) ^ Double::isNeg(rightDbl))
|
||||
result = Double::NEGATIVE_INFINITY;
|
||||
if (leftDbl == 0 || txDouble::isNaN(leftDbl))
|
||||
result = txDouble::NaN;
|
||||
else if (txDouble::isNeg(leftDbl) ^ txDouble::isNeg(rightDbl))
|
||||
result = txDouble::NEGATIVE_INFINITY;
|
||||
else
|
||||
result = Double::POSITIVE_INFINITY;
|
||||
result = txDouble::POSITIVE_INFINITY;
|
||||
}
|
||||
else
|
||||
result = leftDbl / rightDbl;
|
||||
@ -87,12 +87,12 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
|
||||
case MODULUS:
|
||||
if (rightDbl == 0) {
|
||||
result = Double::NaN;
|
||||
result = txDouble::NaN;
|
||||
}
|
||||
else {
|
||||
#if defined(XP_WIN)
|
||||
/* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
|
||||
if (!Double::isInfinite(leftDbl) && Double::isInfinite(rightDbl))
|
||||
if (!txDouble::isInfinite(leftDbl) && txDouble::isInfinite(rightDbl))
|
||||
result = leftDbl;
|
||||
else
|
||||
#endif
|
||||
|
@ -67,7 +67,7 @@ short NumberResult::getResultType() {
|
||||
void
|
||||
NumberResult::stringValue(nsString& aResult)
|
||||
{
|
||||
Double::toString(value, aResult);
|
||||
txDouble::toString(value, aResult);
|
||||
}
|
||||
|
||||
const nsString*
|
||||
@ -80,7 +80,7 @@ bool NumberResult::booleanValue() {
|
||||
// OG+
|
||||
// As per the XPath spec, the boolean value of a number is true if and only if
|
||||
// it is neither positive 0 nor negative 0 nor NaN
|
||||
return (bool)(value != 0.0 && !Double::isNaN(value));
|
||||
return (bool)(value != 0.0 && !txDouble::isNaN(value));
|
||||
// OG-
|
||||
} //-- booleanValue
|
||||
|
||||
|
@ -84,6 +84,6 @@ bool StringResult::booleanValue() {
|
||||
} //-- booleanValue
|
||||
|
||||
double StringResult::numberValue() {
|
||||
return Double::toDouble(mValue);
|
||||
return txDouble::toDouble(mValue);
|
||||
} //-- numberValue
|
||||
|
||||
|
@ -58,7 +58,7 @@ double
|
||||
txUnionNodeTest::getDefaultPriority()
|
||||
{
|
||||
NS_ERROR("Don't call getDefaultPriority on txUnionPattern");
|
||||
return Double::NaN;
|
||||
return txDouble::NaN;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -611,7 +611,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
if (nodes->isEmpty()) {
|
||||
return aContext->recycler()->
|
||||
getNumberResult(Double::NaN, aResult);
|
||||
getNumberResult(txDouble::NaN, aResult);
|
||||
}
|
||||
|
||||
bool findMax = mType == MAX;
|
||||
@ -622,9 +622,9 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
for (i = 0; i < len; ++i) {
|
||||
nsAutoString str;
|
||||
txXPathNodeUtils::appendNodeValue(nodes->get(i), str);
|
||||
double val = Double::toDouble(str);
|
||||
if (Double::isNaN(val)) {
|
||||
res = Double::NaN;
|
||||
double val = txDouble::toDouble(str);
|
||||
if (txDouble::isNaN(val)) {
|
||||
res = txDouble::NaN;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -661,8 +661,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
nsAutoString str;
|
||||
const txXPathNode& node = nodes->get(i);
|
||||
txXPathNodeUtils::appendNodeValue(node, str);
|
||||
double val = Double::toDouble(str);
|
||||
if (Double::isNaN(val)) {
|
||||
double val = txDouble::toDouble(str);
|
||||
if (txDouble::isNaN(val)) {
|
||||
resultSet->clear();
|
||||
break;
|
||||
}
|
||||
|
@ -112,16 +112,16 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
}
|
||||
|
||||
// Special cases
|
||||
if (Double::isNaN(value)) {
|
||||
if (txDouble::isNaN(value)) {
|
||||
return aContext->recycler()->getStringResult(format->mNaN, aResult);
|
||||
}
|
||||
|
||||
if (value == Double::POSITIVE_INFINITY) {
|
||||
if (value == txDouble::POSITIVE_INFINITY) {
|
||||
return aContext->recycler()->getStringResult(format->mInfinity,
|
||||
aResult);
|
||||
}
|
||||
|
||||
if (value == Double::NEGATIVE_INFINITY) {
|
||||
if (value == txDouble::NEGATIVE_INFINITY) {
|
||||
nsAutoString res;
|
||||
res.Append(format->mMinusSign);
|
||||
res.Append(format->mInfinity);
|
||||
@ -143,7 +143,7 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
|
||||
// Get right subexpression
|
||||
inQuote = false;
|
||||
if (Double::isNeg(value)) {
|
||||
if (txDouble::isNeg(value)) {
|
||||
while (pos < formatLen &&
|
||||
(inQuote ||
|
||||
formatStr.CharAt(pos) != format->mPatternSeparator)) {
|
||||
|
@ -51,7 +51,7 @@
|
||||
class nsIAtom;
|
||||
class txExecutionState;
|
||||
|
||||
class txInstruction : public TxObject
|
||||
class txInstruction : public txObject
|
||||
{
|
||||
public:
|
||||
txInstruction()
|
||||
|
@ -180,8 +180,8 @@ txNodeSorter::sortNodeSet(txNodeSet* aNodes, txExecutionState* aEs,
|
||||
PRUint32 len = static_cast<PRUint32>(aNodes->size());
|
||||
|
||||
// Limit resource use to something sane.
|
||||
PRUint32 itemSize = sizeof(PRUint32) + mNKeys * sizeof(TxObject*);
|
||||
if (mNKeys > (PR_UINT32_MAX - sizeof(PRUint32)) / sizeof(TxObject*) ||
|
||||
PRUint32 itemSize = sizeof(PRUint32) + mNKeys * sizeof(txObject*);
|
||||
if (mNKeys > (PR_UINT32_MAX - sizeof(PRUint32)) / sizeof(txObject*) ||
|
||||
len >= PR_UINT32_MAX / itemSize) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -190,13 +190,13 @@ txNodeSorter::sortNodeSet(txNodeSet* aNodes, txExecutionState* aEs,
|
||||
NS_ENSURE_TRUE(mem, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
PRUint32* indexes = static_cast<PRUint32*>(mem);
|
||||
TxObject** sortValues = reinterpret_cast<TxObject**>(indexes + len);
|
||||
txObject** sortValues = reinterpret_cast<txObject**>(indexes + len);
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
indexes[i] = i;
|
||||
}
|
||||
memset(sortValues, 0, len * mNKeys * sizeof(TxObject*));
|
||||
memset(sortValues, 0, len * mNKeys * sizeof(txObject*));
|
||||
|
||||
// Sort the indexarray
|
||||
SortData sortData;
|
||||
@ -248,9 +248,9 @@ txNodeSorter::compareNodes(const void* aIndexA, const void* aIndexB,
|
||||
txListIterator iter(&sortData->mNodeSorter->mSortKeys);
|
||||
PRUint32 indexA = *static_cast<const PRUint32*>(aIndexA);
|
||||
PRUint32 indexB = *static_cast<const PRUint32*>(aIndexB);
|
||||
TxObject** sortValuesA = sortData->mSortValues +
|
||||
txObject** sortValuesA = sortData->mSortValues +
|
||||
indexA * sortData->mNodeSorter->mNKeys;
|
||||
TxObject** sortValuesB = sortData->mSortValues +
|
||||
txObject** sortValuesB = sortData->mSortValues +
|
||||
indexB * sortData->mNodeSorter->mNKeys;
|
||||
|
||||
unsigned int i;
|
||||
@ -280,7 +280,7 @@ txNodeSorter::compareNodes(const void* aIndexA, const void* aIndexB,
|
||||
|
||||
//static
|
||||
bool
|
||||
txNodeSorter::calcSortValue(TxObject*& aSortValue, SortKey* aKey,
|
||||
txNodeSorter::calcSortValue(txObject*& aSortValue, SortKey* aKey,
|
||||
SortData* aSortData, PRUint32 aNodeIndex)
|
||||
{
|
||||
aSortData->mContext->setPosition(aNodeIndex + 1); // position is 1-based
|
||||
|
@ -46,7 +46,7 @@
|
||||
class Expr;
|
||||
class txExecutionState;
|
||||
class txNodeSet;
|
||||
class TxObject;
|
||||
class txObject;
|
||||
class txXPathResultComparator;
|
||||
class txIEvalContext;
|
||||
class txNodeSetContext;
|
||||
@ -72,7 +72,7 @@ private:
|
||||
{
|
||||
txNodeSorter* mNodeSorter;
|
||||
txNodeSetContext* mContext;
|
||||
TxObject** mSortValues;
|
||||
txObject** mSortValues;
|
||||
nsresult mRv;
|
||||
};
|
||||
struct SortKey
|
||||
@ -83,8 +83,8 @@ private:
|
||||
|
||||
static int compareNodes(const void* aIndexA, const void* aIndexB,
|
||||
void* aSortData);
|
||||
static bool calcSortValue(TxObject*& aSortValue, SortKey* aKey,
|
||||
SortData* aSortData, PRUint32 aNodeIndex);
|
||||
static bool calcSortValue(txObject*& aSortValue, SortKey* aKey,
|
||||
SortData* aSortData, PRUint32 aNodeIndex);
|
||||
txList mSortKeys;
|
||||
unsigned int mNKeys;
|
||||
};
|
||||
|
@ -77,7 +77,7 @@ double txResultTreeFragment::numberValue()
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Double::toDouble(mBuffer->mStringValue);
|
||||
return txDouble::toDouble(mBuffer->mStringValue);
|
||||
}
|
||||
|
||||
nsresult txResultTreeFragment::flushToHandler(txAXMLEventHandler* aHandler)
|
||||
|
@ -442,9 +442,9 @@ txStylesheet::addTemplate(txTemplateItem* aTemplate,
|
||||
PRUint32 unionPos = 1; // only used when unionPattern is set
|
||||
while (simple) {
|
||||
double priority = aTemplate->mPrio;
|
||||
if (Double::isNaN(priority)) {
|
||||
if (txDouble::isNaN(priority)) {
|
||||
priority = simple->getDefaultPriority();
|
||||
NS_ASSERTION(!Double::isNaN(priority),
|
||||
NS_ASSERTION(!txDouble::isNaN(priority),
|
||||
"simple pattern without default priority");
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ public:
|
||||
ImportFrame* mFirstNotImported;
|
||||
};
|
||||
|
||||
class GlobalVariable : public TxObject {
|
||||
class GlobalVariable : public txObject {
|
||||
public:
|
||||
GlobalVariable(nsAutoPtr<Expr> aExpr,
|
||||
nsAutoPtr<txInstruction> aFirstInstruction,
|
||||
|
@ -303,7 +303,7 @@ getNumberAttr(txStylesheetAttr* aAttributes,
|
||||
txStylesheetCompilerState& aState,
|
||||
double& aNumber)
|
||||
{
|
||||
aNumber = Double::NaN;
|
||||
aNumber = txDouble::NaN;
|
||||
txStylesheetAttr* attr = nsnull;
|
||||
nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
|
||||
aName, aRequired, &attr);
|
||||
@ -311,8 +311,8 @@ getNumberAttr(txStylesheetAttr* aAttributes,
|
||||
return rv;
|
||||
}
|
||||
|
||||
aNumber = Double::toDouble(attr->mValue);
|
||||
if (Double::isNaN(aNumber) && (aRequired || !aState.fcp())) {
|
||||
aNumber = txDouble::toDouble(attr->mValue);
|
||||
if (txDouble::isNaN(aNumber) && (aRequired || !aState.fcp())) {
|
||||
// XXX ErrorReport: number parse failure
|
||||
return NS_ERROR_XSLT_PARSE_FAILURE;
|
||||
}
|
||||
@ -552,7 +552,7 @@ txFnStartLREStylesheet(PRInt32 aNamespaceID,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txExpandedName nullExpr;
|
||||
double prio = Double::NaN;
|
||||
double prio = txDouble::NaN;
|
||||
|
||||
nsAutoPtr<txPattern> match(new txRootPattern());
|
||||
NS_ENSURE_TRUE(match, NS_ERROR_OUT_OF_MEMORY);
|
||||
@ -1145,7 +1145,7 @@ txFnStartTemplate(PRInt32 aNamespaceID,
|
||||
aState, mode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
double prio = Double::NaN;
|
||||
double prio = txDouble::NaN;
|
||||
rv = getNumberAttr(aAttributes, aAttrCount, nsGkAtoms::priority,
|
||||
false, aState, prio);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -688,15 +688,15 @@ txStylesheetCompilerState::popChooseGotoList()
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::pushObject(TxObject* aObject)
|
||||
txStylesheetCompilerState::pushObject(txObject* aObject)
|
||||
{
|
||||
return mObjectStack.push(aObject);
|
||||
}
|
||||
|
||||
TxObject*
|
||||
txObject*
|
||||
txStylesheetCompilerState::popObject()
|
||||
{
|
||||
return static_cast<TxObject*>(mObjectStack.pop());
|
||||
return static_cast<txObject*>(mObjectStack.pop());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -60,7 +60,7 @@ class txPushNewContext;
|
||||
class txStylesheetCompiler;
|
||||
class txInScopeVariable;
|
||||
|
||||
class txElementContext : public TxObject
|
||||
class txElementContext : public txObject
|
||||
{
|
||||
public:
|
||||
txElementContext(const nsAString& aBaseURI);
|
||||
@ -122,8 +122,8 @@ public:
|
||||
void popSorter();
|
||||
nsresult pushChooseGotoList();
|
||||
void popChooseGotoList();
|
||||
nsresult pushObject(TxObject* aObject);
|
||||
TxObject* popObject();
|
||||
nsresult pushObject(txObject* aObject);
|
||||
txObject* popObject();
|
||||
nsresult pushPtr(void* aPtr);
|
||||
void* popPtr();
|
||||
|
||||
|
@ -129,7 +129,7 @@ txResultStringComparator::createSortableValue(Expr *aExpr,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int txResultStringComparator::compareValues(TxObject* aVal1, TxObject* aVal2)
|
||||
int txResultStringComparator::compareValues(txObject* aVal1, txObject* aVal2)
|
||||
{
|
||||
StringValue* strval1 = (StringValue*)aVal1;
|
||||
StringValue* strval2 = (StringValue*)aVal2;
|
||||
@ -223,7 +223,7 @@ txResultNumberComparator::txResultNumberComparator(bool aAscending)
|
||||
nsresult
|
||||
txResultNumberComparator::createSortableValue(Expr *aExpr,
|
||||
txIEvalContext *aContext,
|
||||
TxObject *&aResult)
|
||||
txObject *&aResult)
|
||||
{
|
||||
nsAutoPtr<NumberValue> numval(new NumberValue);
|
||||
if (!numval) {
|
||||
@ -241,15 +241,15 @@ txResultNumberComparator::createSortableValue(Expr *aExpr,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int txResultNumberComparator::compareValues(TxObject* aVal1, TxObject* aVal2)
|
||||
int txResultNumberComparator::compareValues(txObject* aVal1, txObject* aVal2)
|
||||
{
|
||||
double dval1 = ((NumberValue*)aVal1)->mVal;
|
||||
double dval2 = ((NumberValue*)aVal2)->mVal;
|
||||
|
||||
if (Double::isNaN(dval1))
|
||||
return Double::isNaN(dval2) ? 0 : -mAscending;
|
||||
if (txDouble::isNaN(dval1))
|
||||
return txDouble::isNaN(dval2) ? 0 : -mAscending;
|
||||
|
||||
if (Double::isNaN(dval2))
|
||||
if (txDouble::isNaN(dval2))
|
||||
return mAscending;
|
||||
|
||||
if (dval1 == dval2)
|
||||
|
@ -62,13 +62,13 @@ public:
|
||||
* Compares two XPath results. Returns -1 if val1 < val2,
|
||||
* 1 if val1 > val2 and 0 if val1 == val2.
|
||||
*/
|
||||
virtual int compareValues(TxObject* val1, TxObject* val2) = 0;
|
||||
virtual int compareValues(txObject* val1, txObject* val2) = 0;
|
||||
|
||||
/*
|
||||
* Create a sortable value.
|
||||
*/
|
||||
virtual nsresult createSortableValue(Expr *aExpr, txIEvalContext *aContext,
|
||||
TxObject *&aResult) = 0;
|
||||
txObject *&aResult) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -80,9 +80,9 @@ public:
|
||||
txResultStringComparator(bool aAscending, bool aUpperFirst,
|
||||
const nsAFlatString& aLanguage);
|
||||
|
||||
int compareValues(TxObject* aVal1, TxObject* aVal2);
|
||||
int compareValues(txObject* aVal1, txObject* aVal2);
|
||||
nsresult createSortableValue(Expr *aExpr, txIEvalContext *aContext,
|
||||
TxObject *&aResult);
|
||||
txObject *&aResult);
|
||||
private:
|
||||
nsCOMPtr<nsICollation> mCollation;
|
||||
nsresult init(const nsAFlatString& aLanguage);
|
||||
@ -92,7 +92,7 @@ private:
|
||||
PRUint32* aLength);
|
||||
int mSorting;
|
||||
|
||||
class StringValue : public TxObject
|
||||
class StringValue : public txObject
|
||||
{
|
||||
public:
|
||||
StringValue();
|
||||
@ -112,14 +112,14 @@ class txResultNumberComparator : public txXPathResultComparator
|
||||
public:
|
||||
txResultNumberComparator(bool aAscending);
|
||||
|
||||
int compareValues(TxObject* aVal1, TxObject* aVal2);
|
||||
int compareValues(txObject* aVal1, txObject* aVal2);
|
||||
nsresult createSortableValue(Expr *aExpr, txIEvalContext *aContext,
|
||||
TxObject *&aResult);
|
||||
txObject *&aResult);
|
||||
|
||||
private:
|
||||
int mAscending;
|
||||
|
||||
class NumberValue : public TxObject
|
||||
class NumberValue : public txObject
|
||||
{
|
||||
public:
|
||||
double mVal;
|
||||
|
@ -122,9 +122,9 @@ txXSLTNumber::getValueList(Expr* aValueExpr, txPattern* aCountPattern,
|
||||
|
||||
double value = result->numberValue();
|
||||
|
||||
if (Double::isInfinite(value) || Double::isNaN(value) ||
|
||||
if (txDouble::isInfinite(value) || txDouble::isNaN(value) ||
|
||||
value < 0.5) {
|
||||
Double::toString(value, aValueString);
|
||||
txDouble::toString(value, aValueString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ txXSLTNumber::getCounters(Expr* aGroupSize, Expr* aGroupSeparator,
|
||||
rv = aGroupSize->evaluateToString(aContext, sizeStr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
double size = Double::toDouble(sizeStr);
|
||||
double size = txDouble::toDouble(sizeStr);
|
||||
groupSize = (PRInt32)size;
|
||||
if ((double)groupSize != size) {
|
||||
groupSize = 0;
|
||||
|
@ -54,7 +54,7 @@
|
||||
double txUnionPattern::getDefaultPriority()
|
||||
{
|
||||
NS_ERROR("Don't call getDefaultPriority on txUnionPattern");
|
||||
return Double::NaN;
|
||||
return txDouble::NaN;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -73,6 +73,35 @@ DoomCachedStatements(const nsACString& aQuery,
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
// This runnable doesn't actually do anything beyond "prime the pump" and get
|
||||
// transactions in the right order on the transaction thread pool.
|
||||
class StartTransactionRunnable : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
// NOP
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
// Could really use those NS_REFCOUNTING_HAHA_YEAH_RIGHT macros here.
|
||||
NS_IMETHODIMP_(nsrefcnt) StartTransactionRunnable::AddRef()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt) StartTransactionRunnable::Release()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(StartTransactionRunnable, nsIRunnable)
|
||||
|
||||
StartTransactionRunnable gStartTransactionRunnable;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
@ -121,6 +150,11 @@ IDBTransaction::Create(IDBDatabase* aDatabase,
|
||||
transaction->mCreating = true;
|
||||
}
|
||||
|
||||
if (aMode != nsIIDBTransaction::VERSION_CHANGE) {
|
||||
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
|
||||
pool->Dispatch(transaction, &gStartTransactionRunnable, false, nsnull);
|
||||
}
|
||||
|
||||
return transaction.forget();
|
||||
}
|
||||
|
||||
|
@ -47,8 +47,7 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
|
||||
using mozilla::MutexAutoLock;
|
||||
using mozilla::MutexAutoUnlock;
|
||||
using mozilla::MonitorAutoLock;
|
||||
|
||||
USING_INDEXEDDB_NAMESPACE
|
||||
|
||||
@ -604,8 +603,7 @@ TransactionThreadPool::MaybeFireCallback(PRUint32 aCallbackIndex)
|
||||
TransactionThreadPool::
|
||||
TransactionQueue::TransactionQueue(IDBTransaction* aTransaction,
|
||||
nsIRunnable* aRunnable)
|
||||
: mMutex("TransactionQueue::mMutex"),
|
||||
mCondVar(mMutex, "TransactionQueue::mCondVar"),
|
||||
: mMonitor("TransactionQueue::mMonitor"),
|
||||
mTransaction(aTransaction),
|
||||
mShouldFinish(false)
|
||||
{
|
||||
@ -617,29 +615,26 @@ TransactionQueue::TransactionQueue(IDBTransaction* aTransaction,
|
||||
void
|
||||
TransactionThreadPool::TransactionQueue::Dispatch(nsIRunnable* aRunnable)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
NS_ASSERTION(!mShouldFinish, "Dispatch called after Finish!");
|
||||
|
||||
if (!mQueue.AppendElement(aRunnable)) {
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
NS_RUNTIMEABORT("Out of memory!");
|
||||
}
|
||||
mQueue.AppendElement(aRunnable);
|
||||
|
||||
mCondVar.Notify();
|
||||
mMonitor.Notify();
|
||||
}
|
||||
|
||||
void
|
||||
TransactionThreadPool::TransactionQueue::Finish(nsIRunnable* aFinishRunnable)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
NS_ASSERTION(!mShouldFinish, "Finish called more than once!");
|
||||
|
||||
mShouldFinish = true;
|
||||
mFinishRunnable = aFinishRunnable;
|
||||
|
||||
mCondVar.Notify();
|
||||
mMonitor.Notify();
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(TransactionThreadPool::TransactionQueue,
|
||||
@ -656,9 +651,9 @@ TransactionThreadPool::TransactionQueue::Run()
|
||||
NS_ASSERTION(queue.IsEmpty(), "Should have cleared this!");
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
while (!mShouldFinish && mQueue.IsEmpty()) {
|
||||
if (NS_FAILED(mCondVar.Wait())) {
|
||||
if (NS_FAILED(mMonitor.Wait())) {
|
||||
NS_ERROR("Failed to wait!");
|
||||
}
|
||||
}
|
||||
|
@ -46,8 +46,7 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIRunnable.h"
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
@ -106,8 +105,7 @@ protected:
|
||||
inline void Finish(nsIRunnable* aFinishRunnable);
|
||||
|
||||
private:
|
||||
mozilla::Mutex mMutex;
|
||||
mozilla::CondVar mCondVar;
|
||||
mozilla::Monitor mMonitor;
|
||||
IDBTransaction* mTransaction;
|
||||
nsAutoTArray<nsCOMPtr<nsIRunnable>, 10> mQueue;
|
||||
nsCOMPtr<nsIRunnable> mFinishRunnable;
|
||||
|
@ -102,6 +102,7 @@ TEST_FILES = \
|
||||
test_transaction_abort.html \
|
||||
test_transaction_lifetimes.html \
|
||||
test_transaction_lifetimes_nested.html \
|
||||
test_transaction_ordering.html \
|
||||
test_setVersion.html \
|
||||
test_setVersion_abort.html \
|
||||
test_setVersion_events.html \
|
||||
|
61
dom/indexedDB/test/test_transaction_ordering.html
Normal file
61
dom/indexedDB/test/test_transaction_ordering.html
Normal file
@ -0,0 +1,61 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
function testSteps()
|
||||
{
|
||||
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
request.onsuccess = continueToNextStep;
|
||||
|
||||
db.createObjectStore("foo");
|
||||
yield;
|
||||
|
||||
let trans1 = db.transaction("foo", IDBTransaction.READ_WRITE);
|
||||
let trans2 = db.transaction("foo", IDBTransaction.READ_WRITE);
|
||||
|
||||
let request1 = trans2.objectStore("foo").put("2", 42);
|
||||
let request2 = trans1.objectStore("foo").put("1", 42);
|
||||
|
||||
request1.onerror = errorHandler;
|
||||
request2.onerror = errorHandler;
|
||||
|
||||
trans1.oncomplete = grabEventAndContinueHandler;
|
||||
trans2.oncomplete = grabEventAndContinueHandler;
|
||||
|
||||
yield;
|
||||
yield;
|
||||
|
||||
let trans3 = db.transaction("foo", IDBTransaction.READ);
|
||||
let request = trans3.objectStore("foo").get(42);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
request.onerror = errorHandler;
|
||||
|
||||
let event = yield;
|
||||
is(event.target.result, "2", "Transactions were ordered properly.");
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
@ -7,7 +7,7 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) =
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-1.html border-padding-1-ref.html # bug 629430
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-2.html border-padding-2-ref.html # bug 629430
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) skip-if(Android) == border-padding-3.html border-padding-3-ref.html # bug 629430
|
||||
random-if(cocoaWidget||d2d) fails-if(!haveTestPlugin&&!Android) skip-if(!testPluginIsOOP()) == pluginproblemui-direction-1.html pluginproblemui-direction-1-ref.html
|
||||
random-if(cocoaWidget||d2d||/^Windows\x20NT\x205\.1/.test(http.oscpu)) fails-if(!haveTestPlugin&&!Android) skip-if(!testPluginIsOOP()) == pluginproblemui-direction-1.html pluginproblemui-direction-1-ref.html # bug 567367
|
||||
random-if(cocoaWidget) fails-if(!haveTestPlugin&&!Android) skip-if(!testPluginIsOOP()) == pluginproblemui-direction-2.html pluginproblemui-direction-2-ref.html
|
||||
fails-if(!haveTestPlugin) == plugin-canvas-alpha-zindex.html div-alpha-zindex.html
|
||||
fails-if(!haveTestPlugin) == plugin-transform-alpha-zindex.html div-alpha-zindex.html
|
||||
|
@ -203,7 +203,7 @@ WifiGeoPositionProvider.prototype = {
|
||||
|
||||
let accessToken = this.getAccessTokenForURL(providerUrlBase);
|
||||
if (accessToken !== "")
|
||||
providerUrl = providerUrl + "&access_token="+access_token;
|
||||
providerUrl = providerUrl + "&access_token="+accessToken;
|
||||
|
||||
function sort(a, b) {
|
||||
return b.signal - a.signal;
|
||||
|
@ -5155,6 +5155,7 @@ nsEditor::InitializeSelection(nsIDOMEventTarget* aFocusEventTarget)
|
||||
|
||||
// Init selection
|
||||
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
||||
selCon->SetSelectionFlags(nsISelectionDisplay::DISPLAY_ALL);
|
||||
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
// If the computed selection root isn't root content, we should set it
|
||||
// as selection ancestor limit. However, if that is root element, it means
|
||||
|
@ -54,7 +54,9 @@ DIRS += test
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
|
||||
ifeq ($(MOZ_BUILD_APP),mobile/xul)
|
||||
DIRS += android
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -18,10 +18,7 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
|
||||
|
||||
<uses-permission android:name="android.permission.READ_LOGS"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.location" android:required="false"/>
|
||||
|
527
gfx/2d/Blur.cpp
Normal file
527
gfx/2d/Blur.cpp
Normal file
@ -0,0 +1,527 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla gfx.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/gfx/Blur.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CheckedInt.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
/**
|
||||
* Box blur involves looking at one pixel, and setting its value to the average
|
||||
* of its neighbouring pixels.
|
||||
* @param aInput The input buffer.
|
||||
* @param aOutput The output buffer.
|
||||
* @param aLeftLobe The number of pixels to blend on the left.
|
||||
* @param aRightLobe The number of pixels to blend on the right.
|
||||
* @param aWidth The number of columns in the buffers.
|
||||
* @param aRows The number of rows in the buffers.
|
||||
* @param aSkipRect An area to skip blurring in.
|
||||
* XXX shouldn't we pass stride in separately here?
|
||||
*/
|
||||
static void
|
||||
BoxBlurHorizontal(unsigned char* aInput,
|
||||
unsigned char* aOutput,
|
||||
int32_t aLeftLobe,
|
||||
int32_t aRightLobe,
|
||||
int32_t aWidth,
|
||||
int32_t aRows,
|
||||
const IntRect& aSkipRect)
|
||||
{
|
||||
MOZ_ASSERT(aWidth > 0);
|
||||
|
||||
int32_t boxSize = aLeftLobe + aRightLobe + 1;
|
||||
bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
|
||||
aWidth <= aSkipRect.XMost();
|
||||
|
||||
for (int32_t y = 0; y < aRows; y++) {
|
||||
// Check whether the skip rect intersects this row. If the skip
|
||||
// rect covers the whole surface in this row, we can avoid
|
||||
// this row entirely (and any others along the skip rect).
|
||||
bool inSkipRectY = y >= aSkipRect.y &&
|
||||
y < aSkipRect.YMost();
|
||||
if (inSkipRectY && skipRectCoversWholeRow) {
|
||||
y = aSkipRect.YMost() - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t alphaSum = 0;
|
||||
for (int32_t i = 0; i < boxSize; i++) {
|
||||
int32_t pos = i - aLeftLobe;
|
||||
// See assertion above; if aWidth is zero, then we would have no
|
||||
// valid position to clamp to.
|
||||
pos = max(pos, 0);
|
||||
pos = min(pos, aWidth - 1);
|
||||
alphaSum += aInput[aWidth * y + pos];
|
||||
}
|
||||
for (int32_t x = 0; x < aWidth; x++) {
|
||||
// Check whether we are within the skip rect. If so, go
|
||||
// to the next point outside the skip rect.
|
||||
if (inSkipRectY && x >= aSkipRect.x &&
|
||||
x < aSkipRect.XMost()) {
|
||||
x = aSkipRect.XMost();
|
||||
if (x >= aWidth)
|
||||
break;
|
||||
|
||||
// Recalculate the neighbouring alpha values for
|
||||
// our new point on the surface.
|
||||
alphaSum = 0;
|
||||
for (int32_t i = 0; i < boxSize; i++) {
|
||||
int32_t pos = x + i - aLeftLobe;
|
||||
// See assertion above; if aWidth is zero, then we would have no
|
||||
// valid position to clamp to.
|
||||
pos = max(pos, 0);
|
||||
pos = min(pos, aWidth - 1);
|
||||
alphaSum += aInput[aWidth * y + pos];
|
||||
}
|
||||
}
|
||||
int32_t tmp = x - aLeftLobe;
|
||||
int32_t last = max(tmp, 0);
|
||||
int32_t next = min(tmp + boxSize, aWidth - 1);
|
||||
|
||||
aOutput[aWidth * y + x] = alphaSum / boxSize;
|
||||
|
||||
alphaSum += aInput[aWidth * y + next] -
|
||||
aInput[aWidth * y + last];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Identical to BoxBlurHorizontal, except it blurs top and bottom instead of
|
||||
* left and right.
|
||||
* XXX shouldn't we pass stride in separately here?
|
||||
*/
|
||||
static void
|
||||
BoxBlurVertical(unsigned char* aInput,
|
||||
unsigned char* aOutput,
|
||||
int32_t aTopLobe,
|
||||
int32_t aBottomLobe,
|
||||
int32_t aWidth,
|
||||
int32_t aRows,
|
||||
const IntRect& aSkipRect)
|
||||
{
|
||||
MOZ_ASSERT(aRows > 0);
|
||||
|
||||
int32_t boxSize = aTopLobe + aBottomLobe + 1;
|
||||
bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
|
||||
aRows <= aSkipRect.YMost();
|
||||
|
||||
for (int32_t x = 0; x < aWidth; x++) {
|
||||
bool inSkipRectX = x >= aSkipRect.x &&
|
||||
x < aSkipRect.XMost();
|
||||
if (inSkipRectX && skipRectCoversWholeColumn) {
|
||||
x = aSkipRect.XMost() - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t alphaSum = 0;
|
||||
for (int32_t i = 0; i < boxSize; i++) {
|
||||
int32_t pos = i - aTopLobe;
|
||||
// See assertion above; if aRows is zero, then we would have no
|
||||
// valid position to clamp to.
|
||||
pos = max(pos, 0);
|
||||
pos = min(pos, aRows - 1);
|
||||
alphaSum += aInput[aWidth * pos + x];
|
||||
}
|
||||
for (int32_t y = 0; y < aRows; y++) {
|
||||
if (inSkipRectX && y >= aSkipRect.y &&
|
||||
y < aSkipRect.YMost()) {
|
||||
y = aSkipRect.YMost();
|
||||
if (y >= aRows)
|
||||
break;
|
||||
|
||||
alphaSum = 0;
|
||||
for (int32_t i = 0; i < boxSize; i++) {
|
||||
int32_t pos = y + i - aTopLobe;
|
||||
// See assertion above; if aRows is zero, then we would have no
|
||||
// valid position to clamp to.
|
||||
pos = max(pos, 0);
|
||||
pos = min(pos, aRows - 1);
|
||||
alphaSum += aInput[aWidth * pos + x];
|
||||
}
|
||||
}
|
||||
int32_t tmp = y - aTopLobe;
|
||||
int32_t last = max(tmp, 0);
|
||||
int32_t next = min(tmp + boxSize, aRows - 1);
|
||||
|
||||
aOutput[aWidth * y + x] = alphaSum/boxSize;
|
||||
|
||||
alphaSum += aInput[aWidth * next + x] -
|
||||
aInput[aWidth * last + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ComputeLobes(int32_t aRadius, int32_t aLobes[3][2])
|
||||
{
|
||||
int32_t major, minor, final;
|
||||
|
||||
/* See http://www.w3.org/TR/SVG/filters.html#feGaussianBlur for
|
||||
* some notes about approximating the Gaussian blur with box-blurs.
|
||||
* The comments below are in the terminology of that page.
|
||||
*/
|
||||
int32_t z = aRadius / 3;
|
||||
switch (aRadius % 3) {
|
||||
case 0:
|
||||
// aRadius = z*3; choose d = 2*z + 1
|
||||
major = minor = final = z;
|
||||
break;
|
||||
case 1:
|
||||
// aRadius = z*3 + 1
|
||||
// This is a tricky case since there is no value of d which will
|
||||
// yield a radius of exactly aRadius. If d is odd, i.e. d=2*k + 1
|
||||
// for some integer k, then the radius will be 3*k. If d is even,
|
||||
// i.e. d=2*k, then the radius will be 3*k - 1.
|
||||
// So we have to choose values that don't match the standard
|
||||
// algorithm.
|
||||
major = z + 1;
|
||||
minor = final = z;
|
||||
break;
|
||||
case 2:
|
||||
// aRadius = z*3 + 2; choose d = 2*z + 2
|
||||
major = final = z + 1;
|
||||
minor = z;
|
||||
break;
|
||||
default:
|
||||
// Mathematical impossibility!
|
||||
MOZ_ASSERT(false);
|
||||
major = minor = final = 0;
|
||||
}
|
||||
MOZ_ASSERT(major + minor + final == aRadius);
|
||||
|
||||
aLobes[0][0] = major;
|
||||
aLobes[0][1] = minor;
|
||||
aLobes[1][0] = minor;
|
||||
aLobes[1][1] = major;
|
||||
aLobes[2][0] = final;
|
||||
aLobes[2][1] = final;
|
||||
}
|
||||
|
||||
static void
|
||||
SpreadHorizontal(unsigned char* aInput,
|
||||
unsigned char* aOutput,
|
||||
int32_t aRadius,
|
||||
int32_t aWidth,
|
||||
int32_t aRows,
|
||||
int32_t aStride,
|
||||
const IntRect& aSkipRect)
|
||||
{
|
||||
if (aRadius == 0) {
|
||||
memcpy(aOutput, aInput, aStride * aRows);
|
||||
return;
|
||||
}
|
||||
|
||||
bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
|
||||
aWidth <= aSkipRect.XMost();
|
||||
for (int32_t y = 0; y < aRows; y++) {
|
||||
// Check whether the skip rect intersects this row. If the skip
|
||||
// rect covers the whole surface in this row, we can avoid
|
||||
// this row entirely (and any others along the skip rect).
|
||||
bool inSkipRectY = y >= aSkipRect.y &&
|
||||
y < aSkipRect.YMost();
|
||||
if (inSkipRectY && skipRectCoversWholeRow) {
|
||||
y = aSkipRect.YMost() - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32_t x = 0; x < aWidth; x++) {
|
||||
// Check whether we are within the skip rect. If so, go
|
||||
// to the next point outside the skip rect.
|
||||
if (inSkipRectY && x >= aSkipRect.x &&
|
||||
x < aSkipRect.XMost()) {
|
||||
x = aSkipRect.XMost();
|
||||
if (x >= aWidth)
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t sMin = max(x - aRadius, 0);
|
||||
int32_t sMax = min(x + aRadius, aWidth - 1);
|
||||
int32_t v = 0;
|
||||
for (int32_t s = sMin; s <= sMax; ++s) {
|
||||
v = max<int32_t>(v, aInput[aStride * y + s]);
|
||||
}
|
||||
aOutput[aStride * y + x] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SpreadVertical(unsigned char* aInput,
|
||||
unsigned char* aOutput,
|
||||
int32_t aRadius,
|
||||
int32_t aWidth,
|
||||
int32_t aRows,
|
||||
int32_t aStride,
|
||||
const IntRect& aSkipRect)
|
||||
{
|
||||
if (aRadius == 0) {
|
||||
memcpy(aOutput, aInput, aStride * aRows);
|
||||
return;
|
||||
}
|
||||
|
||||
bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
|
||||
aRows <= aSkipRect.YMost();
|
||||
for (int32_t x = 0; x < aWidth; x++) {
|
||||
bool inSkipRectX = x >= aSkipRect.x &&
|
||||
x < aSkipRect.XMost();
|
||||
if (inSkipRectX && skipRectCoversWholeColumn) {
|
||||
x = aSkipRect.XMost() - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32_t y = 0; y < aRows; y++) {
|
||||
// Check whether we are within the skip rect. If so, go
|
||||
// to the next point outside the skip rect.
|
||||
if (inSkipRectX && y >= aSkipRect.y &&
|
||||
y < aSkipRect.YMost()) {
|
||||
y = aSkipRect.YMost();
|
||||
if (y >= aRows)
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t sMin = max(y - aRadius, 0);
|
||||
int32_t sMax = min(y + aRadius, aRows - 1);
|
||||
int32_t v = 0;
|
||||
for (int32_t s = sMin; s <= sMax; ++s) {
|
||||
v = max<int32_t>(v, aInput[aStride * s + x]);
|
||||
}
|
||||
aOutput[aStride * y + x] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CheckedInt<int32_t>
|
||||
RoundUpToMultipleOf4(int32_t aVal)
|
||||
{
|
||||
CheckedInt<int32_t> val(aVal);
|
||||
|
||||
val += 3;
|
||||
val /= 4;
|
||||
val *= 4;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
|
||||
const IntSize& aSpreadRadius,
|
||||
const IntSize& aBlurRadius,
|
||||
const Rect* aDirtyRect,
|
||||
const Rect* aSkipRect)
|
||||
: mSpreadRadius(aSpreadRadius),
|
||||
mBlurRadius(aBlurRadius),
|
||||
mData(NULL)
|
||||
{
|
||||
Rect rect(aRect);
|
||||
rect.Inflate(Size(aBlurRadius + aSpreadRadius));
|
||||
rect.RoundOut();
|
||||
|
||||
if (aDirtyRect) {
|
||||
// If we get passed a dirty rect from layout, we can minimize the
|
||||
// shadow size and make painting faster.
|
||||
mHasDirtyRect = true;
|
||||
mDirtyRect = *aDirtyRect;
|
||||
Rect requiredBlurArea = mDirtyRect.Intersect(rect);
|
||||
requiredBlurArea.Inflate(Size(aBlurRadius + aSpreadRadius));
|
||||
rect = requiredBlurArea.Intersect(rect);
|
||||
} else {
|
||||
mHasDirtyRect = false;
|
||||
}
|
||||
|
||||
if (rect.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSkipRect) {
|
||||
// If we get passed a skip rect, we can lower the amount of
|
||||
// blurring/spreading we need to do. We convert it to IntRect to avoid
|
||||
// expensive int<->float conversions if we were to use Rect instead.
|
||||
Rect skipRect = *aSkipRect;
|
||||
skipRect.RoundIn();
|
||||
skipRect.Deflate(Size(aBlurRadius + aSpreadRadius));
|
||||
mSkipRect = IntRect(skipRect.x, skipRect.y, skipRect.width, skipRect.height);
|
||||
|
||||
IntRect shadowIntRect(rect.x, rect.y, rect.width, rect.height);
|
||||
mSkipRect.IntersectRect(mSkipRect, shadowIntRect);
|
||||
|
||||
if (mSkipRect.IsEqualInterior(shadowIntRect))
|
||||
return;
|
||||
|
||||
mSkipRect -= shadowIntRect.TopLeft();
|
||||
} else {
|
||||
mSkipRect = IntRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
mRect = IntRect(rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
CheckedInt<int32_t> stride = RoundUpToMultipleOf4(mRect.width);
|
||||
if (stride.valid()) {
|
||||
mStride = stride.value();
|
||||
|
||||
CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height *
|
||||
sizeof(unsigned char);
|
||||
if (size.valid()) {
|
||||
mData = static_cast<unsigned char*>(malloc(size.value()));
|
||||
memset(mData, 0, size.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AlphaBoxBlur::~AlphaBoxBlur()
|
||||
{
|
||||
free(mData);
|
||||
}
|
||||
|
||||
unsigned char*
|
||||
AlphaBoxBlur::GetData()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
IntSize
|
||||
AlphaBoxBlur::GetSize()
|
||||
{
|
||||
IntSize size(mRect.width, mRect.height);
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t
|
||||
AlphaBoxBlur::GetStride()
|
||||
{
|
||||
return mStride;
|
||||
}
|
||||
|
||||
IntRect
|
||||
AlphaBoxBlur::GetRect()
|
||||
{
|
||||
return mRect;
|
||||
}
|
||||
|
||||
Rect*
|
||||
AlphaBoxBlur::GetDirtyRect()
|
||||
{
|
||||
if (mHasDirtyRect) {
|
||||
return &mDirtyRect;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
AlphaBoxBlur::Blur()
|
||||
{
|
||||
if (!mData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// no need to do all this if not blurring or spreading
|
||||
if (mBlurRadius != IntSize(0,0) || mSpreadRadius != IntSize(0,0)) {
|
||||
int32_t stride = GetStride();
|
||||
|
||||
// No need to use CheckedInt here - we have validated it in the constructor.
|
||||
size_t szB = stride * GetSize().height * sizeof(unsigned char);
|
||||
unsigned char* tmpData = static_cast<unsigned char*>(malloc(szB));
|
||||
if (!tmpData)
|
||||
return; // OOM
|
||||
|
||||
memset(tmpData, 0, szB);
|
||||
|
||||
if (mSpreadRadius.width > 0 || mSpreadRadius.height > 0) {
|
||||
SpreadHorizontal(mData, tmpData, mSpreadRadius.width, GetSize().width, GetSize().height, stride, mSkipRect);
|
||||
SpreadVertical(tmpData, mData, mSpreadRadius.height, GetSize().width, GetSize().height, stride, mSkipRect);
|
||||
}
|
||||
|
||||
if (mBlurRadius.width > 0) {
|
||||
int32_t lobes[3][2];
|
||||
ComputeLobes(mBlurRadius.width, lobes);
|
||||
BoxBlurHorizontal(mData, tmpData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
|
||||
BoxBlurHorizontal(tmpData, mData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
|
||||
BoxBlurHorizontal(mData, tmpData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
|
||||
} else {
|
||||
memcpy(tmpData, mData, stride * GetSize().height);
|
||||
}
|
||||
|
||||
if (mBlurRadius.height > 0) {
|
||||
int32_t lobes[3][2];
|
||||
ComputeLobes(mBlurRadius.height, lobes);
|
||||
BoxBlurVertical(tmpData, mData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
|
||||
BoxBlurVertical(mData, tmpData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
|
||||
BoxBlurVertical(tmpData, mData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
|
||||
} else {
|
||||
memcpy(mData, tmpData, stride * GetSize().height);
|
||||
}
|
||||
|
||||
free(tmpData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the box blur size (which we're calling the blur radius) from
|
||||
* the standard deviation.
|
||||
*
|
||||
* Much of this, the 3 * sqrt(2 * pi) / 4, is the known value for
|
||||
* approximating a Gaussian using box blurs. This yields quite a good
|
||||
* approximation for a Gaussian. Then we multiply this by 1.5 since our
|
||||
* code wants the radius of the entire triple-box-blur kernel instead of
|
||||
* the diameter of an individual box blur. For more details, see:
|
||||
* http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=590039#c19
|
||||
*/
|
||||
static const Float GAUSSIAN_SCALE_FACTOR = (3 * sqrt(2 * M_PI) / 4) * 1.5;
|
||||
|
||||
IntSize
|
||||
AlphaBoxBlur::CalculateBlurRadius(const Point& aStd)
|
||||
{
|
||||
IntSize size(static_cast<int32_t>(floor(aStd.x * GAUSSIAN_SCALE_FACTOR + 0.5)),
|
||||
static_cast<int32_t>(floor(aStd.y * GAUSSIAN_SCALE_FACTOR + 0.5)));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
185
gfx/2d/Blur.h
Normal file
185
gfx/2d/Blur.h
Normal file
@ -0,0 +1,185 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla gfx.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MOZILLA_GFX_BLUR_H_
|
||||
#define MOZILLA_GFX_BLUR_H_
|
||||
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
/**
|
||||
* Implementation of a triple box blur approximation of a Gaussian blur.
|
||||
*
|
||||
* A Gaussian blur is good for blurring because, when done independently
|
||||
* in the horizontal and vertical directions, it matches the result that
|
||||
* would be obtained using a different (rotated) set of axes. A triple
|
||||
* box blur is a very close approximation of a Gaussian.
|
||||
*
|
||||
* Creates an 8-bit alpha channel context for callers to draw in,
|
||||
* spreads the contents of that context, and blurs the contents.
|
||||
*
|
||||
* A spread N makes each output pixel the maximum value of all source
|
||||
* pixels within a square of side length 2N+1 centered on the output pixel.
|
||||
*
|
||||
* A temporary surface is created in the Init function. The caller then draws
|
||||
* any desired content onto the context acquired through GetContext, and lastly
|
||||
* calls Paint to apply the blurred content as an alpha mask.
|
||||
*/
|
||||
class AlphaBoxBlur
|
||||
{
|
||||
public:
|
||||
|
||||
/** Constructs a box blur and initializes the backing surface.
|
||||
*
|
||||
* @param aRect The coordinates of the surface to create in device units.
|
||||
*
|
||||
* @param aBlurRadius The blur radius in pixels. This is the radius of the
|
||||
* entire (triple) kernel function. Each individual box blur has radius
|
||||
* approximately 1/3 this value, or diameter approximately 2/3 this value.
|
||||
* This parameter should nearly always be computed using CalculateBlurRadius,
|
||||
* below.
|
||||
*
|
||||
* @param aDirtyRect A pointer to a dirty rect, measured in device units, if
|
||||
* available. This will be used for optimizing the blur operation. It is
|
||||
* safe to pass NULL here.
|
||||
*
|
||||
* @param aSkipRect A pointer to a rect, measured in device units, that
|
||||
* represents an area where blurring is unnecessary and shouldn't be done for
|
||||
* speed reasons. It is safe to pass NULL here.
|
||||
*/
|
||||
AlphaBoxBlur(const Rect& aRect,
|
||||
const IntSize& aSpreadRadius,
|
||||
const IntSize& aBlurRadius,
|
||||
const Rect* aDirtyRect,
|
||||
const Rect* aSkipRect);
|
||||
|
||||
~AlphaBoxBlur();
|
||||
|
||||
/**
|
||||
* Return the pointer to memory allocated by the constructor for the 8-bit
|
||||
* alpha surface you need to be blurred. After you draw to this surface, call
|
||||
* Blur(), below, to have its contents blurred.
|
||||
*/
|
||||
unsigned char* GetData();
|
||||
|
||||
/**
|
||||
* Return the size, in pixels, of the 8-bit alpha surface backed by the
|
||||
* pointer returned by GetData().
|
||||
*/
|
||||
IntSize GetSize();
|
||||
|
||||
/**
|
||||
* Return the stride, in bytes, of the 8-bit alpha surface backed by the
|
||||
* pointer returned by GetData().
|
||||
*/
|
||||
int32_t GetStride();
|
||||
|
||||
/**
|
||||
* Returns the device-space rectangle the 8-bit alpha surface covers.
|
||||
*/
|
||||
IntRect GetRect();
|
||||
|
||||
/**
|
||||
* Return a pointer to a dirty rect, as passed in to the constructor, or NULL
|
||||
* if none was passed in.
|
||||
*/
|
||||
Rect* GetDirtyRect();
|
||||
|
||||
/**
|
||||
* Perform the blur in-place on the surface backed by the pointer returned by
|
||||
* GetData().
|
||||
*/
|
||||
void Blur();
|
||||
|
||||
/**
|
||||
* Calculates a blur radius that, when used with box blur, approximates a
|
||||
* Gaussian blur with the given standard deviation. The result of this
|
||||
* function should be used as the aBlurRadius parameter to AlphaBoxBlur's
|
||||
* constructor, above.
|
||||
*/
|
||||
static IntSize CalculateBlurRadius(const Point& aStandardDeviation);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* A rect indicating the area where blurring is unnecessary, and the blur
|
||||
* algorithm should skip over it.
|
||||
*/
|
||||
IntRect mSkipRect;
|
||||
|
||||
/**
|
||||
* The device-space rectangle the the backing 8-bit alpha surface covers.
|
||||
*/
|
||||
IntRect mRect;
|
||||
|
||||
/**
|
||||
* A copy of the dirty rect passed to the constructor. This will only be valid if
|
||||
* mHasDirtyRect is true.
|
||||
*/
|
||||
Rect mDirtyRect;
|
||||
|
||||
/**
|
||||
* The spread radius, in pixels.
|
||||
*/
|
||||
IntSize mSpreadRadius;
|
||||
|
||||
/**
|
||||
* The blur radius, in pixels.
|
||||
*/
|
||||
IntSize mBlurRadius;
|
||||
|
||||
/**
|
||||
* A pointer to the backing 8-bit alpha surface.
|
||||
*/
|
||||
unsigned char* mData;
|
||||
|
||||
/**
|
||||
* The stride of the data contained in mData.
|
||||
*/
|
||||
int32_t mStride;
|
||||
|
||||
/**
|
||||
* Whether mDirtyRect contains valid data.
|
||||
*/
|
||||
bool mHasDirtyRect;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_GFX_BLUR_H_ */
|
@ -137,36 +137,6 @@ GfxOpToSkiaOp(CompositionOp op)
|
||||
return SkXfermode::kSrcOver_Mode;
|
||||
}
|
||||
|
||||
SkPaint::Cap
|
||||
CapStyleToSkiaCap(CapStyle aCap)
|
||||
{
|
||||
switch (aCap)
|
||||
{
|
||||
case CAP_BUTT:
|
||||
return SkPaint::kButt_Cap;
|
||||
case CAP_ROUND:
|
||||
return SkPaint::kRound_Cap;
|
||||
case CAP_SQUARE:
|
||||
return SkPaint::kSquare_Cap;
|
||||
}
|
||||
return SkPaint::kDefault_Cap;
|
||||
}
|
||||
|
||||
SkPaint::Join
|
||||
JoinStyleToSkiaJoin(JoinStyle aJoin)
|
||||
{
|
||||
switch (aJoin)
|
||||
{
|
||||
case JOIN_BEVEL:
|
||||
return SkPaint::kBevel_Join;
|
||||
case JOIN_ROUND:
|
||||
return SkPaint::kRound_Join;
|
||||
case JOIN_MITER:
|
||||
case JOIN_MITER_OR_BEVEL:
|
||||
return SkPaint::kMiter_Join;
|
||||
}
|
||||
return SkPaint::kDefault_Join;
|
||||
}
|
||||
|
||||
SkRect
|
||||
RectToSkRect(const Rect& aRect)
|
||||
@ -201,7 +171,14 @@ DrawTargetSkia::DrawTargetSkia()
|
||||
|
||||
DrawTargetSkia::~DrawTargetSkia()
|
||||
{
|
||||
MarkChanged();
|
||||
if (mSnapshots.size()) {
|
||||
for (std::vector<SourceSurfaceSkia*>::iterator iter = mSnapshots.begin();
|
||||
iter != mSnapshots.end(); iter++) {
|
||||
(*iter)->DrawTargetDestroyed();
|
||||
}
|
||||
// All snapshots will now have copied data.
|
||||
mSnapshots.clear();
|
||||
}
|
||||
}
|
||||
|
||||
TemporaryRef<SourceSurface>
|
||||
@ -280,6 +257,7 @@ struct AutoPaintSetup {
|
||||
mPaint.setAlpha(aOptions.mAlpha*255.0);
|
||||
mAlpha = aOptions.mAlpha;
|
||||
}
|
||||
mPaint.setFilterBitmap(true);
|
||||
}
|
||||
|
||||
void SetPattern(const Pattern& aPattern)
|
||||
@ -336,27 +314,6 @@ struct AutoPaintSetup {
|
||||
}
|
||||
}
|
||||
|
||||
void SetStroke(const StrokeOptions &aOptions)
|
||||
{
|
||||
mPaint.setStrokeWidth(SkFloatToScalar(aOptions.mLineWidth));
|
||||
mPaint.setStrokeMiter(SkFloatToScalar(aOptions.mMiterLimit));
|
||||
mPaint.setStrokeCap(CapStyleToSkiaCap(aOptions.mLineCap));
|
||||
mPaint.setStrokeJoin(JoinStyleToSkiaJoin(aOptions.mLineJoin));
|
||||
if (aOptions.mDashLength) {
|
||||
std::vector<SkScalar> pattern;
|
||||
pattern.resize(aOptions.mDashLength);
|
||||
for (uint32_t i = 0; i < aOptions.mDashLength; i++) {
|
||||
pattern[i] = SkFloatToScalar(aOptions.mDashPattern[i]);
|
||||
}
|
||||
|
||||
SkDashPathEffect* dash = new SkDashPathEffect(&pattern.front(),
|
||||
aOptions.mDashLength,
|
||||
SkFloatToScalar(aOptions.mDashOffset));
|
||||
SkSafeUnref(mPaint.setPathEffect(dash));
|
||||
}
|
||||
mPaint.setStyle(SkPaint::kStroke_Style);
|
||||
}
|
||||
|
||||
// TODO: Maybe add an operator overload to access this easier?
|
||||
SkPaint mPaint;
|
||||
bool mNeedsRestore;
|
||||
@ -386,7 +343,6 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
|
||||
|
||||
MarkChanged();
|
||||
|
||||
NS_ASSERTION(aSurfOptions.mFilter == FILTER_LINEAR, "Only linear filtering supported currently!");
|
||||
SkRect destRect = RectToSkRect(aDest);
|
||||
SkRect sourceRect = RectToSkRect(aSource);
|
||||
|
||||
@ -399,6 +355,9 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
|
||||
SkShader *shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
|
||||
shader->setLocalMatrix(matrix);
|
||||
SkSafeUnref(paint.mPaint.setShader(shader));
|
||||
if (aSurfOptions.mFilter != FILTER_LINEAR) {
|
||||
paint.mPaint.setFilterBitmap(false);
|
||||
}
|
||||
mCanvas->drawRect(destRect, paint.mPaint);
|
||||
}
|
||||
|
||||
@ -492,7 +451,9 @@ DrawTargetSkia::Stroke(const Path *aPath,
|
||||
|
||||
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
|
||||
paint.SetStroke(aStrokeOptions);
|
||||
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCanvas->drawPath(skiaPath->GetPath(), paint.mPaint);
|
||||
}
|
||||
@ -505,7 +466,9 @@ DrawTargetSkia::StrokeRect(const Rect &aRect,
|
||||
{
|
||||
MarkChanged();
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
|
||||
paint.SetStroke(aStrokeOptions);
|
||||
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCanvas->drawRect(RectToSkRect(aRect), paint.mPaint);
|
||||
}
|
||||
@ -519,7 +482,9 @@ DrawTargetSkia::StrokeLine(const Point &aStart,
|
||||
{
|
||||
MarkChanged();
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
|
||||
paint.SetStroke(aStrokeOptions);
|
||||
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCanvas->drawLine(SkFloatToScalar(aStart.x), SkFloatToScalar(aStart.y),
|
||||
SkFloatToScalar(aEnd.x), SkFloatToScalar(aEnd.y),
|
||||
|
@ -46,6 +46,9 @@
|
||||
#ifdef XP_MACOSX
|
||||
#include "ScaledFontMac.h"
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
#include "ScaledFontWin.h"
|
||||
#endif
|
||||
#include "ScaledFontSkia.h"
|
||||
#endif
|
||||
|
||||
@ -124,6 +127,12 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSiz
|
||||
{
|
||||
return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
|
||||
}
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
case NATIVE_FONT_GDI_FONT_FACE:
|
||||
{
|
||||
return new ScaledFontWin(static_cast<gfxGDIFont*>(aNativeFont.mFont), aSize);
|
||||
}
|
||||
#endif
|
||||
case NATIVE_FONT_SKIA_FONT_FACE:
|
||||
{
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "2D.h"
|
||||
#include "skia/SkCanvas.h"
|
||||
#include "skia/SkDashPathEffect.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
@ -72,6 +73,65 @@ GfxMatrixToSkiaMatrix(const Matrix& mat, SkMatrix& retval)
|
||||
0, 0, SK_Scalar1);
|
||||
}
|
||||
|
||||
static inline SkPaint::Cap
|
||||
CapStyleToSkiaCap(CapStyle aCap)
|
||||
{
|
||||
switch (aCap)
|
||||
{
|
||||
case CAP_BUTT:
|
||||
return SkPaint::kButt_Cap;
|
||||
case CAP_ROUND:
|
||||
return SkPaint::kRound_Cap;
|
||||
case CAP_SQUARE:
|
||||
return SkPaint::kSquare_Cap;
|
||||
}
|
||||
return SkPaint::kDefault_Cap;
|
||||
}
|
||||
|
||||
static inline SkPaint::Join
|
||||
JoinStyleToSkiaJoin(JoinStyle aJoin)
|
||||
{
|
||||
switch (aJoin)
|
||||
{
|
||||
case JOIN_BEVEL:
|
||||
return SkPaint::kBevel_Join;
|
||||
case JOIN_ROUND:
|
||||
return SkPaint::kRound_Join;
|
||||
case JOIN_MITER:
|
||||
case JOIN_MITER_OR_BEVEL:
|
||||
return SkPaint::kMiter_Join;
|
||||
}
|
||||
return SkPaint::kDefault_Join;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
StrokeOptionsToPaint(SkPaint& aPaint, const StrokeOptions &aOptions)
|
||||
{
|
||||
// Skia rendewrs 0 width strokes with a width of 1 (and in black),
|
||||
// so we should just skip the draw call entirely.
|
||||
if (!aOptions.mLineWidth) {
|
||||
return false;
|
||||
}
|
||||
aPaint.setStrokeWidth(SkFloatToScalar(aOptions.mLineWidth));
|
||||
aPaint.setStrokeMiter(SkFloatToScalar(aOptions.mMiterLimit));
|
||||
aPaint.setStrokeCap(CapStyleToSkiaCap(aOptions.mLineCap));
|
||||
aPaint.setStrokeJoin(JoinStyleToSkiaJoin(aOptions.mLineJoin));
|
||||
if (aOptions.mDashLength > 1) {
|
||||
std::vector<SkScalar> pattern;
|
||||
pattern.resize(aOptions.mDashLength);
|
||||
for (uint32_t i = 0; i < aOptions.mDashLength; i++) {
|
||||
pattern[i] = SkFloatToScalar(aOptions.mDashPattern[i]);
|
||||
}
|
||||
|
||||
SkDashPathEffect* dash = new SkDashPathEffect(&pattern.front(),
|
||||
aOptions.mDashLength,
|
||||
SkFloatToScalar(aOptions.mDashOffset));
|
||||
SkSafeUnref(aPaint.setPathEffect(dash));
|
||||
}
|
||||
aPaint.setStyle(SkPaint::kStroke_Style);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ EXPORTS_mozilla/gfx = \
|
||||
BaseMargin.h \
|
||||
BaseRect.h \
|
||||
BaseSize.h \
|
||||
Blur.h \
|
||||
PathHelpers.h \
|
||||
Point.h \
|
||||
Matrix.h \
|
||||
@ -68,6 +69,7 @@ CPPSRCS = \
|
||||
Matrix.cpp \
|
||||
DrawTargetCairo.cpp \
|
||||
SourceSurfaceCairo.cpp \
|
||||
Blur.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@ -107,9 +109,13 @@ CPPSRCS += \
|
||||
SourceSurfaceD2DTarget.cpp \
|
||||
PathD2D.cpp \
|
||||
ScaledFontDWrite.cpp \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -DWIN32
|
||||
SourceSurfaceSkia.cpp \
|
||||
DrawTargetSkia.cpp \
|
||||
PathSkia.cpp \
|
||||
ScaledFontSkia.cpp \
|
||||
ScaledFontWin.cpp \
|
||||
$(NULL)
|
||||
DEFINES += -DWIN32 -DUSE_SKIA
|
||||
endif
|
||||
|
||||
#ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
|
@ -196,8 +196,14 @@ Rect
|
||||
PathSkia::GetStrokedBounds(const StrokeOptions &aStrokeOptions,
|
||||
const Matrix &aTransform) const
|
||||
{
|
||||
NS_ASSERTION(false, "GetStrokedBounds not supported yet!");
|
||||
return Rect(0, 0, 0, 0);
|
||||
SkPaint paint;
|
||||
StrokeOptionsToPaint(paint, aStrokeOptions);
|
||||
|
||||
SkPath result;
|
||||
paint.getFillPath(mPath, &result);
|
||||
|
||||
Rect bounds = SkRectToRect(result.getBounds());
|
||||
return aTransform.TransformBounds(bounds);
|
||||
}
|
||||
|
||||
}
|
||||
|
53
gfx/2d/ScaledFontWin.cpp
Normal file
53
gfx/2d/ScaledFontWin.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Castelluccio <mar.castelluccio@studenti.unina.it>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ScaledFontWin.h"
|
||||
#include "skia/SkTypeface_win.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
ScaledFontWin::ScaledFontWin(gfxGDIFont* aFont, Float aSize)
|
||||
: ScaledFontSkia(aSize)
|
||||
{
|
||||
LOGFONT lf;
|
||||
GetObject(aFont->GetHFONT(), sizeof(LOGFONT), &lf);
|
||||
mTypeface = SkCreateTypefaceFromLOGFONT(lf);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
61
gfx/2d/ScaledFontWin.h
Normal file
61
gfx/2d/ScaledFontWin.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Castelluccio <mar.castelluccio@studenti.unina.it>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MOZILLA_GFX_SCALEDFONTWIN_H_
|
||||
#define MOZILLA_GFX_SCALEDFONTWIN_H_
|
||||
|
||||
#include "ScaledFontSkia.h"
|
||||
#include "gfxGDIFont.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class ScaledFontWin : public ScaledFontSkia
|
||||
{
|
||||
public:
|
||||
ScaledFontWin(gfxGDIFont* aFont, Float aSize);
|
||||
|
||||
virtual FontType GetType() const { return FONT_GDI; }
|
||||
|
||||
private:
|
||||
friend class DrawTargetSkia;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_GFX_SCALEDFONTWIN_H_ */
|
@ -129,6 +129,12 @@ SourceSurfaceSkia::DrawTargetWillChange()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::DrawTargetDestroyed()
|
||||
{
|
||||
mDrawTarget = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::MarkIndependent()
|
||||
{
|
||||
@ -138,6 +144,5 @@ SourceSurfaceSkia::MarkIndependent()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,7 @@ private:
|
||||
friend class DrawTargetSkia;
|
||||
|
||||
void DrawTargetWillChange();
|
||||
void DrawTargetDestroyed();
|
||||
void MarkIndependent();
|
||||
|
||||
SkBitmap mBitmap;
|
||||
|
@ -43,7 +43,7 @@
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
bool
|
||||
static inline bool
|
||||
IsOperatorBoundByMask(CompositionOp aOp) {
|
||||
switch (aOp) {
|
||||
case OP_IN:
|
||||
|
@ -91,6 +91,7 @@ enum BackendType
|
||||
enum FontType
|
||||
{
|
||||
FONT_DWRITE,
|
||||
FONT_GDI,
|
||||
FONT_MAC,
|
||||
FONT_SKIA
|
||||
};
|
||||
@ -103,6 +104,7 @@ enum NativeSurfaceType
|
||||
enum NativeFontType
|
||||
{
|
||||
NATIVE_FONT_DWRITE_FONT_FACE,
|
||||
NATIVE_FONT_GDI_FONT_FACE,
|
||||
NATIVE_FONT_MAC_FONT_FACE,
|
||||
NATIVE_FONT_SKIA_FONT_FACE
|
||||
};
|
||||
|
@ -48,9 +48,9 @@ ifdef MOZ_TREE_CAIRO
|
||||
DIRS = cairo
|
||||
endif
|
||||
|
||||
DIRS += 2d ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc
|
||||
DIRS += 2d ycbcr angle src qcms gl layers harfbuzz/src ots/src thebes ipc
|
||||
|
||||
ifeq (,$(filter-out cocoa android,$(MOZ_WIDGET_TOOLKIT)))
|
||||
ifeq (,$(filter-out cocoa android windows,$(MOZ_WIDGET_TOOLKIT)))
|
||||
DIRS += skia
|
||||
endif
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
This is the ANGLE project, from http://code.google.com/p/angleproject/
|
||||
|
||||
Current revision: r809
|
||||
Current revision: r885
|
||||
|
||||
== Applied local patches ==
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# HG changeset patch
|
||||
# Parent b5604c321da4e3b5d6b0a940d18022a827061579
|
||||
# Parent d9b887da80f5bc18854fb3e5e43637c18d2a25ae
|
||||
diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
|
||||
--- a/gfx/angle/src/libGLESv2/Texture.cpp
|
||||
+++ b/gfx/angle/src/libGLESv2/Texture.cpp
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user