1#!/usr/bin/env python 2# Copyright (c) 2012 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'''This file contains item formatters for resource_map_header and 7resource_map_source files. A resource map is a mapping between resource names 8(string) and the internal resource ID.''' 9 10import os 11from functools import partial 12 13from grit import util 14 15 16def GetFormatter(type): 17 if type == 'resource_map_header': 18 return _FormatHeader 19 elif type == 'resource_map_source': 20 return partial(_FormatSource, _GetItemName) 21 elif type == 'resource_file_map_source': 22 return partial(_FormatSource, _GetItemPath) 23 24 25def GetMapName(root): 26 '''Get the name of the resource map based on the header file name. E.g., 27 if our header filename is theme_resources.h, we name our resource map 28 kThemeResourcesMap. 29 30 |root| is the grd file root.''' 31 outputs = root.GetOutputFiles() 32 rc_header_file = None 33 for output in outputs: 34 if 'rc_header' == output.GetType(): 35 rc_header_file = output.GetFilename() 36 if not rc_header_file: 37 raise Exception('unable to find resource header filename') 38 filename = os.path.splitext(os.path.split(rc_header_file)[1])[0] 39 filename = filename[0].upper() + filename[1:] 40 while filename.find('_') != -1: 41 pos = filename.find('_') 42 if pos >= len(filename): 43 break 44 filename = filename[:pos] + filename[pos + 1].upper() + filename[pos + 2:] 45 return 'k' + filename 46 47 48def _FormatHeader(root, lang='en', output_dir='.'): 49 '''Create the header file for the resource mapping. This file just declares 50 an array of name/value pairs.''' 51 return '''\ 52// This file is automatically generated by GRIT. Do not edit. 53 54#include <stddef.h> 55 56#ifndef GRIT_RESOURCE_MAP_STRUCT_ 57#define GRIT_RESOURCE_MAP_STRUCT_ 58struct GritResourceMap { 59 const char* const name; 60 int value; 61}; 62#endif // GRIT_RESOURCE_MAP_STRUCT_ 63 64extern const GritResourceMap %(map_name)s[]; 65extern const size_t %(map_name)sSize; 66''' % { 'map_name': GetMapName(root) } 67 68 69def _FormatSourceHeader(root): 70 '''Create the header of the C++ source file for the resource mapping.''' 71 rc_header_file = None 72 map_header_file = None 73 for output in root.GetOutputFiles(): 74 if 'rc_header' == output.GetType(): 75 rc_header_file = output.GetFilename() 76 elif 'resource_map_header' == output.GetType(): 77 map_header_file = output.GetFilename() 78 if not rc_header_file or not map_header_file: 79 raise Exception('resource_map_source output type requires ' 80 'resource_map_header and rc_header outputs') 81 return '''\ 82// This file is automatically generated by GRIT. Do not edit. 83 84#include "%(map_header_file)s" 85 86#include "base/basictypes.h" 87#include "%(rc_header_file)s" 88 89const GritResourceMap %(map_name)s[] = { 90''' % { 'map_header_file': map_header_file, 91 'rc_header_file': rc_header_file, 92 'map_name': GetMapName(root), 93 } 94 95 96def _FormatSourceFooter(root): 97 # Return the footer text. 98 return '''\ 99}; 100 101const size_t %(map_name)sSize = arraysize(%(map_name)s); 102''' % { 'map_name': GetMapName(root) } 103 104 105def _FormatSource(get_key, root, lang, output_dir): 106 from grit.format import rc_header 107 from grit.node import include, structure, message 108 yield _FormatSourceHeader(root) 109 tids = rc_header.GetIds(root) 110 seen = set() 111 active_descendants = [item for item in root.ActiveDescendants()] 112 output_all_resource_defines = root.ShouldOutputAllResourceDefines() 113 for item in root: 114 if not item.IsResourceMapSource(): 115 continue 116 key = get_key(item) 117 tid = item.attrs['name'] 118 if tid not in tids or key in seen: 119 continue 120 seen.add(key) 121 if item.GeneratesResourceMapEntry(output_all_resource_defines, 122 item in active_descendants): 123 yield ' {"%s", %s},\n' % (key, tid) 124 yield _FormatSourceFooter(root) 125 126 127def _GetItemName(item): 128 return item.attrs['name'] 129 130 131def _GetItemPath(item): 132 return item.GetInputPath().replace("\\", "/") 133