Bug 569365 - Remove preprocessor.pl and replace it with Preprocessor.py. r=ted
authorMike Hommey <mh+mozilla@glandium.org>
Mon, 16 May 2011 15:51:21 +0200
changeset 69575 e7cf79fd6d3246e59c1fd722a0de0975f9e84e5f
parent 69574 357a308588cdf8382c03582e2cf38ac964eae979
child 69576 8e093acb3867bc4c1889b2298a69f3078c778b44
push id20022
push usermh@glandium.org
push dateMon, 16 May 2011 13:52:10 +0000
treeherdermozilla-central@e7cf79fd6d32 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs569365
milestone6.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 569365 - Remove preprocessor.pl and replace it with Preprocessor.py. r=ted
browser/locales/Makefile.in
config/Makefile.in
config/preprocessor.pl
config/preprocessor.txt
js/src/config/Expression.py
js/src/config/Makefile.in
js/src/config/Preprocessor.py
js/src/config/preprocessor.pl
toolkit/locales/l10n.mk
xulrunner/app/Makefile.in
xulrunner/installer/mac/Makefile.in
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -111,22 +111,22 @@ include $(topsrcdir)/toolkit/locales/l10
 
 $(STAGEDIST): $(DIST)/branding
 
 $(DIST)/branding:
 	$(NSINSTALL) -D $@
 
 libs::
 	@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
-	  $(PERL) $(topsrcdir)/config/preprocessor.pl $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
+	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
 	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \
 	fi
 install::
 	@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
-	  $(PERL) $(topsrcdir)/config/preprocessor.pl $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
+	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
 	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(DESTDIR)$(mozappdir)/defaults/existing-profile-defaults.js; \
 	fi
 
 README_FILE = $(call MERGE_FILE,README.txt)
 
 PROFILE_FILES = \
 	localstore.rdf \
 	mimeTypes.rdf \
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -116,17 +116,17 @@ ifdef MOZ_BUILD_DATE
 	printf "%s" $(MOZ_BUILD_DATE) > buildid
 else
 	$(PYTHON) $(topsrcdir)/toolkit/xre/make-platformini.py --print-buildid > buildid
 endif
 
 ifdef WRAP_SYSTEM_INCLUDES
 export::
 	if test ! -d system_wrappers; then mkdir system_wrappers; fi
-	$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) \
+	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
 		-DBUILD_STATIC_LIBS=$(BUILD_STATIC_LIBS) \
 		-DMOZ_TREE_CAIRO=$(MOZ_TREE_CAIRO) \
 		-DMOZ_TREE_PIXMAN=$(MOZ_TREE_PIXMAN) \
 		-DMOZ_ENABLE_LIBXUL=$(MOZ_ENABLE_LIBXUL) \
 		-DMOZ_NATIVE_HUNSPELL=$(MOZ_NATIVE_HUNSPELL) \
 		-DMOZ_NATIVE_BZ2=$(MOZ_NATIVE_BZ2) \
 		-DMOZ_NATIVE_ZLIB=$(MOZ_NATIVE_ZLIB) \
 		-DMOZ_NATIVE_PNG=$(MOZ_NATIVE_PNG) \
