PageRenderTime 1ms CodeModel.GetById 29ms app.highlight 11ms RepoModel.GetById 0ms app.codeStats 1ms

/tools/grit/grit/node/misc.py

https://github.com/akesling/chromium
Python | 272 lines | 237 code | 17 blank | 18 comment | 18 complexity | 890b05e5a95adb751cb74d28644bc57e MD5 | raw file
  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'''Miscellaneous node types.
  7'''
  8
  9import os.path
 10
 11from grit.node import base
 12from grit.node import message
 13
 14from grit import exception
 15from grit import constants
 16from grit import util
 17
 18import grit.format.rc_header
 19
 20
 21
 22class IfNode(base.Node):
 23  '''A node for conditional inclusion of resources.
 24  '''
 25
 26  def _IsValidChild(self, child):
 27    from grit.node import empty
 28    assert self.parent, '<if> node should never be root.'
 29    if isinstance(self.parent, empty.IncludesNode):
 30      from grit.node import include
 31      return isinstance(child, include.IncludeNode)
 32    elif isinstance(self.parent, empty.MessagesNode):
 33      from grit.node import message
 34      return isinstance(child, message.MessageNode)
 35    elif isinstance(self.parent, empty.StructuresNode):
 36      from grit.node import structure
 37      return isinstance(child, structure.StructureNode)
 38    else:
 39      return False
 40
 41  def MandatoryAttributes(self):
 42    return ['expr']
 43
 44  def IsConditionSatisfied(self):
 45    '''Returns true if and only if the Python expression stored in attribute
 46    'expr' evaluates to true.
 47    '''
 48    return self.EvaluateCondition(self.attrs['expr'])
 49
 50
 51class ReleaseNode(base.Node):
 52  '''The <release> element.'''
 53
 54  def _IsValidChild(self, child):
 55    from grit.node import empty
 56    return isinstance(child, (empty.IncludesNode, empty.MessagesNode,
 57                              empty.StructuresNode, empty.IdentifiersNode))
 58
 59  def _IsValidAttribute(self, name, value):
 60    return (
 61      (name == 'seq' and int(value) <= self.GetRoot().GetCurrentRelease()) or
 62      name == 'allow_pseudo'
 63    )
 64
 65  def MandatoryAttributes(self):
 66    return ['seq']
 67
 68  def DefaultAttributes(self):
 69    return { 'allow_pseudo' : 'true' }
 70
 71  def GetReleaseNumber():
 72    '''Returns the sequence number of this release.'''
 73    return self.attribs['seq']
 74
 75  def ItemFormatter(self, t):
 76    if t == 'data_package':
 77      from grit.format import data_pack
 78      return data_pack.DataPack()
 79    else:
 80      return super(type(self), self).ItemFormatter(t)
 81
 82class GritNode(base.Node):
 83  '''The <grit> root element.'''
 84
 85  def __init__(self):
 86    base.Node.__init__(self)
 87    self.output_language = ''
 88    self.defines = {}
 89
 90  def _IsValidChild(self, child):
 91    from grit.node import empty
 92    return isinstance(child, (ReleaseNode, empty.TranslationsNode,
 93                              empty.OutputsNode))
 94
 95  def _IsValidAttribute(self, name, value):
 96    if name not in ['base_dir', 'source_lang_id',
 97                    'latest_public_release', 'current_release',
 98                    'enc_check', 'tc_project']:
 99      return False
