Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
133 lines (117 sloc) 5.17 KB
# Copyright (C) 2012 Olaf Lenz
#
# This file is part of ESPResSo.
#
# ESPResSo 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 3 of the License, or
# (at your option) any later version.
#
# ESPResSo 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, see <http://www.gnu.org/licenses/>.
#
# This module parses the feature definition file features.def
#
import fileinput, string, re
class SyntaxError:
def __init__(self, message, instead):
self.message = message
self.filename = fileinput.filename()
self.lineno = fileinput.filelineno()
self.instead = instead
def __str__(self):
return '%s: %2d: %s in the following line:\n%s' % \
(self.filename, self.lineno, self.message, self.instead)
def toCPPExpr(expr):
expr = expr.replace('and', ' && ')
expr = expr.replace('or', ' || ')
expr = expr.replace('not', ' !')
expr = re.sub('([A-Z0-9_]+)', 'defined(\\1)', expr)
return expr
class defs:
def __init__(self, filename):
# complete set of all defined features
features = set()
# list of implications (pairs of feature -> implied feature)
implications = list()
# list of requirements (pairs of feature -> requirement expr)
requirements = list()
# set of derived features
derived = set()
# list of derivations (pairs of feature -> derivation expr)
derivations = list()
# list of external features
externals = set()
# list of features that are to be tested
notestfeatures = set()
for line in fileinput.input(filename):
line = line.strip()
# Ignore empty and comment lines
if len(line) == 0 or line.startswith('#') \
or line.startswith('//') or line.startswith('/*'): continue
# Tokenify line
tokens = line.split(None, 2)
# Register the feature
feature = tokens.pop(0)
features.add(feature)
# get the keyword
if len(tokens) > 0:
keyword = tokens.pop(0)
if len(tokens) == 0:
rest = None
else:
rest = tokens[0]
# derived
if keyword == 'equals':
if rest is None:
raise SyntaxError("<feature> equals <expr>", line)
if feature in derived:
raise SyntaxError("Derived feature is already defined above:", line);
if feature in externals:
raise SyntaxError("Derived feature is already defined as external above:", line);
derived.add(feature)
derivations.append((feature, rest, toCPPExpr(rest)))
# externals
elif keyword == 'external':
if rest is not None:
raise SyntaxError("<feature> external", line)
if feature in derived:
raise SyntaxError("External feature is already defined as derived above:", line);
implied = set(map((lambda (x,y):y), implications))
if feature in implied:
raise SyntaxError("External feature is implied above:", line);
externals.add(feature)
# implications
elif keyword == 'implies':
if rest is None:
raise SyntaxError("<feature> implies [<feature>...]", line)
tokens = rest.split()
for implied in tokens:
if implied.endswith(','): implied = implied[:-1]
if implied in externals:
raise SyntaxError("Implied feature %s is already defined as external above:" % feature, line);
implications.append((feature, implied))
# requires
elif keyword == 'requires':
if rest is None:
raise SyntaxError("<feature> requires <expr>", line)
requirements.append((feature, rest, toCPPExpr(rest)))
elif keyword == 'notest':
if rest is not None:
raise SyntaxError("<feature> notest", line)
notestfeatures.add(feature)
features = features.difference(derived)
features = features.difference(externals)
self.features = features
self.requirements = requirements
self.implications = implications
self.derived = derived
self.derivations = derivations
self.externals = externals
self.notestfeatures = notestfeatures
# Test whether all implied features or features in an expression are defined
Something went wrong with that request. Please try again.