195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org#!/usr/bin/env python
295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org# Copyright (c) 2012 The Chromium Authors. All rights reserved.
301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Use of this source code is governed by a BSD-style license that can be
401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# found in the LICENSE file.
501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''This file contains item formatters for resource_map_header and
701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgresource_map_source files.  A resource map is a mapping between resource names
801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org(string) and the internal resource ID.'''
901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgimport os
11ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgfrom functools import partial
1201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit import util
14ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
15ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
16ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgdef GetFormatter(type):
17ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  if type == 'resource_map_header':
18ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    return _FormatHeader
19ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  elif type == 'resource_map_source':
20ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    return partial(_FormatSource, _GetItemName)
21ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  elif type == 'resource_file_map_source':
22ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    return partial(_FormatSource, _GetItemPath)
23ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
2401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgdef GetMapName(root):
2601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''Get the name of the resource map based on the header file name.  E.g.,
2701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  if our header filename is theme_resources.h, we name our resource map
2801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  kThemeResourcesMap.
2901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
3001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  |root| is the grd file root.'''
3101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  outputs = root.GetOutputFiles()
3201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  rc_header_file = None
3301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  for output in outputs:
3401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if 'rc_header' == output.GetType():
3501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      rc_header_file = output.GetFilename()
3601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  if not rc_header_file:
3701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    raise Exception('unable to find resource header filename')
3801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  filename = os.path.splitext(os.path.split(rc_header_file)[1])[0]
3901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  filename = filename[0].upper() + filename[1:]
4001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  while filename.find('_') != -1:
4101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pos = filename.find('_')
4201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if pos >= len(filename):
4301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      break
4401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    filename = filename[:pos] + filename[pos + 1].upper() + filename[pos + 2:]
4501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  return 'k' + filename
4601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
4701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
48ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgdef _FormatHeader(root, lang='en', output_dir='.'):
4901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''Create the header file for the resource mapping.  This file just declares
5001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  an array of name/value pairs.'''
51ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  return '''\
5201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// This file is automatically generated by GRIT.  Do not edit.
5301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
5401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include <stddef.h>
5501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
5601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#ifndef GRIT_RESOURCE_MAP_STRUCT_
5701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define GRIT_RESOURCE_MAP_STRUCT_
5801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgstruct GritResourceMap {
5901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  const char* const name;
6001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  int value;
6101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org};
6201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#endif // GRIT_RESOURCE_MAP_STRUCT_
6301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
6401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgextern const GritResourceMap %(map_name)s[];
6501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgextern const size_t %(map_name)sSize;
66ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org''' % { 'map_name': GetMapName(root) }
67ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
68ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
69ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgdef _FormatSourceHeader(root):
70ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  '''Create the header of the C++ source file for the resource mapping.'''
71ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  rc_header_file = None
72ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  map_header_file = None
73ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  for output in root.GetOutputFiles():
74ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    if 'rc_header' == output.GetType():
75ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org      rc_header_file = output.GetFilename()
76ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    elif 'resource_map_header' == output.GetType():
77ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org      map_header_file = output.GetFilename()
78ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  if not rc_header_file or not map_header_file:
79ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    raise Exception('resource_map_source output type requires '
80ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org        'resource_map_header and rc_header outputs')
81ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  return '''\
8201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// This file is automatically generated by GRIT.  Do not edit.
8301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include "%(map_header_file)s"
8501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include "base/basictypes.h"
8701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include "%(rc_header_file)s"
8801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgconst GritResourceMap %(map_name)s[] = {
90d4edc6c61f2135b39318e34f9b342b673133e6ccbenrg@chromium.org''' % { 'map_header_file': map_header_file,
9101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        'rc_header_file': rc_header_file,
92ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org        'map_name': GetMapName(root),
9301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      }
9477cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org
95ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
96ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgdef _FormatSourceFooter(root):
97ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  # Return the footer text.
98ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  return '''\
9901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org};
10001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgconst size_t %(map_name)sSize = arraysize(%(map_name)s);
102ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org''' % { 'map_name': GetMapName(root) }
103ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
104ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org
105ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgdef _FormatSource(get_key, root, lang, output_dir):
106ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  from grit.format import rc_header
107ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  from grit.node import include, structure
108ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  yield _FormatSourceHeader(root)
109ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  tids = rc_header.GetIds(root)
110ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  seen = set()
111ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  for item in root:
112ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    if isinstance(item, (include.IncludeNode, structure.StructureNode)):
113ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org      key = get_key(item)
114ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org      tid = item.attrs['name']
115ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org      if tid in tids and key not in seen:
116ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org        seen.add(key)
117ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org        yield '  {"%s", %s},\n' % (key, tid)
118ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  yield _FormatSourceFooter(root)
11901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
121ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgdef _GetItemName(item):
122ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  return item.attrs['name']
12301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
125ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgdef _GetItemPath(item):
126ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org  return item.GetInputPath().replace("\\", "/")
127