100    if name in ['latest_public_release', 'current_release'] and value.strip(
101      '0123456789') != '':
102      return False
103    return True
104
105  def MandatoryAttributes(self):
106    return ['latest_public_release', 'current_release']
107
108  def DefaultAttributes(self):
109    return {
110      'base_dir' : '.',
111      'source_lang_id' : 'en',
112      'enc_check' : constants.ENCODING_CHECK,
113      'tc_project' : 'NEED_TO_SET_tc_project_ATTRIBUTE',
114    }
115
116  def EndParsing(self):
117    base.Node.EndParsing(self)
118    if (int(self.attrs['latest_public_release'])
119        > int(self.attrs['current_release'])):
120      raise exception.Parsing('latest_public_release cannot have a greater '
121                              'value than current_release')
122
123    self.ValidateUniqueIds()
124
125    # Add the encoding check if it's not present (should ensure that it's always
126    # present in all .grd files generated by GRIT). If it's present, assert if
127    # it's not correct.
128    if 'enc_check' not in self.attrs or self.attrs['enc_check'] == '':
129      self.attrs['enc_check'] = constants.ENCODING_CHECK
130    else:
131      assert self.attrs['enc_check'] == constants.ENCODING_CHECK, (
132        'Are you sure your .grd file is in the correct encoding (UTF-8)?')
133
134  def ValidateUniqueIds(self):
135    '''Validate that 'name' attribute is unique in all nodes in this tree
136    except for nodes that are children of <if> nodes.
137    '''
138    unique_names = {}
139    duplicate_names = []
140    for node in self:
141      if isinstance(node, message.PhNode):
142        continue  # PhNode objects have a 'name' attribute which is not an ID
143
144      node_ids = node.GetTextualIds()
145      if node_ids:
146        for node_id in node_ids:
147          if util.SYSTEM_IDENTIFIERS.match(node_id):
148            continue  # predefined IDs are sometimes used more than once
149
150          # Don't complain about duplicate IDs if they occur in a node that is
151          # inside an <if> node.
152          if (node_id in unique_names and node_id not in duplicate_names and
153              (not node.parent or not isinstance(node.parent, IfNode))):
154            duplicate_names.append(node_id)
155          unique_names[node_id] = 1
156
157    if len(duplicate_names):
158      raise exception.DuplicateKey(', '.join(duplicate_names))
159
160
161  def GetCurrentRelease(self):
162    '''Returns the current release number.'''
163    return int(self.attrs['current_release'])
164
165  def GetLatestPublicRelease(self):
166    '''Returns the latest public release number.'''
167    return int(self.attrs['latest_public_release'])
168
169  def GetSourceLanguage(self):
170    '''Returns the language code of the source language.'''
171    return self.attrs['source_lang_id']
172
173  def GetTcProject(self):
174    '''Returns the name of this project in the TranslationConsole, or
175    'NEED_TO_SET_tc_project_ATTRIBUTE' if it is not defined.'''
176    return self.attrs['tc_project']
177
178  def SetOwnDir(self, dir):
179    '''Informs the 'grit' element of the directory the file it is in resides.
180    This allows it to calculate relative paths from the input file, which is
181    what we desire (rather than from the current path).
182
183    Args:
184      dir: r'c:\bla'
185
186    Return:
187      None
188    '''
189    assert dir
190    self.base_dir = os.path.normpath(os.path.join(dir, self.attrs['base_dir']))
191
192  def GetBaseDir(self):
193    '''Returns the base directory, relative to the working directory.  To get
194    the base directory as set in the .grd file, use GetOriginalBaseDir()
195    '''
196    if hasattr(self, 'base_dir'):
197      return self.base_dir
198    else:
199      return self.GetOriginalBaseDir()
200
201  def GetOriginalBaseDir(self):
202    '''Returns the base directory, as set in the .grd file.
203    '''
204    return self.attrs['base_dir']
205
206  def GetOutputFiles(self):
207    '''Returns the list of <file> nodes that are children of this node's
208    <outputs> child.'''
209    for child in self.children:
210      if child.name == 'outputs':
211        return child.children
212    raise exception.MissingElement()
213
214  def ItemFormatter(self, t):
215    if t == 'rc_header':
216      from grit.format import rc_header  # import here to avoid circular dep
217      return rc_header.TopLevel()
218    elif t in ['rc_all', 'rc_translateable', 'rc_nontranslateable']:
219      from grit.format import rc  # avoid circular dep
220      return rc.TopLevel()
221    elif t == 'resource_map_header':
222      from grit.format import resource_map
223      return resource_map.HeaderTopLevel()
224    elif t == 'resource_map_source':
225      from grit.format import resource_map
226      return resource_map.SourceTopLevel()
227    else:
228      return super(type(self), self).ItemFormatter(t)
229
230  def SetOutputContext(self, output_language, defines):
231    self.output_language = output_language
232    self.defines = defines
233
234
235class IdentifierNode(base.Node):
236  '''A node for specifying identifiers that should appear in the resource
237  header file, and be unique amongst all other resource identifiers, but don't
238  have any other attributes or reference any resources.
239  '''
240
241  def MandatoryAttributes(self):
242    return ['name']
243
244  def DefaultAttributes(self):
245    return { 'comment' : '', 'id' : '' }
246
247  def ItemFormatter(self, t):
248    if t == 'rc_header':
249      return grit.format.rc_header.Item()
250
251  def GetId(self):
252    '''Returns the id of this identifier if it has one, None otherwise
253    '''
254    if 'id' in self.attrs:
255      return self.attrs['id']
256    return None
257
258  # static method
259  def Construct(parent, name, id, comment):
260    '''Creates a new node which is a child of 'parent', with attributes set
261    by parameters of the same name.
262    '''
263    node = IdentifierNode()
264    node.StartParsing('identifier', parent)
265    node.HandleAttribute('name', name)
266    node.HandleAttribute('id', id)
267    node.HandleAttribute('comment', comment)
268    node.EndParsing()
269    return node
270  Construct = staticmethod(Construct)
271
272