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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « grit/format/rc.py ('k') | grit/format/rc_header_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: grit/format/rc_header.py
===================================================================
--- grit/format/rc_header.py (revision 0)
+++ grit/format/rc_header.py (revision 0)
@@ -0,0 +1,180 @@
+#!/usr/bin/python2.4
+# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+'''Item formatters for RC headers.
+'''
+
+import re
+
+from grit.format import interface
+from grit import exception
+from grit import util
+
+from grit.extern import FP
+
+
+class TopLevel(interface.ItemFormatter):
+ '''Writes the necessary preamble for a resource.h file.'''
+
+ def Format(self, item, lang='', begin_item=True, output_dir='.'):
+ if not begin_item:
+ return ''
+ else:
+ header_string = '''// Copyright (c) Google Inc. %d
+// All rights reserved.
+// This file is automatically generated by GRIT. Do not edit.
+
+#pragma once
+''' % (util.GetCurrentYear())
+ # Check for emit nodes under the rc_header. If any emit node
+ # is present, we assume it means the GRD file wants to override
+ # the default header, with no includes.
+ for output_node in item.GetOutputFiles():
+ if output_node.GetType() == 'rc_header':
+ for child in output_node.children:
+ if child.name == 'emit':
+ if child.attrs['emit_type'] == 'prepend':
+ return header_string
+ # else print out the default header with include
+ return header_string + '''
+#include <atlres.h>
+
+'''
+
+
+class EmitAppender(interface.ItemFormatter):
+ '''Adds the content of the <emit> nodes to the RC header file.'''
+
+ def Format(self, item, lang='', begin_item=True, output_dir='.'):
+ if not begin_item:
+ return ''
+ else:
+ return '%s\n' % (item.GetCdata())
+
+class Item(interface.ItemFormatter):
+ '''Writes the #define line(s) for a single item in a resource.h file. If
+ your node has multiple IDs that need to be defined (as is the case e.g. for
+ dialog resources) it should define a function GetTextIds(self) that returns
+ a list of textual IDs (strings). Otherwise the formatter will use the
+ 'name' attribute of the node.'''
+
+ # All IDs allocated so far, mapped to the textual ID they represent.
+ # Used to detect and resolve collisions.
+ ids_ = {}
+
+ # All textual IDs allocated so far, mapped to the numerical ID they
+ # represent. Used when literal IDs are being defined in the 'identifiers'
+ # section of the GRD file to define other message IDs.
+ tids_ = {}
+
+ def _VerifyId(self, id, tid, msg_if_error):
+ if id in self.ids_ and self.ids_[id] != tid:
+ raise exception.IdRangeOverlap(msg_if_error +
+ '\nUse the first_id attribute on grouping nodes (<structures>,\n'
+ '<includes>, <messages> and <ids>) to fix this problem.')
+ if id < 101:
+ print ('WARNING: Numeric resource IDs should be greater than 100 to avoid\n'
+ 'conflicts with system-defined resource IDs.')
+
+ def Format(self, item, lang='', begin_item=True, output_dir='.'):
+ if not begin_item:
+ return ''
+
+ # Resources that use the RES protocol don't need
+ # any numerical ids generated, so we skip them altogether.
+ # This is accomplished by setting the flag 'generateid' to false
+ # in the GRD file.
+ if 'generateid' in item.attrs:
+ if item.attrs['generateid'] == 'false':
+ return ''
+
+ text_ids = item.GetTextualIds()
+
+ # We consider the "parent" of the item to be the GroupingNode containing
+ # the item, as its immediate parent may be an <if> node.
+ item_parent = item.parent
+ import grit.node.empty
+ while item_parent and not isinstance(item_parent,
+ grit.node.empty.GroupingNode):
+ item_parent = item_parent.parent
+
+ lines = []
+ for tid in text_ids:
+ if util.SYSTEM_IDENTIFIERS.match(tid):
+ # Don't emit a new ID for predefined IDs
+ continue
+
+ # Some identifier nodes can provide their own id,
+ # and we use that id in the generated header in that case.
+ if hasattr(item, 'GetId') and item.GetId():
+ id = long(item.GetId())
+
+ elif ('offset' in item.attrs and item_parent and
+ 'first_id' in item_parent.attrs and item_parent.attrs['first_id'] != ''):
+ offset_text = item.attrs['offset']
+ parent_text = item_parent.attrs['first_id']
+
+ try:
+ offset_id = long(offset_text)
+ except ValueError:
+ offset_id = self.tids_[offset_text]
+
+ try:
+ parent_id = long(parent_text)
+ except ValueError:
+ parent_id = self.tids_[parent_text]
+
+ id = parent_id + offset_id
+
+ # We try to allocate IDs sequentially for blocks of items that might
+ # be related, for instance strings in a stringtable (as their IDs might be
+ # used e.g. as IDs for some radio buttons, in which case the IDs must
+ # be sequential).
+ #
+ # We do this by having the first item in a section store its computed ID
+ # (computed from a fingerprint) in its parent object. Subsequent children
+ # of the same parent will then try to get IDs that sequentially follow
+ # the currently stored ID (on the parent) and increment it.
+ elif not item_parent or not hasattr(item_parent, '_last_id_'):
+ # First check if the starting ID is explicitly specified by the parent.
+ if (item_parent and 'first_id' in item_parent.attrs and
+ item_parent.attrs['first_id'] != ''):
+ id = long(item_parent.attrs['first_id'])
+ self._VerifyId(id, tid,
+ 'Explicitly specified numeric first_id %d conflicts with one of the\n'
+ 'ID ranges already used.' % id)
+ else:
+ # Automatically generate the ID based on the first clique from the
+ # first child of the first child node of our parent (i.e. when we
+ # first get to this location in the code).
+
+ # According to
+ # http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx
+ # the safe usable range for resource IDs in Windows is from decimal
+ # 101 to 0x7FFF.
+
+ id = FP.UnsignedFingerPrint(tid)
+ id = id % (0x7FFF - 101)
+ id += 101
+
+ self._VerifyId(id, tid,
+ 'Automatic (fingerprint-based) numeric ID for %s (%d) overlapped\n'
+ 'with a previously allocated range.' % (tid, id))
+
+ if item_parent:
+ item_parent._last_id_ = id
+ else:
+ assert hasattr(item_parent, '_last_id_')
+ id = item_parent._last_id_ = item_parent._last_id_ + 1
+ self._VerifyId(id, tid,
+ 'Wanted to make numeric value for ID %s (%d) follow the numeric value of\n'
+ 'the previous ID in the .grd file, but it was already used.' % (tid, id))
+
+ if tid not in self.ids_.values():
+ self.ids_[id] = tid
+ self.tids_[tid] = id
+ lines.append('#define %s %d\n' % (tid, id))
+ return ''.join(lines)
+
Property changes on: grit/format/rc_header.py
___________________________________________________________________
Added: svn:eol-style
+ LF
« 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