| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 '''Class for reading GRD files into memory, without processing them. | 6 '''Class for reading GRD files into memory, without processing them. |
| 7 ''' | 7 ''' |
| 8 | 8 |
| 9 import os.path | 9 import os.path |
| 10 import types | 10 import types |
| 11 import xml.sax | 11 import xml.sax |
| 12 import xml.sax.handler | 12 import xml.sax.handler |
| 13 | 13 |
| 14 from grit import exception | 14 from grit import exception |
| 15 from grit import util | 15 from grit import util |
| 16 from grit.node import base | 16 from grit.node import base |
| 17 from grit.node import mapping | 17 from grit.node import mapping |
| 18 from grit.node import misc | 18 from grit.node import misc |
| 19 | 19 |
| 20 | 20 |
| 21 class StopParsingException(Exception): | 21 class StopParsingException(Exception): |
| 22 '''An exception used to stop parsing.''' | 22 '''An exception used to stop parsing.''' |
| 23 pass | 23 pass |
| 24 | 24 |
| 25 | 25 |
| 26 class GrdContentHandler(xml.sax.handler.ContentHandler): | 26 class GrdContentHandler(xml.sax.handler.ContentHandler): |
| 27 def __init__(self, stop_after, debug, dir, defines, tags_to_ignore): | 27 def __init__(self, stop_after, debug, dir, defines, tags_to_ignore, |
| 28 target_platform): |
| 28 # Invariant of data: | 29 # Invariant of data: |
| 29 # 'root' is the root of the parse tree being created, or None if we haven't | 30 # 'root' is the root of the parse tree being created, or None if we haven't |
| 30 # parsed out any elements. | 31 # parsed out any elements. |
| 31 # 'stack' is the a stack of elements that we push new nodes onto and | 32 # 'stack' is the a stack of elements that we push new nodes onto and |
| 32 # pop from when they finish parsing, or [] if we are not currently parsing. | 33 # pop from when they finish parsing, or [] if we are not currently parsing. |
| 33 # 'stack[-1]' is the top of the stack. | 34 # 'stack[-1]' is the top of the stack. |
| 34 self.root = None | 35 self.root = None |
| 35 self.stack = [] | 36 self.stack = [] |
| 36 self.stop_after = stop_after | 37 self.stop_after = stop_after |
| 37 self.debug = debug | 38 self.debug = debug |
| 38 self.dir = dir | 39 self.dir = dir |
| 39 self.defines = defines | 40 self.defines = defines |
| 40 self.tags_to_ignore = tags_to_ignore or set() | 41 self.tags_to_ignore = tags_to_ignore or set() |
| 41 self.ignore_depth = 0 | 42 self.ignore_depth = 0 |
| 43 self.target_platform = target_platform |
| 42 | 44 |
| 43 def startElement(self, name, attrs): | 45 def startElement(self, name, attrs): |
| 44 if self.ignore_depth or name in self.tags_to_ignore: | 46 if self.ignore_depth or name in self.tags_to_ignore: |
| 45 if self.debug and self.ignore_depth == 0: | 47 if self.debug and self.ignore_depth == 0: |
| 46 print "Ignoring element %s and its children" % name | 48 print "Ignoring element %s and its children" % name |
| 47 self.ignore_depth += 1 | 49 self.ignore_depth += 1 |
| 48 return | 50 return |
| 49 | 51 |
| 50 if self.debug: | 52 if self.debug: |
| 51 attr_list = ' '.join('%s="%s"' % kv for kv in attrs.items()) | 53 attr_list = ' '.join('%s="%s"' % kv for kv in attrs.items()) |
| 52 print ("Starting parsing of element %s with attributes %r" % | 54 print ("Starting parsing of element %s with attributes %r" % |
| 53 (name, attr_list or '(none)')) | 55 (name, attr_list or '(none)')) |
| 54 | 56 |
| 55 typeattr = attrs.get('type') | 57 typeattr = attrs.get('type') |
| 56 node = mapping.ElementToClass(name, typeattr)() | 58 node = mapping.ElementToClass(name, typeattr)() |
| 57 | 59 |
| 58 if self.stack: | 60 if self.stack: |
| 59 self.stack[-1].AddChild(node) | 61 self.stack[-1].AddChild(node) |
| 60 node.StartParsing(name, self.stack[-1]) | 62 node.StartParsing(name, self.stack[-1]) |
| 61 else: | 63 else: |
| 62 assert self.root is None | 64 assert self.root is None |
| 63 self.root = node | 65 self.root = node |
| 66 if isinstance(self.root, misc.GritNode): |
| 67 if self.target_platform: |
| 68 self.root.SetTargetPlatform(self.target_platform) |
| 64 node.StartParsing(name, None) | 69 node.StartParsing(name, None) |
| 65 if self.defines: | 70 if self.defines: |
| 66 node.SetDefines(self.defines) | 71 node.SetDefines(self.defines) |
| 67 self.stack.append(node) | 72 self.stack.append(node) |
| 68 | 73 |
| 69 for attr, attrval in attrs.items(): | 74 for attr, attrval in attrs.items(): |
| 70 node.HandleAttribute(attr, attrval) | 75 node.HandleAttribute(attr, attrval) |
| 71 | 76 |
| 72 def endElement(self, name): | 77 def endElement(self, name): |
| 73 if self.ignore_depth: | 78 if self.ignore_depth: |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 Subclass of grit.node.base.Node | 173 Subclass of grit.node.base.Node |
| 169 | 174 |
| 170 Throws: | 175 Throws: |
| 171 grit.exception.Parsing | 176 grit.exception.Parsing |
| 172 ''' | 177 ''' |
| 173 | 178 |
| 174 if dir is None and isinstance(filename_or_stream, types.StringType): | 179 if dir is None and isinstance(filename_or_stream, types.StringType): |
| 175 dir = util.dirname(filename_or_stream) | 180 dir = util.dirname(filename_or_stream) |
| 176 | 181 |
| 177 handler = GrdContentHandler(stop_after=stop_after, debug=debug, dir=dir, | 182 handler = GrdContentHandler(stop_after=stop_after, debug=debug, dir=dir, |
| 178 defines=defines, tags_to_ignore=tags_to_ignore) | 183 defines=defines, tags_to_ignore=tags_to_ignore, |
| 184 target_platform=target_platform) |
| 179 try: | 185 try: |
| 180 xml.sax.parse(filename_or_stream, handler) | 186 xml.sax.parse(filename_or_stream, handler) |
| 181 except StopParsingException: | 187 except StopParsingException: |
| 182 assert stop_after | 188 assert stop_after |
| 183 pass | 189 pass |
| 184 except: | 190 except: |
| 185 if not debug: | 191 if not debug: |
| 186 print "parse exception: run GRIT with the -x flag to debug .grd problems" | 192 print "parse exception: run GRIT with the -x flag to debug .grd problems" |
| 187 raise | 193 raise |
| 188 | 194 |
| 189 if handler.root.name != 'grit': | 195 if handler.root.name != 'grit': |
| 190 raise exception.MissingElement("root tag must be <grit>") | 196 raise exception.MissingElement("root tag must be <grit>") |
| 191 | 197 |
| 192 if hasattr(handler.root, 'SetOwnDir'): | 198 if hasattr(handler.root, 'SetOwnDir'): |
| 193 # Fix up the base_dir so it is relative to the input file. | 199 # Fix up the base_dir so it is relative to the input file. |
| 194 assert dir is not None | 200 assert dir is not None |
| 195 handler.root.SetOwnDir(dir) | 201 handler.root.SetOwnDir(dir) |
| 196 | 202 |
| 197 if isinstance(handler.root, misc.GritNode): | 203 if isinstance(handler.root, misc.GritNode): |
| 198 if target_platform: | |
| 199 handler.root.SetTargetPlatform(target_platform) | |
| 200 if first_ids_file: | 204 if first_ids_file: |
| 201 # Make the path to the first_ids_file relative to the grd file, | 205 # Make the path to the first_ids_file relative to the grd file, |
| 202 # unless it begins with GRIT_DIR. | 206 # unless it begins with GRIT_DIR. |
| 203 GRIT_DIR_PREFIX = 'GRIT_DIR' | 207 GRIT_DIR_PREFIX = 'GRIT_DIR' |
| 204 if not (first_ids_file.startswith(GRIT_DIR_PREFIX) | 208 if not (first_ids_file.startswith(GRIT_DIR_PREFIX) |
| 205 and first_ids_file[len(GRIT_DIR_PREFIX)] in ['/', '\\']): | 209 and first_ids_file[len(GRIT_DIR_PREFIX)] in ['/', '\\']): |
| 206 rel_dir = os.path.relpath(os.getcwd(), dir) | 210 rel_dir = os.path.relpath(os.getcwd(), dir) |
| 207 first_ids_file = util.normpath(os.path.join(rel_dir, first_ids_file)) | 211 first_ids_file = util.normpath(os.path.join(rel_dir, first_ids_file)) |
| 208 handler.root.attrs['first_ids_file'] = first_ids_file | 212 handler.root.attrs['first_ids_file'] = first_ids_file |
| 209 # Assign first ids to the nodes that don't have them. | 213 # Assign first ids to the nodes that don't have them. |
| 210 handler.root.AssignFirstIds(filename_or_stream, defines) | 214 handler.root.AssignFirstIds(filename_or_stream, defines) |
| 211 | 215 |
| 212 return handler.root | 216 return handler.root |
| 213 | 217 |
| 214 | 218 |
| 215 if __name__ == '__main__': | 219 if __name__ == '__main__': |
| 216 util.ChangeStdoutEncoding() | 220 util.ChangeStdoutEncoding() |
| 217 print unicode(Parse(sys.argv[1])) | 221 print unicode(Parse(sys.argv[1])) |
| OLD | NEW |