# Copyright (C) 2014 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.
from common.logger import Logger from file_format.checker.struct import TestExpression, TestStatement
# Required for eval. import os import re
def head_and_tail(list): return list[0], list[1:]
def split_at_separators(expressions): """ Splits a list of TestExpressions at separators. """
split_expressions = []
word_start = 0 for index, expression in enumerate(expressions): if expression.variant == TestExpression.Variant.SEPARATOR:
split_expressions.append(expressions[word_start:index])
word_start = index + 1
split_expressions.append(expressions[word_start:]) return split_expressions
def get_variable(name, variables, pos): if name in variables: return variables[name] else:
Logger.test_failed('Missing definition of variable "{}"'.format(name), pos, variables)
def set_variable(name, value, variables, pos): if name notin variables: return variables.copy_with(name, value) else:
Logger.test_failed('Multiple definitions of variable "{}"'.format(name), pos, variables)
def match_words(checker_word, string_word, variables, pos): """ Attempts to match a list of TestExpressions against a string.
Returns updated variable dictionary if successful andNone otherwise. """ for expression in checker_word: # If `expression` is a variable reference, replace it with the value. if expression.variant == TestExpression.Variant.VAR_REF:
pattern = re.escape(get_variable(expression.name, variables, pos)) else:
pattern = expression.text
try:
pattern = re.compile(pattern) except re.error as e:
message = ('Invalid regex "{}" at {}:{},' ' compiling fails with error: {}'.format(pattern, pos.filename, pos.line_no, e)) raise RuntimeError(message)
# Match the expression's regex pattern against the remainder of the word. # Note: re.match will succeed only if matched from the beginning.
match = re.match(pattern, string_word) ifnot match: returnNone
# If `expression` was a variable definition, set the variable's value. if expression.variant == TestExpression.Variant.VAR_DEF:
variables = set_variable(expression.name, string_word[:match.end()], variables, pos)
# Move cursor by deleting the matched characters.
string_word = string_word[match.end():]
# Make sure the entire word matched, i.e. `stringWord` is empty. if string_word: returnNone
return variables
def match_lines(checker_line, string_line, variables): """ Attempts to match a CHECK line against a string. Returns variable state
after the match if successful andNone otherwise. """ assert checker_line.variant != TestStatement.Variant.EVAL
while checker_words: # Get the next run of TestExpressions which must match one string word.
checker_word, checker_words = head_and_tail(checker_words)
# Keep reading words until a match is found.
word_matched = False while string_words:
string_word, string_words = head_and_tail(string_words)
new_variables = match_words(checker_word, string_word, variables, checker_line) if new_variables isnotNone:
word_matched = True
variables = new_variables break ifnot word_matched: returnNone
# All TestExpressions matched. Return new variable state. return variables
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.