blob: b9c0130a75373874f53915a17550e123bcfd68dd [file] [log] [blame]
# 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