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

Side by Side Diff: grit/format/rc_header.py

Issue 7994004: Initial source commit to grit-i18n project. (Closed) Base URL: http://grit-i18n.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « grit/format/rc.py ('k') | grit/format/rc_header_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 #!/usr/bin/python2.4
2 # Copyright (c) 2006-2008 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 '''Item formatters for RC headers.
7 '''
8
9 import re
10
11 from grit.format import interface
12 from grit import exception
13 from grit import util
14
15 from grit.extern import FP
16
17
18 class TopLevel(interface.ItemFormatter):
19 '''Writes the necessary preamble for a resource.h file.'''
20
21 def Format(self, item, lang='', begin_item=True, output_dir='.'):
22 if not begin_item:
23 return ''
24 else:
25 header_string = '''// Copyright (c) Google Inc. %d
26 // All rights reserved.
27 // This file is automatically generated by GRIT. Do not edit.
28
29 #pragma once
30 ''' % (util.GetCurrentYear())
31 # Check for emit nodes under the rc_header. If any emit node
32 # is present, we assume it means the GRD file wants to override
33 # the default header, with no includes.
34 for output_node in item.GetOutputFiles():
35 if output_node.GetType() == 'rc_header':
36 for child in output_node.children:
37 if child.name == 'emit':
38 if child.attrs['emit_type'] == 'prepend':
39 return header_string
40 # else print out the default header with include
41 return header_string + '''
42 #include <atlres.h>
43
44 '''
45
46
47 class EmitAppender(interface.ItemFormatter):
48 '''Adds the content of the <emit> nodes to the RC header file.'''
49
50 def Format(self, item, lang='', begin_item=True, output_dir='.'):
51 if not begin_item:
52 return ''
53 else:
54 return '%s\n' % (item.GetCdata())
55
56 class Item(interface.ItemFormatter):
57 '''Writes the #define line(s) for a single item in a resource.h file. If
58 your node has multiple IDs that need to be defined (as is the case e.g. for
59 dialog resources) it should define a function GetTextIds(self) that returns
60 a list of textual IDs (strings). Otherwise the formatter will use the
61 'name' attribute of the node.'''
62
63 # All IDs allocated so far, mapped to the textual ID they represent.
64 # Used to detect and resolve collisions.
65 ids_ = {}
66
67 # All textual IDs allocated so far, mapped to the numerical ID they
68 # represent. Used when literal IDs are being defined in the 'identifiers'
69 # section of the GRD file to define other message IDs.
70 tids_ = {}
71
72 def _VerifyId(self, id, tid, msg_if_error):
73 if id in self.ids_ and self.ids_[id] != tid:
74 raise exception.IdRangeOverlap(msg_if_error +
75 '\nUse the first_id attribute on grouping nodes (<structures>,\n'
76 '<includes>, <messages> and <ids>) to fix this problem.')
77 if id < 101:
78 print ('WARNING: Numeric resource IDs should be greater than 100 to avoid\ n'
79 'conflicts with system-defined resource IDs.')
80
81 def Format(self, item, lang='', begin_item=True, output_dir='.'):
82 if not begin_item:
83 return ''
84
85 # Resources that use the RES protocol don't need
86 # any numerical ids generated, so we skip them altogether.
87 # This is accomplished by setting the flag 'generateid' to false
88 # in the GRD file.
89 if 'generateid' in item.attrs:
90 if item.attrs['generateid'] == 'false':
91 return ''
92
93 text_ids = item.GetTextualIds()
94
95 # We consider the "parent" of the item to be the GroupingNode containing
96 # the item, as its immediate parent may be an <if> node.
97 item_parent = item.parent
98 import grit.node.empty
99 while item_parent and not isinstance(item_parent,
100 grit.node.empty.GroupingNode):
101 item_parent = item_parent.parent
102
103 lines = []
104 for tid in text_ids:
105 if util.SYSTEM_IDENTIFIERS.match(tid):
106 # Don't emit a new ID for predefined IDs
107 continue
108
109 # Some identifier nodes can provide their own id,
110 # and we use that id in the generated header in that case.
111 if hasattr(item, 'GetId') and item.GetId():
112 id = long(item.GetId())
113
114 elif ('offset' in item.attrs and item_parent and
115 'first_id' in item_parent.attrs and item_parent.attrs['first_id'] != ''):
116 offset_text = item.attrs['offset']
117 parent_text = item_parent.attrs['first_id']
118
119 try:
120 offset_id = long(offset_text)
121 except ValueError:
122 offset_id = self.tids_[offset_text]
123
124 try:
125 parent_id = long(parent_text)
126 except ValueError:
127 parent_id = self.tids_[parent_text]
128
129 id = parent_id + offset_id
130
131 # We try to allocate IDs sequentially for blocks of items that might
132 # be related, for instance strings in a stringtable (as their IDs might be
133 # used e.g. as IDs for some radio buttons, in which case the IDs must
134 # be sequential).
135 #
136 # We do this by having the first item in a section store its computed ID
137 # (computed from a fingerprint) in its parent object. Subsequent children
138 # of the same parent will then try to get IDs that sequentially follow
139 # the currently stored ID (on the parent) and increment it.
140 elif not item_parent or not hasattr(item_parent, '_last_id_'):
141 # First check if the starting ID is explicitly specified by the parent.
142 if (item_parent and 'first_id' in item_parent.attrs and
143 item_parent.attrs['first_id'] != ''):
144 id = long(item_parent.attrs['first_id'])
145 self._VerifyId(id, tid,
146 'Explicitly specified numeric first_id %d conflicts with one of the\ n'
147 'ID ranges already used.' % id)
148 else:
149 # Automatically generate the ID based on the first clique from the
150 # first child of the first child node of our parent (i.e. when we
151 # first get to this location in the code).
152
153 # According to
154 # http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx
155 # the safe usable range for resource IDs in Windows is from decimal
156 # 101 to 0x7FFF.
157
158 id = FP.UnsignedFingerPrint(tid)
159 id = id % (0x7FFF - 101)
160 id += 101
161
162 self._VerifyId(id, tid,
163 'Automatic (fingerprint-based) numeric ID for %s (%d) overlapped\n'
164 'with a previously allocated range.' % (tid, id))
165
166 if item_parent:
167 item_parent._last_id_ = id
168 else:
169 assert hasattr(item_parent, '_last_id_')
170 id = item_parent._last_id_ = item_parent._last_id_ + 1
171 self._VerifyId(id, tid,
172 'Wanted to make numeric value for ID %s (%d) follow the numeric value of\n'
173 'the previous ID in the .grd file, but it was already used.' % (tid, i d))
174
175 if tid not in self.ids_.values():
176 self.ids_[id] = tid
177 self.tids_[tid] = id
178 lines.append('#define %s %d\n' % (tid, id))
179 return ''.join(lines)
180
OLDNEW
« no previous file with comments | « grit/format/rc.py ('k') | grit/format/rc_header_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698