deleted file mode 100644
--- a/config/preprocessor.pl
+++ /dev/null
@@ -1,671 +0,0 @@
-#!/usr/bin/perl -w
-# -*- Mode: perl; tab-width: 4; indent-tabs-mode: nil; -*-
-#
-# Preprocessor
-# Version 1.1
-#
-# Copyright (c) 2002, 2003, 2004 by Ian Hickson
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-# Thanks to bryner and bsmedberg for suggestions.
-# Thanks to jon rekai for a patch to not require File::Spec 0.8.
-
-use strict;
-
-# takes as arguments the files to process
-# defaults to stdin
-# output to stdout
-
-my $stack = new stack;
-my $marker = '#';
-
-# command line arguments
-my @includes;
-while ($_ = $ARGV[0], defined($_) && /^-./) {
-    shift;
-    last if /^--$/os;
-    if (/^-D(.*)$/os) { 
-        for ($1) {
-            if (/^([\w\.]+)=(.*)$/os) {
-                $stack->define($1, $2);
-            } elsif (/^([\w\.]+)$/os) {
-                $stack->define($1, 1);
-            } else {
-                die "$0: invalid argument to -D: $_\n";
-            }
-        }
-    } elsif (/^-F(.*)$/os) { 
-        for ($1) {
-            if (/^(\w+)$/os) {
-                $stack->filter($1, 1);
-            } else {
-                die "$0: invalid argument to -F: $_\n";
-            }
-        }
-    } elsif (/^-I(.*)$/os) { 
-        push(@includes, $1);
-    } elsif (/^-E$/os) { 
-        foreach (keys %ENV) {
-            # define all variables that have valid names
-            $stack->define($_, $ENV{$_}) unless m/\W/;
-        }
-    } elsif (/^-d$/os) { 
-        $stack->{'dependencies'} = 1;
-    } elsif (/^--line-endings=crlf$/os) { 
-        $stack->{'lineEndings'} = "\x0D\x0A";
-    } elsif (/^--line-endings=cr$/os) { 
-        $stack->{'lineEndings'} = "\x0D";
-    } elsif (/^--line-endings=lf$/os) { 
-        $stack->{'lineEndings'} = "\x0A";
-    } elsif (/^--line-endings=(.+)$/os) { 
-        die "$0: unrecognised line ending: $1\n";
-    } elsif (/^--marker=(.)$/os) {
-        $marker = $1;
-    } else {
-        die "$0: invalid argument: $_\n";
-    }
-}
-unshift(@ARGV, '-') unless @ARGV;
-unshift(@ARGV, @includes);
-
-# do the work
-foreach (@ARGV) { include($stack, $_); }
-exit(0);
-
-########################################################################
-
-package main;
-use File::Spec;
-use File::Spec::Unix; # on all platforms, because the #include syntax is unix-based
-
-# Note: Ideally we would use File::Spec 0.8. When this becomes
-# possible, add "0.8" to the first "use" line above, then replace
-# occurrences of "::_0_8::" with "->" below. And remove the code for
-# File::Spec 0.8 much lower down the file.
-
-sub include {
-    my($stack, $filename) = @_;
-    my $directory = $stack->{'variables'}->{'DIRECTORY'};
-    if ($filename ne '-') {
-        $filename = File::Spec::_0_8::rel2abs($filename, $directory);
-        # splitpath expects forward-slash paths on windows, so we have to
-        # change the slashes if using Activestate Perl.
-        $filename =~ s?\\?/?g if "$^O" eq "MSWin32";
-        my($volume, $path) = File::Spec::_0_8::splitpath($filename);
-        $directory = File::Spec::_0_8::catpath($volume, $path, '');
-    }
-    local $stack->{'variables'}->{'DIRECTORY'} = $directory;
-    local $stack->{'variables'}->{'FILE'} = $filename;
-    local $stack->{'variables'}->{'LINE'} = 0;
-    local *FILE;
-    open(FILE, $filename) or die "Couldn't open $filename: $!\n";
-    my $lineout = 0;
-    while (<FILE>) {
-        # on cygwin, line endings are screwed up, so normalise them.
-        s/[\x0D\x0A]+$/\n/os if ($^O eq 'msys' || $^O eq 'cygwin' || "$^O" eq "MSWin32");
-        $stack->newline;
-        if (/^\Q$marker\E([a-z]+)\n?$/os) { # argumentless processing instruction
-            process($stack, $1);
-        } elsif (/^\Q$marker\E([a-z]+)\s(.*?)\n?$/os) { # processing instruction with arguments
-            process($stack, $1, $2);
-        } elsif (/^\Q$marker\E/os) { # comment
-            # ignore it
-        } elsif ($stack->enabled) {
-            next if $stack->{'dependencies'};
-
-            # set the current line number in JavaScript if necessary
-            my $linein = $stack->{'variables'}->{'LINE'};
-            if (++$lineout != $linein) {
-                if ($filename =~ /\.js(|\.in)$/o) {
-                    $stack->print("//\@line $linein \"$filename\"\n")
-                }
-                $lineout = $linein;
-            }
-
-            # print it, including any newlines
-            $stack->print(filtered($stack, $_));
-        }
-    }
-    close(FILE);
-}
-
-sub process {
-    my($stack, $instruction, @arguments) = @_;
-    my $method = 'preprocessor'->can($instruction);
-    if (not defined($method)) {
-        fatal($stack, 'unknown instruction', $instruction);
-    }
-    eval { &$method($stack, @arguments) };
-    if ($@) {
-        fatal($stack, "error evaluating $instruction:", $@);
-    }
-}
-
-sub filtered {
-    my($stack, $text) = @_;
-    foreach my $filter (sort keys %{$stack->{'filters'}}) {
-        next unless $stack->{'filters'}->{$filter};
-        my $method = 'filter'->can($filter);
-        if (not defined($method)) {
-            fatal($stack, 'unknown filter', $filter);
-        }
-        $text = eval { &$method($stack, $text) };
-        if ($@) {
-            fatal($stack, "error using $filter:", $@);
-        }                
-    }
-    return $text;
-}
-
-sub fatal {
-    my $stack = shift;
-    my $filename = $stack->{'variables'}->{'FILE'};
-    local $" = ' ';
-    print STDERR "$0:$filename:$.: @_\n";
-    exit(1);
-}
-
-
-########################################################################
-
-package stack;
-
-# condition evaluated just prior to this context was false
-use constant COND_FALSE => 0;
-
-# condition evaluated just prior to this context was true
-use constant COND_TRUE => 1;
-
-# some prior condition at this level already evaluated to true (or a
-# parent condition evaluated to false or must be ignored), so we're
-# ignoring all remaining conditions at current level (and nested
-# conditions, too)
-use constant COND_COMPLETED => 2;
-
-sub new {
-    return bless {
-        'variables' => {
-            # %ENV,
-            'LINE' => 0, # the line number in the source file
-            'DIRECTORY' => '', # current directory
-            'FILE' => '', # source filename
-            '1' => 1, # for convenience (the constant '1' is thus true)
-        },
-        'filters' => {
-            # filters
-        },
-        'values' => [], # the value of the last condition evaluated at the nth level
-        'lastConditionState' => [], # whether the condition in the nth-level context was true, false, or not applicable
-        'conditionState' => COND_TRUE,
-        'dependencies' => 0, # whether we are showing dependencies
-        'lineEndings' => "\n", # default to platform conventions
-    };
-}
-
-sub newline {
-    my $self = shift;
-    $self->{'variables'}->{'LINE'}++;
-}
-
-sub define {
-    my $self = shift;
-    my($variable, $value) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    $self->{'variables'}->{$variable} = $value;
-}
-
-sub defined {
-    my $self = shift;
-    my($variable) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    return defined($self->{'variables'}->{$variable});
-}
-
-sub undefine {
-    my $self = shift;
-    my($variable) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    delete($self->{'variables'}->{$variable});
-}
-
-sub get {
-    my $self = shift;
-    my($variable, $required) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    my $value = $self->{'variables'}->{$variable};
-    if (defined($value)) {
-        return $value;
-    } else {
-        die "variable '$variable' is not defined\n" if $required;
-        return '';
-    }
-}
-
-sub replace {
-    my $self = shift;
-    my ($value) = @_;
-
-    ${$self->{'values'}}[-1] = $value;
-    $self->{'conditionState'} = $self->{'conditionState'} != COND_FALSE
-                              ? COND_COMPLETED
-                              : $value ? COND_TRUE : COND_FALSE;
-}
-
-sub push {
-    my $self = shift;
-    my($value) = @_;
-
-    push(@{$self->{'values'}}, $value);
-    my $lastCondition = $self->{'conditionState'};
-    push(@{$self->{'lastConditionState'}}, $lastCondition);
-    $self->{'conditionState'} = $lastCondition != COND_TRUE
-                              ? COND_COMPLETED
-                              : $value ? COND_TRUE : COND_FALSE;
-}
-
-sub pop {
-    my $self = shift;
-    $self->{'conditionState'} = pop(@{$self->{'lastConditionState'}});
-    return pop(@{$self->{'values'}});
-}
-
-sub enabled {
-    my $self = shift;
-    return $self->{'conditionState'} == COND_TRUE;
-}
-
-sub disabled {
-    my $self = shift;
-    return $self->{'conditionState'} != COND_TRUE;
-}
-
-sub filter {
-    my $self = shift;
-    my($filter, $value) = @_;
-    die "not a valid filter name: '$filter'\n" if $filter =~ m/\W/;
-    $self->{'filters'}->{$filter} = $value;
-}
-
-sub expand {
-    my $self = shift;
-    my($line) = @_;
-    $line =~ s/__(\w+)__/$self->get($1)/gose;
-    return $line;
-}
-
-sub print {
-    my $self = shift;
-    return if $self->{'dependencies'};
-    foreach my $line (@_) {
-        if (chomp $line) {
-            CORE::print("$line$self->{'lineEndings'}");
-        } else {
-            CORE::print($line);
-        }
-    }
-}
-
-sub visit {
-    my $self = shift;
-    my($filename) = @_;
-    my $directory = $stack->{'variables'}->{'DIRECTORY'};
-    $filename = File::Spec::_0_8::abs2rel(File::Spec::_0_8::rel2abs($filename, $directory));
-    CORE::print("$filename\n");
-}
-
-########################################################################
-
-package preprocessor;
-
-sub define {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $argument = shift;
-    for ($argument) {
-        /^(\w+)\s(.*)$/os && do {
-            return $stack->define($1, $2);
-        };
-        /^(\w+)$/os && do {
-            return $stack->define($1, 1);
-        };
-        die "invalid argument: '$_'\n";
-    }
-}
-
-sub undef {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    $stack->undefine(@_);
-}
-
-sub ifdef {
-    my $stack = shift;
-    my $variable = shift;
-    my $replace = defined(shift);
-    die "argument expected\n" unless defined($variable);
-    if ($replace) {
-        $stack->replace($stack->defined($variable));
-    } else {
-        $stack->push($stack->defined($variable));
-    }
-}
-
-sub ifndef {
-    my $stack = shift;
-    my $variable = shift;
-    my $replace = defined(shift);
-    die "argument expected\n" unless defined($variable);
-    if ($replace) {
-        $stack->replace(not $stack->defined($variable));
-    } else {
-        $stack->push(not $stack->defined($variable));
-    }
-}
-
-sub if {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    my $argument = shift;
-    my $replace = defined(shift);
-    for ($argument) {
-        /^(\w+)==(.*)$/os && do {
-            # equality
-            if ($replace) {
-                return $stack->replace($stack->get($1) eq $2);
-            } else {
-                return $stack->push($stack->get($1) eq $2);
-            }
-        };
-        /^(\w+)!=(.*)$/os && do {
-            # inequality
-            if ($replace) {
-                return $stack->replace($stack->get($1) ne $2);
-            } else {
-                return $stack->push($stack->get($1) ne $2);
-            }
-        };
-        /^(\w+)$/os && do {
-            # true value
-            if ($replace) {
-                return $stack->replace($stack->get($1));
-            } else {
-                return $stack->push($stack->get($1));
-            }
-        };
-        /^!(\w+)$/os && do {
-            # false value
-            if ($replace) {
-                return $stack->replace(not $stack->get($1));
-            } else {
-                return $stack->push(not $stack->get($1));
-            }
-        };
-        die "invalid argument: '$_'\n";
-    }
-}
-
-sub else {
-    my $stack = shift;
-    die "argument unexpected\n" if @_;
-    $stack->replace(1);
-}
-
-sub elif {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    &if($stack, @_, 1);
-}
-
-sub elifdef {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    &ifdef($stack, @_, 1);
-}
-
-sub elifndef {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    &ifndef($stack, @_, 1);
-}
-
-sub endif {
-    my $stack = shift;
-    die "argument unexpected\n" if @_;
-    $stack->pop;
-}
-
-sub error {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $line = $stack->expand(@_);
-    die "$line\n";
-}
-
-sub expand {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $line = $stack->expand(@_);
-    $stack->print("$line\n");
-}
-
-sub literal {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $line = shift;
-    $stack->print("$line\n");
-}
-
-sub include {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $filename = File::Spec::_0_8::catpath(File::Spec::_0_8::splitpath(@_));
-    if ($stack->{'dependencies'}) {
-        $stack->visit($filename);
-    } else {
-        main::include($stack, $filename);
-    }
-}
-
-sub includesubst {
-    my ($stack, $filename) = @_;
-    return if $stack->disabled;
-    die "argument expected\n" unless $filename;
-    $filename =~ s/@(\w+)@/$stack->get($1, 1)/gose;
-    $filename = File::Spec::_0_8::catpath(File::Spec::_0_8::splitpath($filename));
-    if ($stack->{'dependencies'}) {
-        $stack->visit($filename);
-    } else {
-        main::include($stack, $filename);
-    }
-}
-
-sub filter {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    foreach (split(/\s/os, shift)) {
-        $stack->filter($_, 1);
-    }
-}
-
-sub unfilter {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    foreach (split(/\s/os, shift)) {
-        $stack->filter($_, 0);
-    }
-}
-
-
-########################################################################
-
-package filter;
-
-sub emptyLines {
-    my($stack, $text) = @_;
-    $text = "" if $text eq "\n";
-    return $text;
-}
-
-sub spaces {
-    my($stack, $text) = @_;
-    $text =~ s/ +/ /gos; # middle spaces
-    $text =~ s/^ //gos; # start spaces
-    $text =~ s/ (\n?)$/$1/gos; # end spaces
-    return $text;
-}
-
-sub slashslash {
-    my($stack, $text) = @_;
-    $text =~ s|//.*?(\n?)$|$1|gos;
-    return $text;
-}
-
-sub substitution {
-    my($stack, $text) = @_;
-    $text =~ s/@(\w+)@/$stack->get($1, 1)/gose;
-    return $text;
-}
-
-sub attemptSubstitution {
-    my($stack, $text) = @_;
-    $text =~ s/@(\w+)@/$stack->get($1, 0)/gose;
-    return $text;
-}
-
-########################################################################
-
-########################################################################
-# This code is from File::Spec::Unix 0.8.
-# It is not considered a part of the preprocessor.pl source file
-# This code is licensed under the same license as File::Spec itself.
-
-package File::Spec::_0_8;
-
-use Cwd;
-
-sub rel2abs {
-    my ($path, $base) = @_;
-    if ( ! File::Spec->file_name_is_absolute( $path ) ) {
-        if ( !defined( $base ) || $base eq '' ) {
-            $base = cwd() ;
-        } elsif ( ! File::Spec->file_name_is_absolute( $base ) ) {
-            $base = rel2abs( $base );
-        } else {
-            $base = File::Spec->canonpath( $base );
-        }
-        $path = File::Spec->catdir( $base, $path );
-    }
-    return File::Spec->canonpath( $path );
-}
-
-sub splitdir {
-    return split m|/|, $_[1], -1;  # Preserve trailing fields
-}
-
-sub splitpath {
-    my ($path, $nofile) = @_;
-
-    my ($volume,$directory,$file) = ('','','');
-
-    if ( $nofile ) {
-        $directory = $path;
-    }
-    else {
-        $path =~ m|^ ( (?: .* / (?: \.\.?\Z(?!\n) )? )? ) ([^/]*) |xs;
-        $directory = $1;
-        $file      = $2;
-    }
-
-    return ($volume,$directory,$file);
-}
-
-sub catpath {
-    my ($volume,$directory,$file) = @_;
-
-    if ( $directory ne ''                && 
-         $file ne ''                     && 
-         substr( $directory, -1 ) ne '/' && 
-         substr( $file, 0, 1 ) ne '/' 
-    ) {
-        $directory .= "/$file" ;
-    }
-    else {
-        $directory .= $file ;
-    }
-
-    return $directory ;
-}
-
-sub abs2rel {
-    my($path,$base) = @_;
-
-    # Clean up $path
-    if ( ! File::Spec->file_name_is_absolute( $path ) ) {
-        $path = rel2abs( $path ) ;
-    }
-    else {
-        $path = File::Spec->canonpath( $path ) ;
-    }
-
-    # Figure out the effective $base and clean it up.
-    if ( !defined( $base ) || $base eq '' ) {
-        $base = cwd();
-    }
-    elsif ( ! File::Spec->file_name_is_absolute( $base ) ) {
-        $base = rel2abs( $base ) ;
-    }
-    else {
-        $base = File::Spec->canonpath( $base ) ;
-    }
-
-    # Now, remove all leading components that are the same
-    my @pathchunks = File::Spec::_0_8::splitdir( $path);
-    my @basechunks = File::Spec::_0_8::splitdir( $base);
-
-    while (@pathchunks && @basechunks && $pathchunks[0] eq $basechunks[0]) {
-        shift @pathchunks ;
-        shift @basechunks ;
-    }
-
-    $path = CORE::join( '/', @pathchunks );
-    $base = CORE::join( '/', @basechunks );
-
-    # $base now contains the directories the resulting relative path 
-    # must ascend out of before it can descend to $path_directory.  So, 
-    # replace all names with $parentDir
-    $base =~ s|[^/]+|..|g ;
-
-    # Glue the two together, using a separator if necessary, and preventing an
-    # empty result.
-    if ( $path ne '' && $base ne '' ) {
-        $path = "$base/$path" ;
-    } else {
-        $path = "$base$path" ;
-    }
-
-    return File::Spec->canonpath( $path ) ;
-}
-
-# End code from File::Spec::Unix 0.8.
-########################################################################
deleted file mode 100644
--- a/config/preprocessor.txt
+++ /dev/null
@@ -1,252 +0,0 @@
-Preprocessor
-============
-
-This is a very primitive line based preprocessor, for times when using
-a C preprocessor isn't an option.
-
-
-Instructions
-------------
-
-Any line starting with a hash # and a letter is considered to be a
-preprocessor instruction. Other lines starting with a hash are ignored
-as comments.
-
-The following preprocessor instructions are recognised.
-
-   #define VARIABLE
-   #define VARIABLE STRING
-   #undef VARIABLE
-   #ifdef VARIABLE
-   #ifndef VARIABLE
-   #if VARIABLE
-   #if !VARIABLE
-   #if VARIABLE==STRING
-   #if VARIABLE!=STRING
-   #else
-   #elifdef VARIABLE
-   #elifndef VARIABLE
-   #elif VARIABLE
-   #elif !VARIABLE
-   #elif VARIABLE==STRING
-   #elif VARIABLE!=STRING
-   #endif
-   #error STRING
-   #include FILENAME
-   #includesubst @VAR@FILENAME
-   #expand STRING
-   #literal STRING
-   #filter FILTER1 FILTER2 ... FILTERn
-   #unfilter FILTER1 FILTER2 ... FILTERn
-
-Whitespace is significant -- for instance, '#define TEST foo' is not
-the same as '#define TEST foo '. The first defines TEST to be a three
-character string, the second defines it to be four characters long.
-
-The conditionals (#ifdef, #ifndef, #if, #else, #elifdef, #elifndef,
-#elif, #endif) can be nested to arbitrary depth.
-
-The #elifdef, #elifndef, and #elif instructions are equivalent to
-#else instructions combined with the relevant conditional.  For
-example,
-
-   #ifdef foo
-      block 1
-   #elifdef bar
-      block 2
-   #endif
-
-...could be written as:
-
-   #ifdef foo
-      block 1
-   #else
-   #ifdef bar
-      block 2
-   #endif
-   #endif
-
-An #else block is included if all previous conditions were false, and
-is equivalent to #elif 1, i.e.:
-
-   #ifdef foo
-      foo is defined
-   #else
-      foo is not defined
-   #endif
-
-...is equivalent to:
-   
-   #ifdef foo
-      foo is defined
-   #elif 1
-      foo is not defined
-   #endif
-
-#else is not required to be the last condition in an if/el*/endif
-series.  In particular, along with #else's equivalence to #elif 1
-this means that the following holds:
-
-   #if 0
-      never included
-   #else
-      always included
-   #else
-      never included
-   #elif 1
-      never included
-   #endif
-
-The #error instruction stops execution at this point with a fatal
-error. The error message will include the given STRING.
-
-The #include instruction causes the specified file FILENAME to be
-recursively processed, as if it was inserted at the current position
-in the file. This means conditionals can be started in one file and
-ended in another, although this practice is strongly discouraged.
-There is no predefined limit to the depth of #includes, and there is
-no restriction on self-inclusion, so care should be taken to avoid
-infinite loops.
-
-The #includesubst instruction behaves like #include, except that any
-variables in @ATSIGNS@ are expanded, like the substitution filter.
-
-The #expand instruction will print the given STRING with variable
-substitutions. See the substitution section below.
-
-The #literal instruction will print the given STRING with a newline,
-with absolutely no other fixups, guaranteed. This can be used to
-output lines starting with a #, which would otherwise be stripped out
-as comments.
-
-The #filter instruction enables the specified filters. You can turn
-off filters using #unfilter. See the Filters section below.
-
-
-Variables
----------
-
-Variables consist of any alphanumeric string. They are defined using
-the -D command line argument and the #define instruction.
-
-To define all environment variables, so that you can use __HOME__,
-etc, with #expand, use the -E argument. Note that arguments that use
-non-word characters (like "!") are not included. (In particular,
-cygwin is known to include all kinds of weird characters in its
-environment variables.)
-
-Two special variables are predefined, FILE and LINE. They can be
-passed to #define and #undef, but FILE is automatically redefined at
-the top of each file, and LINE is increased by one at the start of
-each line.
-
-The variable '1' is predefined with value 1. The variable '0' is not
-defined. This allows constructs such as
-
-   #if 0
-   ...
-   #endif
-
-...to be used to quickly comment out large sections. Note, however,
-that these are simply variables, and can be redefined. This is
-strongly discouraged.
-
-
-Substitution
-------------
-
-In any line starting with the instruction #expand, variable names
-contained between double underscores, like __THIS__, are expanded to
-their string values, or the empty string if they are not defined.
-
-For example to print the current filename:
-
-   #expand <!-- This file is automatically generated from __FILE__ -->
-
-Normal lines are not affected.
-
-See also the substitution filter below.
-
-
-Filters
--------
-
-The following filters are supported:
-
-   emptyLines
-     Strips blank lines from the output.
-
-   slashslash
-     Strips everything from the first two consecutive slash (/)
-     characters until the end of the line.
-
-   spaces
-     Collapses sequences of spaces into a single space.
-
-   substitution
-     Replaces occurrences of "@foo@" by the value of the variable
-     "foo". If @foo@ is not defined, the preprocessor will terminate
-     with a fatal error.
-
-   attemptSubstitution
-     Replaces occurrences of "@foo@" by the value of the variable
-     "foo". If @foo@ is not defined, the empty string is used instead.
-
-Filters are run in alphabetical order, on a per-line basis.
-
-
-Command Line Arguments
-----------------------
-
-Syntax:
-   preprocessor.pl [-Dvariable[=value]] [-E] [-Ffilter]
-                   [-Ifilename] [-d] [--marker=<c>] [--] filenames...
-
--Dvariable
-   Set variable to 1 before processing the files.
-
--Dvariable=value
-   Set variable to value before processing the files.
-
--E
-   Define all environment variables.
-
--Ffilter
-   Enables the specified filter.
-
--Ifilename
-   Include filename before any other files.
-
--d
-   Run through the files on the command line, listing the files they
-   depend on given the specified environment variables and filters.
-   Doesn't recurse into those files. The output is given as one
-   dependency per line, and filenames are given relative to the
-   current directory.
-
---line-endings=type
-   Set the type of line endings to use. "type" can be either "cr",
-   "lf", or "crlf". The default is whatever your platform uses for
-   perl's "\n" character.
-
---marker=<c>
-   Use the character <c> instead of '#' as the marker for preprocessor
-   instructions.
-
---
-   Indicates the end of non-filename arguments.
-
--
-   Indicates that input should come from standard input.
-
-If no filenames are provided, standard input is used instead. If many
-files are provided, they are processed sequentially, as if they were
-one big file. -I files are handled before the other files, in the
-order specified, but after handling any -D, -E, -F, and -d arguments.
-
-
-Contact Details
----------------
-
-Feel free to e-mail me if you have any questions:
-Ian Hickson <preprocessor@software.hixie.ch>
copy from config/Expression.py
copy to js/src/config/Expression.py
--- a/js/src/config/Makefile.in
+++ b/js/src/config/Makefile.in
@@ -88,17 +88,17 @@ HOST_CFLAGS += -DUNICODE -D_UNICODE
 export:: $(TARGETS)
 ifdef HOST_PROGRAM
 	$(INSTALL) $(HOST_PROGRAM) $(DIST)/bin
 endif
 
 ifdef WRAP_SYSTEM_INCLUDES
 export::
 	if test ! -d system_wrappers_js; then mkdir system_wrappers_js; fi
-	$(PERL) $(srcdir)/preprocessor.pl $(DEFINES) $(ACDEFINES) \
+	$(PYTHON) $(srcdir)/Preprocessor.py $(DEFINES) $(ACDEFINES) \
 		-DBUILD_STATIC_LIBS=$(BUILD_STATIC_LIBS) \
 		$(srcdir)/system-headers | $(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers_js
 	$(INSTALL) system_wrappers_js $(DIST)
 
 GARBAGE_DIRS += system_wrappers_js
 endif
 
 GARBAGE += $(srcdir)/*.pyc *.pyc
copy from config/Preprocessor.py
copy to js/src/config/Preprocessor.py
deleted file mode 100644
--- a/js/src/config/preprocessor.pl
+++ /dev/null
@@ -1,671 +0,0 @@
-#!/usr/bin/perl -w
-# -*- Mode: perl; tab-width: 4; indent-tabs-mode: nil; -*-
-#
-# Preprocessor
-# Version 1.1
-#
-# Copyright (c) 2002, 2003, 2004 by Ian Hickson
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-# Thanks to bryner and bsmedberg for suggestions.
-# Thanks to jon rekai for a patch to not require File::Spec 0.8.
-
-use strict;
-
-# takes as arguments the files to process
-# defaults to stdin
-# output to stdout
-
-my $stack = new stack;
-my $marker = '#';
-
-# command line arguments
-my @includes;
-while ($_ = $ARGV[0], defined($_) && /^-./) {
-    shift;
-    last if /^--$/os;
-    if (/^-D(.*)$/os) { 
-        for ($1) {
-            if (/^([\w\.]+)=(.*)$/os) {
-                $stack->define($1, $2);
-            } elsif (/^([\w\.]+)$/os) {
-                $stack->define($1, 1);
-            } else {
-                die "$0: invalid argument to -D: $_\n";
-            }
-        }
-    } elsif (/^-F(.*)$/os) { 
-        for ($1) {
-            if (/^(\w+)$/os) {
-                $stack->filter($1, 1);
-            } else {
-                die "$0: invalid argument to -F: $_\n";
-            }
-        }
-    } elsif (/^-I(.*)$/os) { 
-        push(@includes, $1);
-    } elsif (/^-E$/os) { 
-        foreach (keys %ENV) {
-            # define all variables that have valid names
-            $stack->define($_, $ENV{$_}) unless m/\W/;
-        }
-    } elsif (/^-d$/os) { 
-        $stack->{'dependencies'} = 1;
-    } elsif (/^--line-endings=crlf$/os) { 
-        $stack->{'lineEndings'} = "\x0D\x0A";
-    } elsif (/^--line-endings=cr$/os) { 
-        $stack->{'lineEndings'} = "\x0D";
-    } elsif (/^--line-endings=lf$/os) { 
-        $stack->{'lineEndings'} = "\x0A";
-    } elsif (/^--line-endings=(.+)$/os) { 
-        die "$0: unrecognised line ending: $1\n";
-    } elsif (/^--marker=(.)$/os) {
-        $marker = $1;
-    } else {
-        die "$0: invalid argument: $_\n";
-    }
-}
-unshift(@ARGV, '-') unless @ARGV;
-unshift(@ARGV, @includes);
-
-# do the work
-foreach (@ARGV) { include($stack, $_); }
-exit(0);
-
-########################################################################
-
-package main;
-use File::Spec;
-use File::Spec::Unix; # on all platforms, because the #include syntax is unix-based
-
-# Note: Ideally we would use File::Spec 0.8. When this becomes
-# possible, add "0.8" to the first "use" line above, then replace
-# occurrences of "::_0_8::" with "->" below. And remove the code for
-# File::Spec 0.8 much lower down the file.
-
-sub include {
-    my($stack, $filename) = @_;
-    my $directory = $stack->{'variables'}->{'DIRECTORY'};
-    if ($filename ne '-') {
-        $filename = File::Spec::_0_8::rel2abs($filename, $directory);
-        # splitpath expects forward-slash paths on windows, so we have to
-        # change the slashes if using Activestate Perl.
-        $filename =~ s?\\?/?g if "$^O" eq "MSWin32";
-        my($volume, $path) = File::Spec::_0_8::splitpath($filename);
-        $directory = File::Spec::_0_8::catpath($volume, $path, '');
-    }
-    local $stack->{'variables'}->{'DIRECTORY'} = $directory;
-    local $stack->{'variables'}->{'FILE'} = $filename;
-    local $stack->{'variables'}->{'LINE'} = 0;
-    local *FILE;
-    open(FILE, $filename) or die "Couldn't open $filename: $!\n";
-    my $lineout = 0;
-    while (<FILE>) {
-        # on cygwin, line endings are screwed up, so normalise them.
-        s/[\x0D\x0A]+$/\n/os if ($^O eq 'msys' || $^O eq 'cygwin' || "$^O" eq "MSWin32");
-        $stack->newline;
-        if (/^\Q$marker\E([a-z]+)\n?$/os) { # argumentless processing instruction
-            process($stack, $1);
-        } elsif (/^\Q$marker\E([a-z]+)\s(.*?)\n?$/os) { # processing instruction with arguments
-            process($stack, $1, $2);
-        } elsif (/^\Q$marker\E/os) { # comment
-            # ignore it
-        } elsif ($stack->enabled) {
-            next if $stack->{'dependencies'};
-
-            # set the current line number in JavaScript if necessary
-            my $linein = $stack->{'variables'}->{'LINE'};
-            if (++$lineout != $linein) {
-                if ($filename =~ /\.js(|\.in)$/o) {
-                    $stack->print("//\@line $linein \"$filename\"\n")
-                }
-                $lineout = $linein;
-            }
-
-            # print it, including any newlines
-            $stack->print(filtered($stack, $_));
-        }
-    }
-    close(FILE);
-}
-
-sub process {
-    my($stack, $instruction, @arguments) = @_;
-    my $method = 'preprocessor'->can($instruction);
-    if (not defined($method)) {
-        fatal($stack, 'unknown instruction', $instruction);
-    }
-    eval { &$method($stack, @arguments) };
-    if ($@) {
-        fatal($stack, "error evaluating $instruction:", $@);
-    }
-}
-
-sub filtered {
-    my($stack, $text) = @_;
-    foreach my $filter (sort keys %{$stack->{'filters'}}) {
-        next unless $stack->{'filters'}->{$filter};
-        my $method = 'filter'->can($filter);
-        if (not defined($method)) {
-            fatal($stack, 'unknown filter', $filter);
-        }
-        $text = eval { &$method($stack, $text) };
-        if ($@) {
-            fatal($stack, "error using $filter:", $@);
-        }                
-    }
-    return $text;
-}
-
-sub fatal {
-    my $stack = shift;
-    my $filename = $stack->{'variables'}->{'FILE'};
-    local $" = ' ';
-    print STDERR "$0:$filename:$.: @_\n";
-    exit(1);
-}
-
-
-########################################################################
-
-package stack;
-
-# condition evaluated just prior to this context was false
-use constant COND_FALSE => 0;
-
-# condition evaluated just prior to this context was true
-use constant COND_TRUE => 1;
-
-# some prior condition at this level already evaluated to true (or a
-# parent condition evaluated to false or must be ignored), so we're
-# ignoring all remaining conditions at current level (and nested
-# conditions, too)
-use constant COND_COMPLETED => 2;
-
-sub new {
-    return bless {
-        'variables' => {
-            # %ENV,
-            'LINE' => 0, # the line number in the source file
-            'DIRECTORY' => '', # current directory
-            'FILE' => '', # source filename
-            '1' => 1, # for convenience (the constant '1' is thus true)
-        },
-        'filters' => {
-            # filters
-        },
-        'values' => [], # the value of the last condition evaluated at the nth level
-        'lastConditionState' => [], # whether the condition in the nth-level context was true, false, or not applicable
-        'conditionState' => COND_TRUE,
-        'dependencies' => 0, # whether we are showing dependencies
-        'lineEndings' => "\n", # default to platform conventions
-    };
-}
-
-sub newline {
-    my $self = shift;
-    $self->{'variables'}->{'LINE'}++;
-}
-
-sub define {
-    my $self = shift;
-    my($variable, $value) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    $self->{'variables'}->{$variable} = $value;
-}
-
-sub defined {
-    my $self = shift;
-    my($variable) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    return defined($self->{'variables'}->{$variable});
-}
-
-sub undefine {
-    my $self = shift;
-    my($variable) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    delete($self->{'variables'}->{$variable});
-}
-
-sub get {
-    my $self = shift;
-    my($variable, $required) = @_;
-    die "not a valid variable name: '$variable'\n" if $variable =~ m/[^\w\.]/;
-    my $value = $self->{'variables'}->{$variable};
-    if (defined($value)) {
-        return $value;
-    } else {
-        die "variable '$variable' is not defined\n" if $required;
-        return '';
-    }
-}
-
-sub replace {
-    my $self = shift;
-    my ($value) = @_;
-
-    ${$self->{'values'}}[-1] = $value;
-    $self->{'conditionState'} = $self->{'conditionState'} != COND_FALSE
-                              ? COND_COMPLETED
-                              : $value ? COND_TRUE : COND_FALSE;
-}
-
-sub push {
-    my $self = shift;
-    my($value) = @_;
-
-    push(@{$self->{'values'}}, $value);
-    my $lastCondition = $self->{'conditionState'};
-    push(@{$self->{'lastConditionState'}}, $lastCondition);
-    $self->{'conditionState'} = $lastCondition != COND_TRUE
-                              ? COND_COMPLETED
-                              : $value ? COND_TRUE : COND_FALSE;
-}
-
-sub pop {
-    my $self = shift;
-    $self->{'conditionState'} = pop(@{$self->{'lastConditionState'}});
-    return pop(@{$self->{'values'}});
-}
-
-sub enabled {
-    my $self = shift;
-    return $self->{'conditionState'} == COND_TRUE;
-}
-
-sub disabled {
-    my $self = shift;
-    return $self->{'conditionState'} != COND_TRUE;
-}
-
-sub filter {
-    my $self = shift;
-    my($filter, $value) = @_;
-    die "not a valid filter name: '$filter'\n" if $filter =~ m/\W/;
-    $self->{'filters'}->{$filter} = $value;
-}
-
-sub expand {
-    my $self = shift;
-    my($line) = @_;
-    $line =~ s/__(\w+)__/$self->get($1)/gose;
-    return $line;
-}
-
-sub print {
-    my $self = shift;
-    return if $self->{'dependencies'};
-    foreach my $line (@_) {
-        if (chomp $line) {
-            CORE::print("$line$self->{'lineEndings'}");
-        } else {
-            CORE::print($line);
-        }
-    }
-}
-
-sub visit {
-    my $self = shift;
-    my($filename) = @_;
-    my $directory = $stack->{'variables'}->{'DIRECTORY'};
-    $filename = File::Spec::_0_8::abs2rel(File::Spec::_0_8::rel2abs($filename, $directory));
-    CORE::print("$filename\n");
-}
-
-########################################################################
-
-package preprocessor;
-
-sub define {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $argument = shift;
-    for ($argument) {
-        /^(\w+)\s(.*)$/os && do {
-            return $stack->define($1, $2);
-        };
-        /^(\w+)$/os && do {
-            return $stack->define($1, 1);
-        };
-        die "invalid argument: '$_'\n";
-    }
-}
-
-sub undef {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    $stack->undefine(@_);
-}
-
-sub ifdef {
-    my $stack = shift;
-    my $variable = shift;
-    my $replace = defined(shift);
-    die "argument expected\n" unless defined($variable);
-    if ($replace) {
-        $stack->replace($stack->defined($variable));
-    } else {
-        $stack->push($stack->defined($variable));
-    }
-}
-
-sub ifndef {
-    my $stack = shift;
-    my $variable = shift;
-    my $replace = defined(shift);
-    die "argument expected\n" unless defined($variable);
-    if ($replace) {
-        $stack->replace(not $stack->defined($variable));
-    } else {
-        $stack->push(not $stack->defined($variable));
-    }
-}
-
-sub if {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    my $argument = shift;
-    my $replace = defined(shift);
-    for ($argument) {
-        /^(\w+)==(.*)$/os && do {
-            # equality
-            if ($replace) {
-                return $stack->replace($stack->get($1) eq $2);
-            } else {
-                return $stack->push($stack->get($1) eq $2);
-            }
-        };
-        /^(\w+)!=(.*)$/os && do {
-            # inequality
-            if ($replace) {
-                return $stack->replace($stack->get($1) ne $2);
-            } else {
-                return $stack->push($stack->get($1) ne $2);
-            }
-        };
-        /^(\w+)$/os && do {
-            # true value
-            if ($replace) {
-                return $stack->replace($stack->get($1));
-            } else {
-                return $stack->push($stack->get($1));
-            }
-        };
-        /^!(\w+)$/os && do {
-            # false value
-            if ($replace) {
-                return $stack->replace(not $stack->get($1));
-            } else {
-                return $stack->push(not $stack->get($1));
-            }
-        };
-        die "invalid argument: '$_'\n";
-    }
-}
-
-sub else {
-    my $stack = shift;
-    die "argument unexpected\n" if @_;
-    $stack->replace(1);
-}
-
-sub elif {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    &if($stack, @_, 1);
-}
-
-sub elifdef {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    &ifdef($stack, @_, 1);
-}
-
-sub elifndef {
-    my $stack = shift;
-    die "argument expected\n" unless @_;
-    &ifndef($stack, @_, 1);
-}
-
-sub endif {
-    my $stack = shift;
-    die "argument unexpected\n" if @_;
-    $stack->pop;
-}
-
-sub error {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $line = $stack->expand(@_);
-    die "$line\n";
-}
-
-sub expand {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $line = $stack->expand(@_);
-    $stack->print("$line\n");
-}
-
-sub literal {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $line = shift;
-    $stack->print("$line\n");
-}
-
-sub include {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    my $filename = File::Spec::_0_8::catpath(File::Spec::_0_8::splitpath(@_));
-    if ($stack->{'dependencies'}) {
-        $stack->visit($filename);
-    } else {
-        main::include($stack, $filename);
-    }
-}
-
-sub includesubst {
-    my ($stack, $filename) = @_;
-    return if $stack->disabled;
-    die "argument expected\n" unless $filename;
-    $filename =~ s/@(\w+)@/$stack->get($1, 1)/gose;
-    $filename = File::Spec::_0_8::catpath(File::Spec::_0_8::splitpath($filename));
-    if ($stack->{'dependencies'}) {
-        $stack->visit($filename);
-    } else {
-        main::include($stack, $filename);
-    }
-}
-
-sub filter {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    foreach (split(/\s/os, shift)) {
-        $stack->filter($_, 1);
-    }
-}
-
-sub unfilter {
-    my $stack = shift;
-    return if $stack->disabled;
-    die "argument expected\n" unless @_;
-    foreach (split(/\s/os, shift)) {
-        $stack->filter($_, 0);
-    }
-}
-
-
-########################################################################
-
-package filter;
-
-sub emptyLines {
-    my($stack, $text) = @_;
-    $text = "" if $text eq "\n";
-    return $text;
-}
-
-sub spaces {
-    my($stack, $text) = @_;
-    $text =~ s/ +/ /gos; # middle spaces
-    $text =~ s/^ //gos; # start spaces
-    $text =~ s/ (\n?)$/$1/gos; # end spaces
-    return $text;
-}
-
-sub slashslash {
-    my($stack, $text) = @_;
-    $text =~ s|//.*?(\n?)$|$1|gos;
-    return $text;
-}
-
-sub substitution {
-    my($stack, $text) = @_;
-    $text =~ s/@(\w+)@/$stack->get($1, 1)/gose;
-    return $text;
-}
-
-sub attemptSubstitution {
-    my($stack, $text) = @_;
-    $text =~ s/@(\w+)@/$stack->get($1, 0)/gose;
-    return $text;
-}
-
-########################################################################
-
-########################################################################
-# This code is from File::Spec::Unix 0.8.
-# It is not considered a part of the preprocessor.pl source file
-# This code is licensed under the same license as File::Spec itself.
-
-package File::Spec::_0_8;
-
-use Cwd;
-
-sub rel2abs {
-    my ($path, $base) = @_;
-    if ( ! File::Spec->file_name_is_absolute( $path ) ) {
-        if ( !defined( $base ) || $base eq '' ) {
-            $base = cwd() ;
-        } elsif ( ! File::Spec->file_name_is_absolute( $base ) ) {
-            $base = rel2abs( $base );
-        } else {
-            $base = File::Spec->canonpath( $base );
-        }
-        $path = File::Spec->catdir( $base, $path );
-    }
-    return File::Spec->canonpath( $path );
-}
-
-sub splitdir {
-    return split m|/|, $_[1], -1;  # Preserve trailing fields
-}
-
-sub splitpath {
-    my ($path, $nofile) = @_;
-
-    my ($volume,$directory,$file) = ('','','');
-
-    if ( $nofile ) {
-        $directory = $path;
-    }
-    else {
-        $path =~ m|^ ( (?: .* / (?: \.\.?\Z(?!\n) )? )? ) ([^/]*) |xs;
-        $directory = $1;
-        $file      = $2;
-    }
-
-    return ($volume,$directory,$file);
-}
-
-sub catpath {
-    my ($volume,$directory,$file) = @_;
-
-    if ( $directory ne ''                && 
-         $file ne ''                     && 
-         substr( $directory, -1 ) ne '/' && 
-         substr( $file, 0, 1 ) ne '/' 
-    ) {
-        $directory .= "/$file" ;
-    }
-    else {
-        $directory .= $file ;
-    }
-
-    return $directory ;
-}
-
-sub abs2rel {
-    my($path,$base) = @_;
-
-    # Clean up $path
-    if ( ! File::Spec->file_name_is_absolute( $path ) ) {
-        $path = rel2abs( $path ) ;
-    }
-    else {
-        $path = File::Spec->canonpath( $path ) ;
-    }
-
-    # Figure out the effective $base and clean it up.
-    if ( !defined( $base ) || $base eq '' ) {
-        $base = cwd();
-    }
-    elsif ( ! File::Spec->file_name_is_absolute( $base ) ) {
-        $base = rel2abs( $base ) ;
-    }
-    else {
-        $base = File::Spec->canonpath( $base ) ;
-    }
-
-    # Now, remove all leading components that are the same
-    my @pathchunks = File::Spec::_0_8::splitdir( $path);
-    my @basechunks = File::Spec::_0_8::splitdir( $base);
-
-    while (@pathchunks && @basechunks && $pathchunks[0] eq $basechunks[0]) {
-        shift @pathchunks ;
-        shift @basechunks ;
-    }
-
-    $path = CORE::join( '/', @pathchunks );
-    $base = CORE::join( '/', @basechunks );
-
-    # $base now contains the directories the resulting relative path 
-    # must ascend out of before it can descend to $path_directory.  So, 
-    # replace all names with $parentDir
-    $base =~ s|[^/]+|..|g ;
-
-    # Glue the two together, using a separator if necessary, and preventing an
-    # empty result.
-    if ( $path ne '' && $base ne '' ) {
-        $path = "$base/$path" ;
-    } else {
-        $path = "$base$path" ;
-    }
-
-    return File::Spec->canonpath( $path ) ;
-}
-
-# End code from File::Spec::Unix 0.8.
-########################################################################
--- a/toolkit/locales/l10n.mk
+++ b/toolkit/locales/l10n.mk
@@ -184,17 +184,17 @@ TK_DEFINES = $(firstword \
    $(MOZILLA_DIR)/toolkit/locales/en-US/defines.inc)
 
 langpack-%: LANGPACK_FILE=$(_ABS_DIST)/$(PKG_LANGPACK_PATH)$(PKG_LANGPACK_BASENAME).xpi
 langpack-%: AB_CD=$*
 langpack-%: XPI_NAME=locale-$*
 langpack-%: libs-%
 	@echo "Making langpack $(LANGPACK_FILE)"
 	$(NSINSTALL) -D $(DIST)/$(PKG_LANGPACK_PATH)
-	$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) -I$(TK_DEFINES) -I$(APP_DEFINES) $(srcdir)/generic/install.rdf > $(FINAL_TARGET)/install.rdf
+	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) -I$(TK_DEFINES) -I$(APP_DEFINES) $(srcdir)/generic/install.rdf > $(FINAL_TARGET)/install.rdf
 	cd $(DIST)/xpi-stage/locale-$(AB_CD) && \
 	  $(ZIP) -r9D $(LANGPACK_FILE) install.rdf chrome chrome.manifest -x chrome/$(AB_CD).manifest
 
 
 # This variable is to allow the wget-en-US target to know which ftp server to download from
 ifndef EN_US_BINARY_URL 
 EN_US_BINARY_URL = $(error You must set EN_US_BINARY_URL)
 endif
--- a/xulrunner/app/Makefile.in
+++ b/xulrunner/app/Makefile.in
@@ -207,17 +207,17 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 libs::
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png $(DIST)/bin/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png $(DIST)/bin/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(DIST)/bin/chrome/icons/default
 endif
 
 # XXX applications would need to supply this file
 #export:: brand.dtd.in
-#	$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $^ > brand.dtd
+#	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > brand.dtd
 
 export::
 	$(NSINSTALL) -D $(DIST)/branding
 ifeq ($(OS_ARCH),WINNT)
 	cp $(srcdir)/xulrunner.ico   $(DIST)/branding/xulrunner.ico
 	cp $(srcdir)/xulrunner.ico   $(DIST)/branding/app.ico
 	cp $(srcdir)/document.ico  $(DIST)/branding/document.ico
 endif
--- a/xulrunner/installer/mac/Makefile.in
+++ b/xulrunner/installer/mac/Makefile.in
@@ -56,17 +56,17 @@ NO_PKG_FILES = \
 	xpt_link* \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 libs:: stage-package
 
 %.plist: %.plist.in
-	$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $< > $@
+	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $< > $@
 
 PACKAGER_NO_LIBS=1
 _APPNAME = XUL.framework
 _BINPATH = /$(_APPNAME)/Versions/Current
 
 include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
 
 _ABS_OBJDIR := $(shell pwd)