import ast
import itertools
import os
import unittest
import bcanalyzer
import parallel
import test_util
def _MakeBytes(bits, toks):
"""Creates a multi-byte string from ASCII strings and/or ASCII codes.
Args:
bits: Number of bits per character, must be in {8, 16, 32}.
toks: A list of tokens, each of which is a ASCII strings or an integer
representing a character's ASCII value (e.g., 0 for terminating null).
Returns: A flattened string of the |bits|-bit string formed by |bit|-extending
the result of concatanating tokens.
"""
cfi = itertools.chain.from_iterable
chars = cfi(map(ord, t) if isinstance(t, str) else (t, ) for t in toks)
return bytes(cfi((c >> (8 * i) for i in range(bits // 8)) for c in chars))
class BcAnalyzerTest(unittest.TestCase):
def testParseTag(self):
self.assertEqual((bcanalyzer.OPENING_TAG, 'FOO', 4),
bcanalyzer.ParseTag('<FOO> trailing'))
self.assertEqual((bcanalyzer.OPENING_TAG, 'BAR', 4),
bcanalyzer.ParseTag('<BAR op0=3 op1=4>'))
self.assertEqual((bcanalyzer.CLOSING_TAG, 'FOO', 5),
bcanalyzer.ParseTag('</FOO>'))
self.assertEqual((bcanalyzer.SELF_CLOSING_TAG, 'FOO', 4),
bcanalyzer.ParseTag('<FOO/>'))
self.assertEqual((bcanalyzer.SELF_CLOSING_TAG, 'TOMATO2', 8),
bcanalyzer.ParseTag('<TOMATO2 />'))
self.assertEqual((bcanalyzer.OPENING_TAG, 'TOMATO2', 8),
bcanalyzer.ParseTag('<TOMATO2 / >'))
self.assertEqual((bcanalyzer.SELF_CLOSING_TAG, 'BAR', 4),
bcanalyzer.ParseTag('<BAR op0=3 op1=4/>'))
self.assertEqual((bcanalyzer.OPENING_TAG, 'FOO', 4),
bcanalyzer.ParseTag('<FOO> / trailing'))
self.assertEqual((bcanalyzer.SELF_CLOSING_TAG, 'STRUCT_NAME', 12),
bcanalyzer.ParseTag('<STRUCT_NAME abbrevid=7 op0=0/>'))
self.assertEqual((bcanalyzer.SELF_CLOSING_TAG, 'UnkownCode41', 13),
bcanalyzer.ParseTag('<UnkownCode41 op0=0 op1=4 op2=5/>'))
self.assertEqual((bcanalyzer.CLOSING_TAG, 'FOO_BAR', 9),
bcanalyzer.ParseTag('</FOO_BAR> \'/>trailing\''))
self.assertEqual((bcanalyzer.OPENING_TAG, 'A', 2),
bcanalyzer.ParseTag('<A>'))
self.assertEqual((bcanalyzer.OPENING_TAG, 'lower', 6),
bcanalyzer.ParseTag('<lower >'))
self.assertEqual((bcanalyzer.OPENING_TAG, '123', 4),
bcanalyzer.ParseTag('<123>'))
self.assertEqual((bcanalyzer.SELF_CLOSING_TAG, 'FOO', 5),
bcanalyzer.ParseTag('</FOO/>'))
self.assertEqual((bcanalyzer.SELF_CLOSING_TAG, 'FOO', 4),
bcanalyzer.ParseTag('<FOO///////>'))
self.assertEqual((bcanalyzer.OPENING_TAG, 'FOO', 4),
bcanalyzer.ParseTag('<FOO>>>>>'))
None3 = (None, None, None)
self.assertEqual(None3, bcanalyzer.ParseTag(''))
self.assertEqual(None3, bcanalyzer.ParseTag(' '))
self.assertEqual(None3, bcanalyzer.ParseTag('<>'))
self.assertEqual(None3, bcanalyzer.ParseTag('<> '))
self.assertEqual(None3, bcanalyzer.ParseTag('< >'))
self.assertEqual(None3, bcanalyzer.ParseTag('<<FOO>'))
self.assertEqual(None3, bcanalyzer.ParseTag('< FOO>'))
self.assertEqual(None3, bcanalyzer.ParseTag('<//FOO>'))
self.assertEqual(None3, bcanalyzer.ParseTag('</ FOO>'))
self.assertEqual(None3, bcanalyzer.ParseTag('< FOO />'))
self.assertEqual(None3, bcanalyzer.ParseTag('<FOO<>'))
self.assertEqual(None3, bcanalyzer.ParseTag('<NOEND'))
self.assertEqual(None3, bcanalyzer.ParseTag('some text'))
self.assertEqual(None3, bcanalyzer.ParseTag(' <UNTRIMMED>'))
self.assertEqual(None3, bcanalyzer.ParseTag('<AAA>'))
def testAnalyzer(self):
saved_char_width_limit = bcanalyzer._CHAR_WIDTH_LIMIT
for width_limit, include_4byte_strings in [(2, False), (4, True)]:
bcanalyzer._CHAR_WIDTH_LIMIT = width_limit
with test_util.AddMocksToPath():
encoded_results = bcanalyzer.RunBcAnalyzerOnIntermediates(
['test.o'], test_util.TEST_OUTPUT_DIR)
results = parallel.DecodeDictOfLists(
encoded_results, value_transform=ast.literal_eval)
self.assertEqual(['test.o'], list(results.keys()))
str_list = results['test.o']
expected = []
expected.append(_MakeBytes(8, ['Test1a', 0]))
expected.append(_MakeBytes(8, ['Test1b', 0]))
expected.append(_MakeBytes(8, ['Test2a', 0]))
expected.append(_MakeBytes(8, ['Test2b', 0]))
expected.append(_MakeBytes(16, ['Test3a', 0]))
expected.append(_MakeBytes(16, ['Test3b', 0]))
if include_4byte_strings:
expected.append(_MakeBytes(32, ['Test4a', 0]))
expected.append(_MakeBytes(32, ['Test4b', 0]))
expected.append(_MakeBytes(8, [1, 0, 0, 1, 1, 0]))
expected.append(_MakeBytes(8, [1, 0, 0, 1, 1, 1]))
expected.append(_MakeBytes(8, ['Test5a', 0]))
expected.append(_MakeBytes(8, ['Test5b', 1]))
expected.append(_MakeBytes(16, ['Test6a', 0]))
expected.append(_MakeBytes(16, ['Test6b', 1]))
if include_4byte_strings:
expected.append(_MakeBytes(32, ['Test7a', 0]))
expected.append(_MakeBytes(32, ['Test7b', 1]))
expected.append(_MakeBytes(8, ['Test8a', 0]))
expected.append(_MakeBytes(8, ['Test8b', 0]))
expected.append(_MakeBytes(8, ['1a', 0]))
self.assertEqual(expected, str_list)
bcanalyzer._CHAR_WIDTH_LIMIT = saved_char_width_limit
if __name__ == '__main__':
unittest.main()