blob: 7426363294e9ce33324f44d7885995831c064600 [file] [log] [blame]
# Copyright 2018 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.
"""Common utility functions to generate C++ source fragments."""
_AUTO_GENERATED_HEADER_BEGIN_TEMPLATE = (
r'''// Copyright 2018 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.
#ifndef {guard_macro_name}
#define {guard_macro_name}
// clang-format off
// BEGIN_AUTO_GENERATED [{script_name}] DO NOT EDIT!!
//
namespace crazy {{
namespace testing {{
''')
_AUTO_GENERATED_HEADER_END_TEMPLATE = (
r'''
}} // namespace testing
}} // namespace crazy
// END_AUTO_GENERATED_CODE [{script_name}]
// clang-format on
#endif // {guard_macro_name}'''
)
def CSourceForArrayData(values, formatter, margin=4, width=80):
"""Turn an array of values into a C source array data definition.
Args:
values: Array of input values.
formatter: Formatting function, applied to each input value to get a
C-source description of the value.
margin: Left-side margin / indentation level.
width: Maximum line width.
Returns:
A string containing the data definition as a C source fragment.
"""
read_pos = 0
read_len = len(values)
write_pos = margin
line_start = ' ' * margin
# Account for the margin + one final comma.
max_width = width - margin - 1
out = ''
while read_pos < read_len:
out += line_start
write_pos = 0
comma = ''
while read_pos < read_len:
item = comma + formatter(values[read_pos])
if write_pos + len(item) > max_width:
break # Too long, break line before this item.
out += item
read_pos += 1
write_pos += len(item)
comma = ','
if read_pos == read_len:
break
out += ',\n'
return out
def CSourceForIntegerHexArray(values, num_bits, margin=4, width=80):
"""Turn an array of integers into a C source array data definition.
Args:
values: An array of integers.
num_bits: The number of bits of said integers (i.e. 8, 16, 32 or 64).
margin: Left-side margin / indentation level (must be > 0).
width: Maximum line width.
Returns:
A string containing the data definition as a C source fragment.
"""
chars_per_word = num_bits / 4
format_str = ' 0x%%0%dx' % chars_per_word
out = CSourceForArrayData(values, lambda x: format_str % x,
margin - 1, width)
out += ',\n'
return out
def _FormatChar(ch):
"""Convert a character into its C source description."""
code = ord(ch)
if code < 32 or code > 127:
return "'\\%d'" % code
else:
return "'%s'" % ch
def CSourceForConstCharArray(chars, variable_name, margin=4, width=80):
"""Return C source fragment for static const char C array.
Args:
chars: An array or string containing all the characters for array.
variable_name: Name of the array variable.
Returns:
A new string holding a C source fragment for the array definition.
"""
out = 'static const char %s[%d] = {\n' % (variable_name, len(chars))
out += CSourceForArrayData(chars, _FormatChar, margin, width)
out += '};\n'
return out
def CSourceForComments(lines):
"""Wrap the content of |lines| instead into C++ comments."""
out = ''
for line in lines.split('\n'):
line = line.rstrip()
if line:
out += '// %s\n' % line
else:
out += '//\n'
return out
def CSourceBeginAutoGeneratedHeader(script_name, guard_macro_name):
return _AUTO_GENERATED_HEADER_BEGIN_TEMPLATE.format(
script_name=script_name,
guard_macro_name=guard_macro_name)
def CSourceEndAutoGeneratedHeader(script_name, guard_macro_name):
return _AUTO_GENERATED_HEADER_END_TEMPLATE.format(
script_name=script_name,
guard_macro_name=guard_macro_name)