1#!/usr/bin/env python3
2# Copyright (C) 2020 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from __future__ import absolute_import
17from __future__ import division
18from __future__ import print_function
19import os
20import sys
21import argparse
22import tempfile
23import subprocess
24import textwrap
25
26
27def write_cpp_header(gendir, target, descriptor_bytes):
28  _, target_name = os.path.split(target)
29
30  proto_name = target_name[:-len('.descriptor.h')].title().replace("_", "")
31  try:
32    ord(descriptor_bytes[0])
33    ordinal = ord
34  except TypeError:
35    ordinal = lambda x: x
36  binary = '{' + ', '.join(
37      '{0:#04x}'.format(ordinal(c)) for c in descriptor_bytes) + '}'
38  binary = textwrap.fill(
39      binary, width=80, initial_indent='    ', subsequent_indent='     ')
40
41  relative_target = os.path.relpath(target, gendir)
42  include_guard = relative_target.replace('\\', '_').replace('/', '_').replace(
43      '.', '_').upper() + '_'
44
45  with open(target, 'wb') as f:
46    f.write("""/*
47 * Copyright (C) 2020 The Android Open Source Project
48 *
49 * Licensed under the Apache License, Version 2.0 (the "License");
50 * you may not use this file except in compliance with the License.
51 * You may obtain a copy of the License at
52 *
53 *      http://www.apache.org/licenses/LICENSE-2.0
54 *
55 * Unless required by applicable law or agreed to in writing, software
56 * distributed under the License is distributed on an "AS IS" BASIS,
57 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
58 * See the License for the specific language governing permissions and
59 * limitations under the License.
60 */
61
62#ifndef {include_guard}
63#define {include_guard}
64
65#include <stddef.h>
66#include <stdint.h>
67#include <array>
68
69namespace perfetto {{
70
71constexpr std::array<uint8_t, {size}> k{proto_name}Descriptor{{
72{binary}}};
73
74}}  // namespace perfetto
75
76#endif  // {include_guard}
77""".format(
78        proto_name=proto_name,
79        size=len(descriptor_bytes),
80        binary=binary,
81        include_guard=include_guard,
82    ).encode())
83
84
85def main():
86  parser = argparse.ArgumentParser()
87  parser.add_argument('--cpp_out', required=True)
88  parser.add_argument('--gen_dir', default='')
89  parser.add_argument('descriptor')
90  args = parser.parse_args()
91
92  with open(args.descriptor, 'rb') as fdescriptor:
93    s = fdescriptor.read()
94    write_cpp_header(args.gen_dir, args.cpp_out, s)
95
96  return 0
97
98
99if __name__ == '__main__':
100  sys.exit(main())
101