1# Copyright (c) 2012 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Utilies and constants specific to Chromium C++ code.
6"""
7
8from code import Code
9from datetime import datetime
10from model import PropertyType
11import os
12import re
13
14CHROMIUM_LICENSE = (
15"""// Copyright (c) %d The Chromium Authors. All rights reserved.
16// Use of this source code is governed by a BSD-style license that can be
17// found in the LICENSE file.""" % datetime.now().year
18)
19GENERATED_FILE_MESSAGE = """// GENERATED FROM THE API DEFINITION IN
20//   %s
21// DO NOT EDIT.
22"""
23GENERATED_BUNDLE_FILE_MESSAGE = """// GENERATED FROM THE API DEFINITIONS IN
24//   %s
25// DO NOT EDIT.
26"""
27GENERATED_FEATURE_MESSAGE = """// GENERATED FROM THE FEATURE DEFINITIONS IN
28//   %s
29// DO NOT EDIT.
30"""
31
32def Classname(s):
33  """Translates a namespace name or function name into something more
34  suited to C++.
35
36  eg experimental.downloads -> Experimental_Downloads
37  updateAll -> UpdateAll.
38  """
39  return '_'.join([x[0].upper() + x[1:] for x in re.split('\W', s)])
40
41
42def GetAsFundamentalValue(type_, src, dst):
43  """Returns the C++ code for retrieving a fundamental type from a
44  Value into a variable.
45
46  src: Value*
47  dst: Property*
48  """
49  return {
50      PropertyType.BOOLEAN: '%s->GetAsBoolean(%s)',
51      PropertyType.DOUBLE: '%s->GetAsDouble(%s)',
52      PropertyType.INTEGER: '%s->GetAsInteger(%s)',
53      PropertyType.STRING: '%s->GetAsString(%s)',
54  }[type_.property_type] % (src, dst)
55
56
57def GetValueType(type_):
58  """Returns the Value::Type corresponding to the model.Type.
59  """
60  return {
61      PropertyType.ARRAY: 'base::Value::TYPE_LIST',
62      PropertyType.BINARY: 'base::Value::TYPE_BINARY',
63      PropertyType.BOOLEAN: 'base::Value::TYPE_BOOLEAN',
64      # PropertyType.CHOICES can be any combination of types.
65      PropertyType.DOUBLE: 'base::Value::TYPE_DOUBLE',
66      PropertyType.ENUM: 'base::Value::TYPE_STRING',
67      PropertyType.FUNCTION: 'base::Value::TYPE_DICTIONARY',
68      PropertyType.INTEGER: 'base::Value::TYPE_INTEGER',
69      PropertyType.OBJECT: 'base::Value::TYPE_DICTIONARY',
70      PropertyType.STRING: 'base::Value::TYPE_STRING',
71  }[type_.property_type]
72
73
74def GetParameterDeclaration(param, type_):
75  """Gets a parameter declaration of a given model.Property and its C++
76  type.
77  """
78  if param.type_.property_type in (PropertyType.ANY,
79                                   PropertyType.ARRAY,
80                                   PropertyType.CHOICES,
81                                   PropertyType.OBJECT,
82                                   PropertyType.REF,
83                                   PropertyType.STRING):
84    arg = 'const %(type)s& %(name)s'
85  else:
86    arg = '%(type)s %(name)s'
87  return arg % {
88    'type': type_,
89    'name': param.unix_name,
90  }
91
92
93def GenerateIfndefName(file_path):
94  """Formats |file_path| as a #define name. Presumably |file_path| is a header
95  file, or there's little point in generating a #define for it.
96
97  e.g chrome/extensions/gen/file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__.
98  """
99  return (('%s__' % file_path).upper()
100      .replace('\\', '_')
101      .replace('/', '_')
102      .replace('.', '_'))
103
104
105def PadForGenerics(var):
106  """Appends a space to |var| if it ends with a >, so that it can be compiled
107  within generic types.
108  """
109  return ('%s ' % var) if var.endswith('>') else var
110
111
112
113def OpenNamespace(cpp_namespace):
114  """Get opening root namespace declarations.
115  """
116  c = Code()
117  for component in cpp_namespace.split('::'):
118    c.Append('namespace %s {' % component)
119  return c
120
121
122def CloseNamespace(cpp_namespace):
123  """Get closing root namespace declarations.
124  """
125  c = Code()
126  for component in reversed(cpp_namespace.split('::')):
127    c.Append('}  // namespace %s' % component)
128  return c
129
130
131def ConstantName(feature_name):
132  """Returns a kName for a feature's name.
133  """
134  return ('k' + ''.join(word[0].upper() + word[1:]
135      for word in feature_name.replace('.', ' ').split()))
136
137
138def CamelCase(unix_name):
139  return ''.join(word.capitalize() for word in unix_name.split('_'))
140
141
142def ClassName(filepath):
143  return CamelCase(os.path.split(filepath)[1])
144
145
146def GetCppNamespace(pattern, namespace):
147  '''Returns the C++ namespace given |pattern| which includes a %(namespace)s
148  substitution, and the |namespace| to substitute. It is expected that |pattern|
149  has been passed as a flag to compiler.py from GYP/GN.
150  '''
151  # For some reason Windows builds escape the % characters, so unescape them.
152  # This means that %% can never appear legitimately within a pattern, but
153  # that's ok. It should never happen.
154  cpp_namespace = pattern.replace('%%', '%') % { 'namespace': namespace }
155  assert '%' not in cpp_namespace, \
156         ('Did not manage to fully substitute namespace "%s" into pattern "%s"'
157           % (namespace, pattern))
158  return cpp_namespace
159