1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#!/usr/bin/env python 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org########################################################################## 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# copy of this software and associated documentation files (the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# "Software"), to deal in the Software without restriction, including 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# without limitation the rights to use, copy, modify, merge, publish, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# distribute, sub license, and/or sell copies of the Software, and to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# permit persons to whom the Software is furnished to do so, subject to 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# the following conditions: 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# The above copyright notice and this permission notice (including the 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# next paragraph) shall be included in all copies or substantial portions 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# of the Software. 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org########################################################################## 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgimport sys 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgimport xml.parsers.expat 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgimport binascii 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgimport optparse 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfrom model import * 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF = range(4) 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass XmlToken: 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __init__(self, type, name_or_data, attrs = None, line = None, column = None): 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert type in (ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF) 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.type = type 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.name_or_data = name_or_data 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.attrs = attrs 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.line = line 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.column = column 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __str__(self): 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.type == ELEMENT_START: 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return '<' + self.name_or_data + ' ...>' 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.type == ELEMENT_END: 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return '</' + self.name_or_data + '>' 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.type == CHARACTER_DATA: 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return self.name_or_data 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.type == EOF: 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 'end of file' 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert 0 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass XmlTokenizer: 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org """Expat based XML tokenizer.""" 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __init__(self, fp, skip_ws = True): 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.fp = fp 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.tokens = [] 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.index = 0 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.final = False 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.skip_ws = skip_ws 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.character_pos = 0, 0 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.character_data = '' 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.parser = xml.parsers.expat.ParserCreate() 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.parser.StartElementHandler = self.handle_element_start 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.parser.EndElementHandler = self.handle_element_end 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.parser.CharacterDataHandler = self.handle_character_data 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def handle_element_start(self, name, attributes): 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.finish_character_data() 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line, column = self.pos() 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token = XmlToken(ELEMENT_START, name, attributes, line, column) 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.tokens.append(token) 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def handle_element_end(self, name): 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.finish_character_data() 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line, column = self.pos() 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token = XmlToken(ELEMENT_END, name, None, line, column) 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.tokens.append(token) 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def handle_character_data(self, data): 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if not self.character_data: 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.character_pos = self.pos() 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.character_data += data 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def finish_character_data(self): 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.character_data: 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if not self.skip_ws or not self.character_data.isspace(): 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line, column = self.character_pos 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token = XmlToken(CHARACTER_DATA, self.character_data, None, line, column) 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.tokens.append(token) 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.character_data = '' 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def next(self): 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size = 16*1024 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.index >= len(self.tokens) and not self.final: 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.tokens = [] 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.index = 0 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data = self.fp.read(size) 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.final = len(data) < size 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data = data.rstrip('\0') 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org try: 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.parser.Parse(data, self.final) 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org except xml.parsers.expat.ExpatError, e: 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS: 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if e.code == 3: 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pass 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else: 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org raise e 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.index >= len(self.tokens): 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line, column = self.pos() 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token = XmlToken(EOF, None, None, line, column) 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else: 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token = self.tokens[self.index] 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.index += 1 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return token 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def pos(self): 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return self.parser.CurrentLineNumber, self.parser.CurrentColumnNumber 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass TokenMismatch(Exception): 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __init__(self, expected, found): 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.expected = expected 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.found = found 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __str__(self): 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return '%u:%u: %s expected, %s found' % (self.found.line, self.found.column, str(self.expected), str(self.found)) 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass XmlParser: 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org """Base XML document parser.""" 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __init__(self, fp): 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.tokenizer = XmlTokenizer(fp) 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.consume() 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def consume(self): 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.token = self.tokenizer.next() 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def match_element_start(self, name): 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return self.token.type == ELEMENT_START and self.token.name_or_data == name 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def match_element_end(self, name): 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return self.token.type == ELEMENT_END and self.token.name_or_data == name 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def element_start(self, name): 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.token.type == CHARACTER_DATA: 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.consume() 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.type != ELEMENT_START: 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.name_or_data != name: 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org attrs = self.token.attrs 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.consume() 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return attrs 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def element_end(self, name): 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.token.type == CHARACTER_DATA: 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.consume() 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.type != ELEMENT_END: 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.name_or_data != name: 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.consume() 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def character_data(self, strip = True): 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data = '' 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.token.type == CHARACTER_DATA: 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data += self.token.name_or_data 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.consume() 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if strip: 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data = data.strip() 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return data 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass TraceParser(XmlParser): 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __init__(self, fp): 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org XmlParser.__init__(self, fp) 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.last_call_no = 0 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse(self): 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('trace') 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.token.type not in (ELEMENT_END, EOF): 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org call = self.parse_call() 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.handle_call(call) 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.type != EOF: 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('trace') 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_call(self): 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org attrs = self.element_start('call') 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org try: 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org no = int(attrs['no']) 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org except KeyError: 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.last_call_no += 1 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org no = self.last_call_no 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else: 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.last_call_no = no 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org klass = attrs['class'] 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org method = attrs['method'] 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org args = [] 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = None 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.token.type == ELEMENT_START: 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.name_or_data == 'arg': 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arg = self.parse_arg() 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org args.append(arg) 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elif self.token.name_or_data == 'ret': 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = self.parse_ret() 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elif self.token.name_or_data == 'call': 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org # ignore nested function calls 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.parse_call() 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else: 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org raise TokenMismatch("<arg ...> or <ret ...>", self.token) 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('call') 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Call(no, klass, method, args, ret) 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_arg(self): 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org attrs = self.element_start('arg') 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name = attrs['name'] 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = self.parse_value() 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('arg') 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return name, value 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_ret(self): 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org attrs = self.element_start('ret') 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = self.parse_value() 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('ret') 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_value(self): 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expected_tokens = ('null', 'bool', 'int', 'uint', 'float', 'string', 'enum', 'array', 'struct', 'ptr', 'bytes') 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.type == ELEMENT_START: 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if self.token.name_or_data in expected_tokens: 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org method = getattr(self, 'parse_' + self.token.name_or_data) 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return method() 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org raise TokenMismatch(" or " .join(expected_tokens), self.token) 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_null(self): 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('null') 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('null') 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Literal(None) 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_bool(self): 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('bool') 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = int(self.character_data()) 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('bool') 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Literal(value) 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_int(self): 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('int') 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = int(self.character_data()) 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('int') 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Literal(value) 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_uint(self): 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('uint') 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = int(self.character_data()) 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('uint') 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Literal(value) 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_float(self): 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('float') 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = float(self.character_data()) 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('float') 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Literal(value) 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_enum(self): 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('enum') 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name = self.character_data() 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('enum') 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NamedConstant(name) 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_string(self): 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('string') 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = self.character_data() 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('string') 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Literal(value) 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_bytes(self): 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('bytes') 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = binascii.a2b_hex(self.character_data()) 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('bytes') 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Literal(value) 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_array(self): 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('array') 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elems = [] 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.token.type != ELEMENT_END: 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elems.append(self.parse_elem()) 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('array') 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Array(elems) 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_elem(self): 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('elem') 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = self.parse_value() 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('elem') 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_struct(self): 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org attrs = self.element_start('struct') 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name = attrs['name'] 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org members = [] 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while self.token.type != ELEMENT_END: 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org members.append(self.parse_member()) 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('struct') 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Struct(name, members) 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_member(self): 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org attrs = self.element_start('member') 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name = attrs['name'] 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = self.parse_value() 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('member') 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return name, value 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def parse_ptr(self): 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_start('ptr') 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org address = self.character_data() 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.element_end('ptr') 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Pointer(address) 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def handle_call(self, call): 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pass 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass TraceDumper(TraceParser): 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __init__(self, fp): 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TraceParser.__init__(self, fp) 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.formatter = format.DefaultFormatter(sys.stdout) 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.pretty_printer = PrettyPrinter(self.formatter) 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def handle_call(self, call): 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org call.visit(self.pretty_printer) 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.formatter.newline() 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass Main: 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org '''Common main class for all retrace command line utilities.''' 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def __init__(self): 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pass 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def main(self): 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org optparser = self.get_optparser() 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (options, args) = optparser.parse_args(sys.argv[1:]) 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if args: 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for arg in args: 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if arg.endswith('.gz'): 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org from gzip import GzipFile 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stream = GzipFile(arg, 'rt') 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elif arg.endswith('.bz2'): 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org from bz2 import BZ2File 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stream = BZ2File(arg, 'rU') 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else: 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stream = open(arg, 'rt') 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.process_arg(stream, options) 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else: 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org self.process_arg(stream, options) 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def get_optparser(self): 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org optparser = optparse.OptionParser( 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usage="\n\t%prog [options] [traces] ...") 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return optparser 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org def process_arg(self, stream, options): 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org parser = TraceDumper(stream) 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org parser.parse() 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgif __name__ == '__main__': 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Main().main() 393