mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 361583, start using Preprocessor.py instead of preprocessor.pl in building Minefield, r=bsmedberg
This commit is contained in:
parent
84266dc3d0
commit
a364c25975
@ -50,7 +50,7 @@ FILES := \
|
||||
$(NULL)
|
||||
|
||||
libs::
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $(srcdir)/install.rdf.in > install.rdf
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(srcdir)/install.rdf.in > install.rdf
|
||||
$(INSTALL) $(FILES) $(DIST)/bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
|
||||
install::
|
||||
|
@ -47,9 +47,9 @@ DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
@$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) \
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(FINAL_TARGET)/browserconfig.properties
|
||||
|
||||
install::
|
||||
@$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) \
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(DESTDIR)$(mozappdir)/browserconfig.properties
|
||||
|
208
config/Expression.py
Normal file
208
config/Expression.py
Normal file
@ -0,0 +1,208 @@
|
||||
# ***** 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 build system.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Axel Hecht <axel@pike.org>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
"""
|
||||
Parses and evaluates simple statements for Preprocessor:
|
||||
|
||||
Expression currently supports the following grammar, whitespace is ignored:
|
||||
|
||||
expression :
|
||||
unary ( ( '==' | '!=' ) unary ) ? ;
|
||||
unary :
|
||||
'!'? value ;
|
||||
value :
|
||||
[0-9]+ # integer
|
||||
| \w+ # string identifier or value;
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
class Expression:
|
||||
def __init__(self, expression_string):
|
||||
"""
|
||||
Create a new expression with this string.
|
||||
The expression will already be parsed into an Abstract Syntax Tree.
|
||||
"""
|
||||
self.content = expression_string
|
||||
self.offset = 0
|
||||
self.__ignore_whitespace()
|
||||
self.e = self.__get_equality()
|
||||
if self.content:
|
||||
raise Expression.ParseError, self
|
||||
|
||||
def __get_equality(self):
|
||||
"""
|
||||
Production: unary ( ( '==' | '!=' ) unary ) ?
|
||||
"""
|
||||
if not len(self.content):
|
||||
return None
|
||||
rv = Expression.__AST("equality")
|
||||
# unary
|
||||
rv.append(self.__get_unary())
|
||||
self.__ignore_whitespace()
|
||||
if not re.match('[=!]=', self.content):
|
||||
# no equality needed, short cut to our prime unary
|
||||
return rv[0]
|
||||
# append operator
|
||||
rv.append(Expression.__ASTLeaf('op', self.content[:2]))
|
||||
self.__strip(2)
|
||||
self.__ignore_whitespace()
|
||||
rv.append(self.__get_unary())
|
||||
self.__ignore_whitespace()
|
||||
return rv
|
||||
|
||||
def __get_unary(self):
|
||||
"""
|
||||
Production: '!'? value
|
||||
"""
|
||||
# eat whitespace right away, too
|
||||
not_ws = re.match('!\s*', self.content)
|
||||
if not not_ws:
|
||||
return self.__get_value()
|
||||
rv = Expression.__AST('not')
|
||||
self.__strip(not_ws.end())
|
||||
rv.append(self.__get_value())
|
||||
self.__ignore_whitespace()
|
||||
return rv
|
||||
|
||||
def __get_value(self):
|
||||
"""
|
||||
Production: ( [0-9]+ | \w+)
|
||||
Note that the order is important, and the expression is kind-of
|
||||
ambiguous as \w includes 0-9. One could make it unambiguous by
|
||||
removing 0-9 from the first char of a string literal.
|
||||
"""
|
||||
rv = None
|
||||
word_len = re.match('[0-9]*', self.content).end()
|
||||
if word_len:
|
||||
rv = Expression.__ASTLeaf('int', int(self.content[:word_len]))
|
||||
else:
|
||||
word_len = re.match('\w*', self.content).end()
|
||||
if word_len:
|
||||
rv = Expression.__ASTLeaf('string', self.content[:word_len])
|
||||
else:
|
||||
raise Expression.ParseError, self
|
||||
self.__strip(word_len)
|
||||
self.__ignore_whitespace()
|
||||
return rv
|
||||
|
||||
def __ignore_whitespace(self):
|
||||
ws_len = re.match('\s*', self.content).end()
|
||||
self.__strip(ws_len)
|
||||
return
|
||||
|
||||
def __strip(self, length):
|
||||
"""
|
||||
Remove a given amount of chars from the input and update
|
||||
the offset.
|
||||
"""
|
||||
self.content = self.content[length:]
|
||||
self.offset += length
|
||||
|
||||
def evaluate(self, context):
|
||||
"""
|
||||
Evaluate the expression with the given context
|
||||
"""
|
||||
|
||||
# Helper function to evaluate __get_equality results
|
||||
def eval_equality(tok):
|
||||
left = opmap[tok[0].type](tok[0])
|
||||
right = opmap[tok[2].type](tok[2])
|
||||
rv = left == right
|
||||
if tok[1].value == '!=':
|
||||
rv = not rv
|
||||
return rv
|
||||
# Mapping from token types to evaluator functions
|
||||
# Apart from (non-)equality, all these can be simple lambda forms.
|
||||
opmap = {
|
||||
'equality': eval_equality,
|
||||
'not': lambda tok: not opmap[tok[0].type](tok[0]),
|
||||
'string': lambda tok: context[tok.value],
|
||||
'int': lambda tok: tok.value}
|
||||
|
||||
return opmap[self.e.type](self.e);
|
||||
|
||||
class __AST(list):
|
||||
"""
|
||||
Internal class implementing Abstract Syntax Tree nodes
|
||||
"""
|
||||
def __init__(self, type):
|
||||
self.type = type
|
||||
super(self.__class__, self).__init__(self)
|
||||
|
||||
class __ASTLeaf:
|
||||
"""
|
||||
Internal class implementing Abstract Syntax Tree leafs
|
||||
"""
|
||||
def __init__(self, type, value):
|
||||
self.value = value
|
||||
self.type = type
|
||||
def __str__(self):
|
||||
return self.value.__str__()
|
||||
def __repr__(self):
|
||||
return self.value.__repr__()
|
||||
|
||||
class ParseError(StandardError):
|
||||
"""
|
||||
Error raised when parsing fails.
|
||||
It has two members, offset and content, which give the offset of the
|
||||
error and the offending content.
|
||||
"""
|
||||
def __init__(self, expression):
|
||||
self.offset = expression.offset
|
||||
self.content = expression.content[:3]
|
||||
def __str__(self):
|
||||
return 'Unexpected content at offset %i, "%s"'%(self.offset, self.content)
|
||||
|
||||
class Context(dict):
|
||||
"""
|
||||
This class holds variable values by subclassing dict, and while it
|
||||
truthfully reports True and False on
|
||||
|
||||
name in context
|
||||
|
||||
it returns the variable name itself on
|
||||
|
||||
context["name"]
|
||||
|
||||
to reflect the ambiguity between string literals and preprocessor
|
||||
variables.
|
||||
"""
|
||||
def __getitem__(self, key):
|
||||
if key in self:
|
||||
return super(self.__class__, self).__getitem__(key)
|
||||
return key
|
@ -165,3 +165,11 @@ ifdef MKDEPEND_DIR
|
||||
clean clobber realclean clobber_all::
|
||||
cd $(MKDEPEND_DIR); $(MAKE) $@
|
||||
endif
|
||||
|
||||
PYUNITS := unit-Expression.py unit-Preprocessor.py
|
||||
|
||||
check::
|
||||
@$(EXIT_ON_ERROR) \
|
||||
for test in $(PYUNITS); do \
|
||||
$(PYTHON) $(srcdir)/tests/$$test ; \
|
||||
done
|
||||
|
465
config/Preprocessor.py
Normal file
465
config/Preprocessor.py
Normal file
@ -0,0 +1,465 @@
|
||||
"""
|
||||
This is a very primitive line based preprocessor, for times when using
|
||||
a C preprocessor isn't an option.
|
||||
"""
|
||||
|
||||
# ***** 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 build system.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Axel Hecht <axel@pike.org>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
|
||||
# hack around win32 mangling our line endings
|
||||
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443
|
||||
if sys.platform == "win32":
|
||||
import os, msvcrt
|
||||
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
||||
|
||||
import Expression
|
||||
|
||||
__all__ = ['Preprocessor', 'preprocess']
|
||||
|
||||
|
||||
class Preprocessor:
|
||||
"""
|
||||
Class for preprocessing text files.
|
||||
"""
|
||||
class Error(RuntimeError):
|
||||
def __init__(self, cpp, MSG, context):
|
||||
self.file = cpp.context['FILE']
|
||||
self.line = cpp.context['LINE']
|
||||
self.key = MSG
|
||||
RuntimeError.__init__(self, (self.file, self.line, self.key, context))
|
||||
def __init__(self):
|
||||
self.context = Expression.Context()
|
||||
for k,v in {'FILE': '',
|
||||
'LINE': 0,
|
||||
'DIRECTORY': os.path.abspath('.')}.iteritems():
|
||||
self.context[k] = v
|
||||
self.disableLevel = 0
|
||||
# ifStates can be
|
||||
# 0: hadTrue
|
||||
# 1: wantsTrue
|
||||
# 2: #else found
|
||||
self.ifStates = []
|
||||
self.checkLineNumbers = False
|
||||
self.writtenLines = 0
|
||||
self.filters = []
|
||||
self.cmds = {}
|
||||
for cmd, level in {'define': 0,
|
||||
'undef': 0,
|
||||
'if': sys.maxint,
|
||||
'ifdef': sys.maxint,
|
||||
'ifndef': sys.maxint,
|
||||
'else': 1,
|
||||
'elif': 1,
|
||||
'elifdef': 1,
|
||||
'elifndef': 1,
|
||||
'endif': sys.maxint,
|
||||
'expand': 0,
|
||||
'literal': 0,
|
||||
'filter': 0,
|
||||
'unfilter': 0,
|
||||
'include': 0,
|
||||
'includesubst': 0,
|
||||
'error': 0}.iteritems():
|
||||
self.cmds[cmd] = (level, getattr(self, 'do_' + cmd))
|
||||
self.out = sys.stdout
|
||||
self.setMarker('#')
|
||||
self.LE = '\n'
|
||||
self.varsubst = re.compile('@(?P<VAR>\w+)@', re.U)
|
||||
|
||||
def setLineEndings(self, aLE):
|
||||
"""
|
||||
Set the line endings to be used for output.
|
||||
"""
|
||||
self.LE = {'cr': '\x0D', 'lf': '\x0A', 'crlf': '\x0D\x0A'}[aLE]
|
||||
|
||||
def setMarker(self, aMarker):
|
||||
"""
|
||||
Set the marker to be used for processing directives.
|
||||
Used for handling CSS files, with pp.setMarker('%'), for example.
|
||||
"""
|
||||
self.marker = aMarker
|
||||
self.instruction = re.compile('%s(?P<cmd>[a-z]+)(?:\s(?P<args>.*))?$'%aMarker, re.U)
|
||||
self.comment = re.compile(aMarker, re.U)
|
||||
|
||||
def clone(self):
|
||||
"""
|
||||
Create a clone of the current processor, including line ending
|
||||
settings, marker, variable definitions, output stream.
|
||||
"""
|
||||
rv = Preprocessor()
|
||||
rv.context.update(self.context)
|
||||
rv.setMarker(self.marker)
|
||||
rv.LE = self.LE
|
||||
rv.out = self.out
|
||||
return rv
|
||||
|
||||
def write(self, aLine):
|
||||
"""
|
||||
Internal method for handling output.
|
||||
"""
|
||||
if self.checkLineNumbers:
|
||||
self.writtenLines += 1
|
||||
ln = self.context['LINE']
|
||||
if self.writtenLines != ln:
|
||||
self.out.write('//@line %(line)d "%(file)s"%(le)s'%{'line': ln,
|
||||
'file': self.context['FILE'],
|
||||
'le': self.LE})
|
||||
self.writtenLines = ln
|
||||
for f in self.filters:
|
||||
aLine = f[1](aLine)
|
||||
aLine = aLine.rstrip('\r\n') + self.LE
|
||||
self.out.write(aLine)
|
||||
|
||||
def handleCommandLine(self, args, defaultToStdin = False):
|
||||
"""
|
||||
Parse a commandline into this parser.
|
||||
Uses OptionParser internally, no args mean sys.argv[1:].
|
||||
"""
|
||||
includes = []
|
||||
def handleI(option, opt, value, parser):
|
||||
includes.append(value)
|
||||
def handleE(option, opt, value, parser):
|
||||
for k,v in os.environ.iteritems():
|
||||
self.context[k] = v
|
||||
def handleD(option, opt, value, parser):
|
||||
vals = value.split('=')
|
||||
assert len(vals) < 3
|
||||
if len(vals) == 1:
|
||||
vals.append(1)
|
||||
self.context[vals[0]] = vals[1]
|
||||
def handleU(option, opt, value, parser):
|
||||
del self.context[value]
|
||||
def handleLE(option, opt, value, parser):
|
||||
self.setLineEndings(value)
|
||||
def handleMarker(option, opt, value, parser):
|
||||
self.setMarker(value)
|
||||
p = OptionParser()
|
||||
p.add_option('-I', action='callback', callback=handleI, type="string",
|
||||
metavar="FILENAME", help='Include file')
|
||||
p.add_option('-E', action='callback', callback=handleE,
|
||||
help='Import the environment into the defined variables')
|
||||
p.add_option('-D', action='callback', callback=handleD, type="string",
|
||||
metavar="VAR[=VAL]", help='Define a variable')
|
||||
p.add_option('-U', action='callback', callback=handleU, type="string",
|
||||
metavar="VAR", help='Undefine a variable')
|
||||
p.add_option('--line-endings', action='callback', callback=handleLE,
|
||||
type="string", metavar="[cr|lr|crlf]",
|
||||
help='Use the specified line endings [Default: OS dependent]')
|
||||
p.add_option('--marker', action='callback', callback=handleMarker,
|
||||
type="string",
|
||||
help='Use the specified marker instead of #')
|
||||
(options, args) = p.parse_args(args=args)
|
||||
if defaultToStdin and len(args) == 0:
|
||||
args = [sys.stdin]
|
||||
includes.extend(args)
|
||||
for f in includes:
|
||||
self.do_include(f)
|
||||
pass
|
||||
|
||||
def handleLine(self, aLine):
|
||||
"""
|
||||
Handle a single line of input (internal).
|
||||
"""
|
||||
m = self.instruction.match(aLine)
|
||||
if m:
|
||||
args = None
|
||||
cmd = m.group('cmd')
|
||||
try:
|
||||
args = m.group('args')
|
||||
except IndexError:
|
||||
pass
|
||||
if cmd not in self.cmds:
|
||||
raise Preprocessor.Error(self, 'INVALID_CMD', aLine)
|
||||
level, cmd = self.cmds[cmd]
|
||||
if (level >= self.disableLevel):
|
||||
cmd(args)
|
||||
elif self.disableLevel == 0 and not self.comment.match(aLine):
|
||||
self.write(aLine)
|
||||
pass
|
||||
|
||||
# Instruction handlers
|
||||
# These are named do_'instruction name' and take one argument
|
||||
|
||||
# Variables
|
||||
def do_define(self, args):
|
||||
m = re.match('(?P<name>\w+)(?:\s(?P<value>.*))?', args, re.U)
|
||||
if not m:
|
||||
raise Preprocessor.Error(self, 'SYNTAX_DEF', args)
|
||||
val = 1
|
||||
if m.group('value'):
|
||||
val = m.group('value')
|
||||
try:
|
||||
if val[0] == '0':
|
||||
val = int(val, 8)
|
||||
else:
|
||||
val = int(val)
|
||||
except:
|
||||
pass
|
||||
self.context[m.group('name')] = val
|
||||
def do_undef(self, args):
|
||||
m = re.match('(?P<name>\w+)$', args, re.U)
|
||||
if not m:
|
||||
raise Preprocessor.Error(self, 'SYNTAX_DEF', args)
|
||||
if args in self.context:
|
||||
del self.context[args]
|
||||
# Logic
|
||||
def ensure_not_else(self):
|
||||
if len(self.ifStates) == 0 or self.ifStates[-1] == 2:
|
||||
sys.stderr.write('WARNING: bad nesting of #else\n')
|
||||
def do_if(self, args, replace=False):
|
||||
if self.disableLevel and not replace:
|
||||
self.disableLevel += 1
|
||||
return
|
||||
val = None
|
||||
try:
|
||||
e = Expression.Expression(args)
|
||||
val = e.evaluate(self.context)
|
||||
except Exception:
|
||||
# XXX do real error reporting
|
||||
raise Preprocessor.Error(self, 'SYNTAX_ERR', args)
|
||||
if type(val) == str:
|
||||
# we're looking for a number value, strings are false
|
||||
val = False
|
||||
if not val:
|
||||
self.disableLevel = 1
|
||||
if replace:
|
||||
if val:
|
||||
self.disableLevel = 0
|
||||
self.ifStates[-1] = self.disableLevel
|
||||
else:
|
||||
self.ifStates.append(self.disableLevel)
|
||||
pass
|
||||
def do_ifdef(self, args, replace=False):
|
||||
if self.disableLevel and not replace:
|
||||
self.disableLevel += 1
|
||||
return
|
||||
if re.match('\W', args, re.U):
|
||||
raise Preprocessor.Error(self, 'INVALID_VAR', args)
|
||||
if args not in self.context:
|
||||
self.disableLevel = 1
|
||||
if replace:
|
||||
if args in self.context:
|
||||
self.disableLevel = 0
|
||||
self.ifStates[-1] = self.disableLevel
|
||||
else:
|
||||
self.ifStates.append(self.disableLevel)
|
||||
pass
|
||||
def do_ifndef(self, args, replace=False):
|
||||
if self.disableLevel and not replace:
|
||||
self.disableLevel += 1
|
||||
return
|
||||
if re.match('\W', args, re.U):
|
||||
raise Preprocessor.Error(self, 'INVALID_VAR', args)
|
||||
if args in self.context:
|
||||
self.disableLevel = 1
|
||||
if replace:
|
||||
if args not in self.context:
|
||||
self.disableLevel = 0
|
||||
self.ifStates[-1] = self.disableLevel
|
||||
else:
|
||||
self.ifStates.append(self.disableLevel)
|
||||
pass
|
||||
def do_else(self, args, ifState = 2):
|
||||
self.ensure_not_else()
|
||||
hadTrue = self.ifStates[-1] == 0
|
||||
self.ifStates[-1] = ifState # in-else
|
||||
if hadTrue:
|
||||
self.disableLevel = 1
|
||||
return
|
||||
self.disableLevel = 0
|
||||
def do_elif(self, args):
|
||||
if self.disableLevel == 1:
|
||||
if self.ifStates[-1] == 1:
|
||||
self.do_if(args, replace=True)
|
||||
else:
|
||||
self.do_else(None, self.ifStates[-1])
|
||||
def do_elifdef(self, args):
|
||||
if self.disableLevel == 1:
|
||||
if self.ifStates[-1] == 1:
|
||||
self.do_ifdef(args, replace=True)
|
||||
else:
|
||||
self.do_else(None, self.ifStates[-1])
|
||||
def do_elifndef(self, args):
|
||||
if self.disableLevel == 1:
|
||||
if self.ifStates[-1] == 1:
|
||||
self.do_ifndef(args, replace=True)
|
||||
else:
|
||||
self.do_else(None, self.ifStates[-1])
|
||||
def do_endif(self, args):
|
||||
if self.disableLevel > 0:
|
||||
self.disableLevel -= 1
|
||||
if self.disableLevel == 0:
|
||||
self.ifStates.pop()
|
||||
# output processing
|
||||
def do_expand(self, args):
|
||||
lst = re.split('__(\w+)__', args, re.U)
|
||||
do_replace = False
|
||||
def vsubst(v):
|
||||
if v in self.context:
|
||||
return str(self.context[v])
|
||||
return ''
|
||||
for i in range(1, len(lst), 2):
|
||||
lst[i] = vsubst(lst[i])
|
||||
lst.append('\n') # add back the newline
|
||||
self.write(reduce(lambda x, y: x+y, lst, ''))
|
||||
def do_literal(self, args):
|
||||
self.write(args)
|
||||
def do_filter(self, args):
|
||||
filters = [f for f in args.split(' ') if hasattr(self, 'filter_' + f)]
|
||||
if len(filters) == 0:
|
||||
return
|
||||
current = dict(self.filters)
|
||||
for f in filters:
|
||||
current[f] = getattr(self, 'filter_' + f)
|
||||
filterNames = current.keys()
|
||||
filterNames.sort()
|
||||
self.filters = [(fn, current[fn]) for fn in filterNames]
|
||||
return
|
||||
def do_unfilter(self, args):
|
||||
filters = args.split(' ')
|
||||
current = dict(self.filters)
|
||||
for f in filters:
|
||||
if f in current:
|
||||
del current[f]
|
||||
filterNames = current.keys()
|
||||
filterNames.sort()
|
||||
self.filters = [(fn, current[fn]) for fn in filterNames]
|
||||
return
|
||||
# Filters
|
||||
#
|
||||
# emptyLines
|
||||
# Strips blank lines from the output.
|
||||
def filter_emptyLines(self, aLine):
|
||||
if aLine == '\n':
|
||||
return ''
|
||||
return aLine
|
||||
# slashslash
|
||||
# Strips everything after //
|
||||
def filter_slashslash(self, aLine):
|
||||
[aLine, rest] = aLine.split('//', 1)
|
||||
if rest:
|
||||
aLine += '\n'
|
||||
return aLine
|
||||
# spaces
|
||||
# Collapses sequences of spaces into a single space
|
||||
def filter_spaces(self, aLine):
|
||||
return re.sub(' +', ' ', aLine).strip(' ')
|
||||
# substition
|
||||
# helper to be used by both substition and attemptSubstitution
|
||||
def filter_substitution(self, aLine, fatal=True):
|
||||
def repl(matchobj):
|
||||
varname = matchobj.group('VAR')
|
||||
if varname in self.context:
|
||||
return str(self.context[varname])
|
||||
if fatal:
|
||||
raise Preprocessor.Error(self, 'UNDEFINED_VAR', varname)
|
||||
return ''
|
||||
return self.varsubst.sub(repl, aLine)
|
||||
def filter_attemptSubstitution(self, aLine):
|
||||
return self.filter_substitution(aLine, fatal=False)
|
||||
# File ops
|
||||
def do_include(self, args):
|
||||
"""
|
||||
Preprocess a given file.
|
||||
args can either be a file name, or a file-like object.
|
||||
Files should be opened, and will be closed after processing.
|
||||
"""
|
||||
isName = type(args) == str or type(args) == unicode
|
||||
oldWrittenLines = self.writtenLines
|
||||
oldCheckLineNumbers = self.checkLineNumbers
|
||||
self.checkLineNumbers = False
|
||||
if isName:
|
||||
try:
|
||||
args = str(args)
|
||||
if not os.path.isabs(args):
|
||||
args = os.path.join(self.context['DIRECTORY'], args)
|
||||
args = open(args)
|
||||
except:
|
||||
raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args))
|
||||
self.checkLineNumbers = bool(re.search('\.js(?:\.in)?$', args.name))
|
||||
oldFile = self.context['FILE']
|
||||
oldLine = self.context['LINE']
|
||||
oldDir = self.context['DIRECTORY']
|
||||
if args.isatty():
|
||||
# we're stdin, use '-' and '' for file and dir
|
||||
self.context['FILE'] = '-'
|
||||
self.context['DIRECTORY'] = ''
|
||||
else:
|
||||
abspath = os.path.abspath(args.name)
|
||||
self.context['FILE'] = abspath
|
||||
self.context['DIRECTORY'] = os.path.dirname(abspath)
|
||||
self.context['LINE'] = 0
|
||||
self.writtenLines = 0
|
||||
for l in args:
|
||||
self.context['LINE'] += 1
|
||||
self.handleLine(l)
|
||||
args.close()
|
||||
self.context['FILE'] = oldFile
|
||||
self.checkLineNumbers = oldCheckLineNumbers
|
||||
self.writtenLines = oldWrittenLines
|
||||
self.context['LINE'] = oldLine
|
||||
self.context['DIRECTORY'] = oldDir
|
||||
def do_includesubst(self, args):
|
||||
args = self.filter_substitution(args)
|
||||
self.do_include(args)
|
||||
def do_error(self, args):
|
||||
raise Preprocessor.Error(self, 'Error: ', str(args))
|
||||
|
||||
def main():
|
||||
pp = Preprocessor()
|
||||
pp.handleCommandLine(None, True)
|
||||
return
|
||||
|
||||
def preprocess(includes=[sys.stdin], defines={},
|
||||
output = sys.stdout,
|
||||
line_endings='\n', marker='#'):
|
||||
pp = Preprocessor()
|
||||
pp.context.update(defines)
|
||||
pp.setLineEndings(line_endings)
|
||||
pp.setMarker(marker)
|
||||
pp.out = output
|
||||
for f in includes:
|
||||
pp.do_include(f)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -777,7 +777,7 @@ endif
|
||||
# Now test variables that might have been set or overridden by $(MY_CONFIG).
|
||||
|
||||
DEFINES += -DOSTYPE=\"$(OS_CONFIG)\"
|
||||
DEFINES += -DOSARCH=\"$(OS_ARCH)\"
|
||||
DEFINES += -DOSARCH=$(OS_ARCH)
|
||||
|
||||
# For profiling
|
||||
ifdef ENABLE_EAZEL_PROFILER
|
||||
|
@ -1436,7 +1436,7 @@ libs:: $(PREF_JS_EXPORTS)
|
||||
for i in $(PREF_JS_EXPORTS); do \
|
||||
dest=$(FINAL_TARGET)/$(PREF_DIR)/`basename $$i`; \
|
||||
$(RM) -f $$dest; \
|
||||
$(PERL) $(topsrcdir)/config/preprocessor.pl $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
done
|
||||
endif
|
||||
|
||||
@ -1447,7 +1447,7 @@ install:: $(PREF_JS_EXPORTS)
|
||||
for i in $(PREF_JS_EXPORTS); do \
|
||||
dest=$(DESTDIR)$(mozappdir)/$(PREF_DIR)/`basename $$i`; \
|
||||
$(RM) -f $$dest; \
|
||||
$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
done
|
||||
endif
|
||||
endif
|
||||
@ -1676,7 +1676,7 @@ ifndef NO_DIST_INSTALL
|
||||
for i in $^; do \
|
||||
dest=$(FINAL_TARGET)/components/`basename $$i`; \
|
||||
$(RM) -f $$dest; \
|
||||
$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
done
|
||||
endif
|
||||
|
||||
@ -1686,7 +1686,7 @@ ifndef NO_INSTALL
|
||||
for i in $^; do \
|
||||
dest=$(DESTDIR)$(mozappdir)/components/`basename $$i`; \
|
||||
$(RM) -f $$dest; \
|
||||
$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
|
||||
done
|
||||
endif
|
||||
endif
|
||||
@ -1732,7 +1732,7 @@ ifndef NO_DIST_INSTALL
|
||||
if test -f $(JAR_MANIFEST); then \
|
||||
if test ! -d $(FINAL_TARGET)/chrome; then $(NSINSTALL) -D $(FINAL_TARGET)/chrome; fi; \
|
||||
if test ! -d $(MAKE_JARS_TARGET)/chrome; then $(NSINSTALL) -D $(MAKE_JARS_TARGET)/chrome; fi; \
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
|
||||
$(JAR_MANIFEST) | \
|
||||
$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/make-jars.pl \
|
||||
-d $(MAKE_JARS_TARGET)/chrome -j $(FINAL_TARGET)/chrome \
|
||||
@ -1749,7 +1749,7 @@ ifndef NO_INSTALL
|
||||
if test -f $(JAR_MANIFEST); then \
|
||||
if test ! -d $(DESTDIR)$(mozappdir)/chrome; then $(NSINSTALL) -D $(DESTDIR)$(mozappdir)/chrome; fi; \
|
||||
if test ! -d $(MAKE_JARS_TARGET)/chrome; then $(NSINSTALL) -D $(MAKE_JARS_TARGET)/chrome; fi; \
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
|
||||
$(JAR_MANIFEST) | \
|
||||
$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/make-jars.pl \
|
||||
-d $(MAKE_JARS_TARGET)/chrome -j $(DESTDIR)$(mozappdir)/chrome \
|
||||
@ -1763,7 +1763,7 @@ libs:: $(DIST_FILES)
|
||||
for f in $(DIST_FILES); do \
|
||||
dest=$(FINAL_TARGET)/`basename $$f`; \
|
||||
$(RM) -f $$dest; \
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl \
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
|
||||
$(XULAPP_DEFINES) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
|
||||
$(srcdir)/$$f > $$dest; \
|
||||
done
|
||||
@ -1775,7 +1775,7 @@ libs:: $(DIST_CHROME_FILES)
|
||||
for f in $(DIST_CHROME_FILES); do \
|
||||
dest=$(FINAL_TARGET)/chrome/`basename $$f`; \
|
||||
$(RM) -f $$dest; \
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl \
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
|
||||
$(XULAPP_DEFINES) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
|
||||
$(srcdir)/$$f > $$dest; \
|
||||
done
|
||||
|
63
config/tests/unit-Expression.py
Normal file
63
config/tests/unit-Expression.py
Normal file
@ -0,0 +1,63 @@
|
||||
import unittest
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from Expression import Expression, Context
|
||||
|
||||
class TestContext(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for the Context class
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.c = Context()
|
||||
self.c['FAIL'] = 'PASS'
|
||||
|
||||
def test_string_literal(self):
|
||||
"""test string literal, fall-through for undefined var in a Context"""
|
||||
self.assertEqual(self.c['PASS'], 'PASS')
|
||||
|
||||
def test_variable(self):
|
||||
"""test value for defined var in the Context class"""
|
||||
self.assertEqual(self.c['FAIL'], 'PASS')
|
||||
|
||||
def test_in(self):
|
||||
"""test 'var in context' to not fall for fallback"""
|
||||
self.assert_('FAIL' in self.c)
|
||||
self.assert_('PASS' not in self.c)
|
||||
|
||||
class TestExpression(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for the Expression class
|
||||
evaluate() is called with a context {FAIL: 'PASS'}
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.c = Context()
|
||||
self.c['FAIL'] = 'PASS'
|
||||
|
||||
def test_string_literal(self):
|
||||
"""Test for a string literal in an Expression"""
|
||||
self.assertEqual(Expression('PASS').evaluate(self.c), 'PASS')
|
||||
|
||||
def test_variable(self):
|
||||
"""Test for variable value in an Expression"""
|
||||
self.assertEqual(Expression('FAIL').evaluate(self.c), 'PASS')
|
||||
|
||||
def test_not(self):
|
||||
"""Test for the ! operator"""
|
||||
self.assert_(Expression('!0').evaluate(self.c))
|
||||
self.assert_(not Expression('!1').evaluate(self.c))
|
||||
|
||||
def test_equals(self):
|
||||
""" Test for the == operator"""
|
||||
self.assert_(Expression('FAIL == PASS').evaluate(self.c))
|
||||
|
||||
def test_notequals(self):
|
||||
""" Test for the != operator"""
|
||||
self.assert_(Expression('FAIL != 1').evaluate(self.c))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
376
config/tests/unit-Preprocessor.py
Normal file
376
config/tests/unit-Preprocessor.py
Normal file
@ -0,0 +1,376 @@
|
||||
import unittest
|
||||
|
||||
from StringIO import StringIO
|
||||
import os
|
||||
import sys
|
||||
import os.path
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from Preprocessor import Preprocessor
|
||||
|
||||
class NamedIO(StringIO):
|
||||
def __init__(self, name, content):
|
||||
self.name = name
|
||||
StringIO.__init__(self, content)
|
||||
|
||||
class TestPreprocessor(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for the Context class
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.pp = Preprocessor()
|
||||
self.pp.out = StringIO()
|
||||
|
||||
def test_conditional_if_0(self):
|
||||
f = NamedIO("conditional_if_0.in", """#if 0
|
||||
FAIL
|
||||
#else
|
||||
PASS
|
||||
#endif
|
||||
""")
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_string_value(self):
|
||||
f = NamedIO("string_value.in", """#define FOO STRING
|
||||
#if FOO
|
||||
string value is true
|
||||
#else
|
||||
string value is false
|
||||
#endif
|
||||
""")
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "string value is false\n")
|
||||
|
||||
def test_number_value(self):
|
||||
f = NamedIO("string_value.in", """#define FOO 1
|
||||
#if FOO
|
||||
number value is true
|
||||
#else
|
||||
number value is false
|
||||
#endif
|
||||
""")
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "number value is true\n")
|
||||
|
||||
def test_conditional_if_0_elif_1(self):
|
||||
f = NamedIO('conditional_if_0_elif_1.in', '''#if 0
|
||||
#elif 1
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_conditional_if_1(self):
|
||||
f = NamedIO('conditional_if_1.in', '''#if 1
|
||||
PASS
|
||||
#else
|
||||
FAILE
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_conditional_if_1_elif_1_else(self):
|
||||
f = NamedIO('conditional_if_1_elif_1_else.in', '''#if 1
|
||||
PASS
|
||||
#elif 1
|
||||
FAIL
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_conditional_if_1_if_1(self):
|
||||
f = NamedIO('conditional_if_1_if_1.in', '''#if 1
|
||||
#if 1
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_conditional_not_0(self):
|
||||
f = NamedIO('conditional_not_0.in', '''#if !0
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_conditional_not_1(self):
|
||||
f = NamedIO('conditional_not_1.in', '''#if !1
|
||||
FAIL
|
||||
#else
|
||||
PASS
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_conditional_not_emptyval(self):
|
||||
f = NamedIO('conditional_not_emptyval.in', '''#define EMPTYVAL
|
||||
#if !EMPTYVAL
|
||||
FAIL
|
||||
#else
|
||||
PASS
|
||||
#endif
|
||||
#if EMPTYVAL
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\nPASS\n")
|
||||
|
||||
def test_conditional_not_nullval(self):
|
||||
f = NamedIO('conditional_not_nullval.in', '''#define NULLVAL 0
|
||||
#if !NULLVAL
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_expand(self):
|
||||
f = NamedIO('expand.in', '''#define ASVAR AS
|
||||
#expand P__ASVAR__S
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_undef_defined(self):
|
||||
f = NamedIO('undef_defined.in', '''#define BAR
|
||||
#undef BAR
|
||||
BAR
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "BAR\n")
|
||||
|
||||
def test_undef_undefined(self):
|
||||
f = NamedIO('undef_undefined.in', '''#undef VAR
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "")
|
||||
|
||||
def test_filter_attemptSubstitution(self):
|
||||
f = NamedIO('filter_attemptSubstitution.in', '''#filter attemptSubstitution
|
||||
P@VAR@ASS
|
||||
#unfilter attemptSubstitution
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_filter_slashslash(self):
|
||||
f = NamedIO('filter_slashslash.in', '''#filter slashslash
|
||||
PASS//FAIL // FAIL
|
||||
#unfilter slashslash
|
||||
PASS // PASS
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\nPASS // PASS\n")
|
||||
|
||||
def test_filter_spaces(self):
|
||||
f = NamedIO('filter_spaces.in', '''#filter spaces
|
||||
You should see two nice ascii tables
|
||||
+-+-+-+
|
||||
| | | |
|
||||
+-+-+-+
|
||||
#unfilter spaces
|
||||
+-+---+
|
||||
| | |
|
||||
+-+---+
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), """You should see two nice ascii tables
|
||||
+-+-+-+
|
||||
| | | |
|
||||
+-+-+-+
|
||||
+-+---+
|
||||
| | |
|
||||
+-+---+
|
||||
""")
|
||||
|
||||
def test_filter_substitution(self):
|
||||
f = NamedIO('filter_substitution.in', '''#define VAR ASS
|
||||
#filter substitution
|
||||
P@VAR@
|
||||
#unfilter substitution
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_error(self):
|
||||
f = NamedIO('error.in', '''#error spit this message out
|
||||
''')
|
||||
caught_msg = None
|
||||
try:
|
||||
self.pp.do_include(f)
|
||||
except Preprocessor.Error, e:
|
||||
caught_msg = e.args[0][-1]
|
||||
self.assertEqual(caught_msg, 'spit this message out')
|
||||
|
||||
def test_javascript_line(self):
|
||||
f = NamedIO('javascript_line.js.in', '''// Line 1
|
||||
#if 0
|
||||
// line 3
|
||||
#endif
|
||||
// line 5
|
||||
# comment
|
||||
// line 7
|
||||
// line 8
|
||||
// line 9
|
||||
# another comment
|
||||
// line 11
|
||||
#define LINE 1
|
||||
// line 13, given line number overwritten with 2
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
out = """// Line 1
|
||||
//@line 5 "CWDjavascript_line.js.in"
|
||||
// line 5
|
||||
//@line 7 "CWDjavascript_line.js.in"
|
||||
// line 7
|
||||
// line 8
|
||||
// line 9
|
||||
//@line 11 "CWDjavascript_line.js.in"
|
||||
// line 11
|
||||
//@line 2 "CWDjavascript_line.js.in"
|
||||
// line 13, given line number overwritten with 2
|
||||
"""
|
||||
out = out.replace('CWD', os.getcwd() + os.path.sep)
|
||||
self.assertEqual(self.pp.out.getvalue(), out)
|
||||
|
||||
def test_literal(self):
|
||||
f = NamedIO('literal.in', '''#literal PASS
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_directory(self):
|
||||
f = NamedIO('var_directory.in', '''#ifdef DIRECTORY
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_file(self):
|
||||
f = NamedIO('var_file.in', '''#ifdef FILE
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_if_0(self):
|
||||
f = NamedIO('var_if_0.in', '''#define VAR 0
|
||||
#if VAR
|
||||
FAIL
|
||||
#else
|
||||
PASS
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_if_0_elifdef(self):
|
||||
f = NamedIO('var_if_0_elifdef.in', '''#if 0
|
||||
#elifdef FILE
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_if_0_elifndef(self):
|
||||
f = NamedIO('var_if_0_elifndef.in', '''#if 0
|
||||
#elifndef VAR
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_ifdef_0(self):
|
||||
f = NamedIO('var_ifdef_0.in', '''#define VAR 0
|
||||
#ifdef VAR
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_ifdef_undef(self):
|
||||
f = NamedIO('var_ifdef_undef.in', '''#define VAR 0
|
||||
#undef VAR
|
||||
#ifdef VAR
|
||||
FAIL
|
||||
#else
|
||||
PASS
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_ifndef_0(self):
|
||||
f = NamedIO('var_ifndef_0.in', '''#define VAR 0
|
||||
#ifndef VAR
|
||||
FAIL
|
||||
#else
|
||||
PASS
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_ifndef_undef(self):
|
||||
f = NamedIO('var_ifndef_undef.in', '''#define VAR 0
|
||||
#undef VAR
|
||||
#ifndef VAR
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
def test_var_line(self):
|
||||
f = NamedIO('var_line.in', '''#ifdef LINE
|
||||
PASS
|
||||
#else
|
||||
FAIL
|
||||
#endif
|
||||
''')
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "PASS\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -241,7 +241,7 @@ nsPlatformCharset::InitGetCharset(nsACString &oString)
|
||||
nsCAutoString propertyFile;
|
||||
// note: NS_LITERAL_CSTRING("unixcharset." OSARCH ".properties") does not compile on AIX
|
||||
propertyFile.AssignLiteral("unixcharset.");
|
||||
propertyFile.Append(OSARCH);
|
||||
propertyFile.AppendLiteral(NS_STRINGIFY(OSARCH));
|
||||
propertyFile.AppendLiteral(".properties");
|
||||
nsGREResProperties *info = new nsGREResProperties(propertyFile);
|
||||
NS_ASSERTION(info, "cannot create nsGREResProperties");
|
||||
|
@ -182,7 +182,7 @@ _FILES = \
|
||||
GARBAGE += $(addprefix $(DIST)/bin/res/,$(_FILES))
|
||||
|
||||
FORMS_CSS_SRC = $(srcdir)/forms.css
|
||||
PREPROCESS_FORMS_CSS = $(PERL) $(MOZILLA_DIR)/config/preprocessor.pl --marker=% $(DEFINES) $(ACDEFINES) $(FORMS_CSS_SRC)
|
||||
PREPROCESS_FORMS_CSS = $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py --marker=% $(DEFINES) $(ACDEFINES) $(FORMS_CSS_SRC)
|
||||
|
||||
$(DIST)/bin/res/forms.css $(DESTDIR)$(mozappdir)/res/forms.css: $(FORMS_CSS_SRC) Makefile
|
||||
if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); else true; fi
|
||||
|
@ -564,7 +564,7 @@ input[type="file"] > input[type="text"] {
|
||||
input[type="file"] { height: 2em; }
|
||||
}
|
||||
|
||||
%if OSARCH=="OS2"
|
||||
%if OSARCH==OS2
|
||||
input {
|
||||
font: medium serif; font-family: inherit
|
||||
}
|
||||
|
@ -47,9 +47,9 @@ DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
@$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) \
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(FINAL_TARGET)/browserconfig.properties
|
||||
|
||||
install::
|
||||
@$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) \
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(DESTDIR)$(mozappdir)/browserconfig.properties
|
||||
|
@ -81,7 +81,7 @@ TEST_DRIVER_PPARGS = -DBROWSER_PATH=$(browser_path) \
|
||||
$(NULL)
|
||||
|
||||
runtests.pl: runtests.pl.in
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl \
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
|
||||
$(TEST_DRIVER_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
|
||||
|
||||
|
@ -50,5 +50,5 @@ GARBAGE += nsHelperAppDlg.js
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
nsHelperAppDlg.js: nsHelperAppDlg.js.in
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
|
||||
|
@ -50,5 +50,5 @@ GARBAGE += nsExtensionManager.js
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
nsExtensionManager.js: nsExtensionManager.js.in
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
|
||||
|
@ -246,7 +246,7 @@ ifdef MOZ_PKG_REMOVALS
|
||||
MOZ_PKG_REMOVALS_GEN = removed-files
|
||||
|
||||
$(MOZ_PKG_REMOVALS_GEN): $(MOZ_PKG_REMOVALS) Makefile Makefile.in
|
||||
$(PERL) $(topsrcdir)/config/preprocessor.pl -Fsubstitution $(DEFINES) $(ACDEFINES) $(MOZ_PKG_REMOVALS) > $(MOZ_PKG_REMOVALS_GEN)
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) $(MOZ_PKG_REMOVALS) > $(MOZ_PKG_REMOVALS_GEN)
|
||||
endif
|
||||
|
||||
GARBAGE += $(DIST)/$(PACKAGE) $(PACKAGE)
|
||||
|
@ -58,7 +58,7 @@ endif
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
nsUpdateService.js: nsUpdateService.js.in
|
||||
$(PERL) $(MOZILLA_DIR)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
check:: nsUpdateService.js
|
||||
|
Loading…
Reference in New Issue
Block a user