Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1051)

Side by Side Diff: grit/grd_reader.py

Issue 1438403002: Remove contents of grit's git-svn-mirror repository. (Closed) Base URL: https://chromium.googlesource.com/external/grit-i18n@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « grit/gather/txt_unittest.py ('k') | grit/grd_reader_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
5
6 '''Class for reading GRD files into memory, without processing them.
7 '''
8
9 import os.path
10 import types
11 import xml.sax
12 import xml.sax.handler
13
14 from grit import exception
15 from grit import util
16 from grit.node import base
17 from grit.node import mapping
18 from grit.node import misc
19
20
21 class StopParsingException(Exception):
22 '''An exception used to stop parsing.'''
23 pass
24
25
26 class GrdContentHandler(xml.sax.handler.ContentHandler):
27 def __init__(self, stop_after, debug, dir, defines, tags_to_ignore,
28 target_platform):
29 # Invariant of data:
30 # 'root' is the root of the parse tree being created, or None if we haven't
31 # parsed out any elements.
32 # 'stack' is the a stack of elements that we push new nodes onto and
33 # pop from when they finish parsing, or [] if we are not currently parsing.
34 # 'stack[-1]' is the top of the stack.
35 self.root = None
36 self.stack = []
37 self.stop_after = stop_after
38 self.debug = debug
39 self.dir = dir
40 self.defines = defines
41 self.tags_to_ignore = tags_to_ignore or set()
42 self.ignore_depth = 0
43 self.target_platform = target_platform
44
45 def startElement(self, name, attrs):
46 if self.ignore_depth or name in self.tags_to_ignore:
47 if self.debug and self.ignore_depth == 0:
48 print "Ignoring element %s and its children" % name
49 self.ignore_depth += 1
50 return
51
52 if self.debug:
53 attr_list = ' '.join('%s="%s"' % kv for kv in attrs.items())
54 print ("Starting parsing of element %s with attributes %r" %
55 (name, attr_list or '(none)'))
56
57 typeattr = attrs.get('type')
58 node = mapping.ElementToClass(name, typeattr)()
59
60 if self.stack:
61 self.stack[-1].AddChild(node)
62 node.StartParsing(name, self.stack[-1])
63 else:
64 assert self.root is None
65 self.root = node
66 if isinstance(self.root, misc.GritNode):
67 if self.target_platform:
68 self.root.SetTargetPlatform(self.target_platform)
69 node.StartParsing(name, None)
70 if self.defines:
71 node.SetDefines(self.defines)
72 self.stack.append(node)
73
74 for attr, attrval in attrs.items():
75 node.HandleAttribute(attr, attrval)
76
77 def endElement(self, name):
78 if self.ignore_depth:
79 self.ignore_depth -= 1
80 return
81
82 if name == 'part':
83 partnode = self.stack[-1]
84 partnode.started_inclusion = True
85 # Add the contents of the sub-grd file as children of the <part> node.
86 partname = partnode.GetInputPath()
87 if os.path.dirname(partname):
88 # TODO(benrg): Remove this limitation. (The problem is that GRIT
89 # assumes that files referenced from the GRD file are relative to
90 # a path stored in the root <grit> node.)
91 raise exception.GotPathExpectedFilenameOnly()
92 partname = os.path.join(self.dir, partname)
93 # Exceptions propagate to the handler in grd_reader.Parse().
94 xml.sax.parse(partname, GrdPartContentHandler(self))
95
96 if self.debug:
97 print "End parsing of element %s" % name
98 self.stack.pop().EndParsing()
99
100 if name == self.stop_after:
101 raise StopParsingException()
102
103 def characters(self, content):
104 if self.ignore_depth == 0:
105 if self.stack[-1]:
106 self.stack[-1].AppendContent(content)
107
108 def ignorableWhitespace(self, whitespace):
109 # TODO(joi) This is not supported by expat. Should use a different XML par ser?
110 pass
111
112
113 class GrdPartContentHandler(xml.sax.handler.ContentHandler):
114 def __init__(self, parent):
115 self.parent = parent
116 self.depth = 0
117
118 def startElement(self, name, attrs):
119 if self.depth:
120 self.parent.startElement(name, attrs)
121 else:
122 if name != 'grit-part':
123 raise exception.MissingElement("root tag must be <grit-part>")
124 if attrs:
125 raise exception.UnexpectedAttribute(
126 "<grit-part> tag must not have attributes")
127 self.depth += 1
128
129 def endElement(self, name):
130 self.depth -= 1
131 if self.depth:
132 self.parent.endElement(name)
133
134 def characters(self, content):
135 self.parent.characters(content)
136
137 def ignorableWhitespace(self, whitespace):
138 self.parent.ignorableWhitespace(whitespace)
139
140
141 def Parse(filename_or_stream, dir=None, stop_after=None, first_ids_file=None,
142 debug=False, defines=None, tags_to_ignore=None, target_platform=None):
143 '''Parses a GRD file into a tree of nodes (from grit.node).
144
145 If filename_or_stream is a stream, 'dir' should point to the directory
146 notionally containing the stream (this feature is only used in unit tests).
147
148 If 'stop_after' is provided, the parsing will stop once the first node
149 with this name has been fully parsed (including all its contents).
150
151 If 'debug' is true, lots of information about the parsing events will be
152 printed out during parsing of the file.
153
154 If 'first_ids_file' is non-empty, it is used to override the setting for the
155 first_ids_file attribute of the <grit> root node. Note that the first_ids_file
156 parameter should be relative to the cwd, even though the first_ids_file
157 attribute of the <grit> node is relative to the grd file.
158
159 If 'target_platform' is set, this is used to determine the target
160 platform of builds, instead of using |sys.platform|.
161
162 Args:
163 filename_or_stream: './bla.xml'
164 dir: None (if filename_or_stream is a filename) or '.'
165 stop_after: 'inputs'
166 first_ids_file: 'GRIT_DIR/../gritsettings/resource_ids'
167 debug: False
168 defines: dictionary of defines, like {'chromeos': '1'}
169 target_platform: None or the value that would be returned by sys.platform
170 on your target platform.
171
172 Return:
173 Subclass of grit.node.base.Node
174
175 Throws:
176 grit.exception.Parsing
177 '''
178
179 if dir is None and isinstance(filename_or_stream, types.StringType):
180 dir = util.dirname(filename_or_stream)
181
182 handler = GrdContentHandler(stop_after=stop_after, debug=debug, dir=dir,
183 defines=defines, tags_to_ignore=tags_to_ignore,
184 target_platform=target_platform)
185 try:
186 xml.sax.parse(filename_or_stream, handler)
187 except StopParsingException:
188 assert stop_after
189 pass
190 except:
191 if not debug:
192 print "parse exception: run GRIT with the -x flag to debug .grd problems"
193 raise
194
195 if handler.root.name != 'grit':
196 raise exception.MissingElement("root tag must be <grit>")
197
198 if hasattr(handler.root, 'SetOwnDir'):
199 # Fix up the base_dir so it is relative to the input file.
200 assert dir is not None
201 handler.root.SetOwnDir(dir)
202
203 if isinstance(handler.root, misc.GritNode):
204 if first_ids_file:
205 # Make the path to the first_ids_file relative to the grd file,
206 # unless it begins with GRIT_DIR.
207 GRIT_DIR_PREFIX = 'GRIT_DIR'
208 if not (first_ids_file.startswith(GRIT_DIR_PREFIX)
209 and first_ids_file[len(GRIT_DIR_PREFIX)] in ['/', '\\']):
210 rel_dir = os.path.relpath(os.getcwd(), dir)
211 first_ids_file = util.normpath(os.path.join(rel_dir, first_ids_file))
212 handler.root.attrs['first_ids_file'] = first_ids_file
213 # Assign first ids to the nodes that don't have them.
214 handler.root.AssignFirstIds(filename_or_stream, defines)
215
216 return handler.root
217
218
219 if __name__ == '__main__':
220 util.ChangeStdoutEncoding()
221 print unicode(Parse(sys.argv[1]))
OLDNEW
« no previous file with comments | « grit/gather/txt_unittest.py ('k') | grit/grd_reader_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698