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