| # Copyright (c) 2012 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. |
| |
| '''This file contains item formatters for resource_map_header and |
| resource_map_source files. A resource map is a mapping between resource names |
| (string) and the internal resource ID.''' |
| |
| import os |
| from functools import partial |
| |
| from grit import util |
| |
| |
| def GetFormatter(type): |
| if type == 'resource_map_header': |
| return _FormatHeader |
| if type == 'resource_file_map_source': |
| return partial(_FormatSource, _GetItemPath) |
| if type == 'resource_map_source': |
| return partial(_FormatSource, _GetItemName) |
| if type == 'gzipped_resource_map_header': |
| return partial(_FormatHeader, include_gzipped=True) |
| if type == 'gzipped_resource_file_map_source': |
| return partial(_FormatSource, _GetItemPath, include_gzipped=True) |
| if type == 'gzipped_resource_map_source': |
| return partial(_FormatSource, _GetItemName, include_gzipped=True) |
| |
| |
| def GetMapName(root): |
| '''Get the name of the resource map based on the header file name. E.g., |
| if our header filename is theme_resources.h, we name our resource map |
| kThemeResourcesMap. |
| |
| |root| is the grd file root.''' |
| outputs = root.GetOutputFiles() |
| rc_header_file = None |
| for output in outputs: |
| if 'rc_header' == output.GetType(): |
| rc_header_file = output.GetFilename() |
| if not rc_header_file: |
| raise Exception('unable to find resource header filename') |
| filename = os.path.splitext(os.path.split(rc_header_file)[1])[0] |
| filename = filename[0].upper() + filename[1:] |
| while True: |
| pos = filename.find('_') |
| if pos == -1 or pos >= len(filename): |
| break |
| filename = filename[:pos] + filename[pos + 1].upper() + filename[pos + 2:] |
| return 'k' + filename |
| |
| |
| def _FormatHeader(root, lang='en', output_dir='.', include_gzipped=False): |
| '''Create the header file for the resource mapping. This file just declares |
| an array of name/value pairs.''' |
| return '''\ |
| // This file is automatically generated by GRIT. Do not edit. |
| |
| #include <stddef.h> |
| |
| #ifndef %(macro_prefix)sGRIT_RESOURCE_MAP_STRUCT_ |
| #define %(macro_prefix)sGRIT_RESOURCE_MAP_STRUCT_ |
| struct %(struct_prefix)sGritResourceMap { |
| const char* name; |
| int value;%(maybe_gzipped_bool)s |
| }; |
| #endif // %(macro_prefix)sGRIT_RESOURCE_MAP_STRUCT_ |
| |
| extern const %(struct_prefix)sGritResourceMap %(map_name)s[]; |
| extern const size_t %(map_name)sSize; |
| ''' % { 'map_name': GetMapName(root), |
| 'maybe_gzipped_bool': '\n bool gzipped;' if include_gzipped else '', |
| 'struct_prefix': 'Gzipped' if include_gzipped else '', |
| 'macro_prefix': 'GZIPPED_' if include_gzipped else '', |
| } |
| |
| |
| def _FormatSourceHeader(root, output_dir, include_gzipped): |
| '''Create the header of the C++ source file for the resource mapping.''' |
| rc_header_file = None |
| map_header_file = None |
| for output in root.GetOutputFiles(): |
| type = output.GetType() |
| if 'rc_header' == type: |
| rc_header_file = util.MakeRelativePath(output_dir, |
| output.GetOutputFilename()) |
| elif 'resource_map_header' == type or 'gzipped_resource_map_header' == type: |
| map_header_file = util.MakeRelativePath(output_dir, |
| output.GetOutputFilename()) |
| if not rc_header_file or not map_header_file: |
| raise Exception('resource_map_source output type requires ' |
| 'a *resource_map_header and rc_header outputs') |
| return '''\ |
| // This file is automatically generated by GRIT. Do not edit. |
| |
| #include "%(map_header_file)s" |
| |
| #include <stddef.h> |
| |
| #include "base/stl_util.h" |
| |
| #include "%(rc_header_file)s" |
| |
| const %(struct_prefix)sGritResourceMap %(map_name)s[] = { |
| ''' % { 'map_header_file': map_header_file, |
| 'rc_header_file': rc_header_file, |
| 'map_name': GetMapName(root), |
| 'struct_prefix': 'Gzipped' if include_gzipped else '', |
| } |
| |
| |
| def _FormatSourceFooter(root): |
| # Return the footer text. |
| return '''\ |
| }; |
| |
| const size_t %(map_name)sSize = base::size(%(map_name)s); |
| ''' % { 'map_name': GetMapName(root) } |
| |
| |
| def _FormatSource(get_key, root, lang, output_dir, include_gzipped=False): |
| from grit.node import include, structure, message |
| id_map = root.GetIdMap() |
| yield _FormatSourceHeader(root, output_dir, include_gzipped) |
| seen = set() |
| for item in root.ActiveDescendants(): |
| if not item.IsResourceMapSource(): |
| continue |
| key = get_key(item) |
| tid = item.attrs['name'] |
| if tid not in id_map or key in seen: |
| continue |
| seen.add(key) |
| if include_gzipped: |
| gzipped = item.attrs.get('compress', '') == 'gzip' |
| yield ' {"%s", %s, %s},\n' % (key, tid, 'true' if gzipped else 'false') |
| else: |
| yield ' {"%s", %s},\n' % (key, tid) |
| yield _FormatSourceFooter(root) |
| |
| |
| def _GetItemName(item): |
| return item.attrs['name'] |
| |
| |
| def _GetItemPath(item): |
| path = item.GetInputPath().replace("\\", "/") |
| # resource_maps don't currently work with variables. See crbug.com/899437 |
| # for why you might not need this, and if you still think you need it then |
| # comment 17 has a patch for how to make it work. |
| assert '$' not in path, 'see comment above' |
| return path |