Skip to content

Commit 418f45b

Browse files
committed
update
1 parent d4b2409 commit 418f45b

6 files changed

Lines changed: 1525 additions & 3 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (C) 2022 Sergey Kovalevich <inndie@gmail.com>
2+
# This file may be distributed under the terms of the GNU GPLv3 license
3+
4+
from .generator import Generator
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Copyright (C) 2022 Sergey Kovalevich <inndie@gmail.com>
2+
# This file may be distributed under the terms of the GNU GPLv3 license
3+
4+
from jinja2 import Environment, FileSystemLoader
5+
import pathlib
6+
import os
7+
8+
from app.generator import GeneratorBase
9+
10+
class Generator(GeneratorBase):
11+
def __init__(self, path: str) -> None:
12+
self.path = path
13+
self.env = Environment(
14+
loader = FileSystemLoader(f'{pathlib.Path(__file__).parent.resolve()}/templates'),
15+
autoescape = False,
16+
trim_blocks = True,
17+
lstrip_blocks = True,
18+
keep_trailing_newline = True
19+
)
20+
self.add_filters()
21+
22+
def _generate_impl(self, schema: dict) -> None:
23+
self.ensure_path_exists()
24+
self.generate_document('schema.h', 'schema.tmpl', schema=schema)
25+
26+
def generate_document(self, document_name: str, template_name: str, **kwargs) -> None:
27+
template = self.env.get_template(template_name)
28+
document_path = f'{self.path}/{document_name}'
29+
document_content = template.render(**kwargs)
30+
with open(document_path, mode='w', encoding='utf8') as document:
31+
document.write(document_content)
32+
33+
def ensure_path_exists(self) -> None:
34+
if not os.path.exists(self.path):
35+
os.makedirs(self.path)
36+
37+
def add_filters(self) -> None:
38+
self.env.filters['fmt_class_type'] = lambda s: s[0].upper() + s[1:]
39+
self.env.filters['fmt_class_ref'] = lambda s: s[0].upper() + s[1:] + 'Ref'
40+
self.env.filters['fmt_class_message'] = lambda s: s[0].upper() + s[1:]
41+
self.env.filters['fmt_class_group'] = lambda s: s[0].upper() + s[1:] + 'Group'
42+
self.env.filters['fmt_class_data'] = lambda s: s[0].upper() + s[1:] + 'Data'
43+
self.env.filters['fmt_enum_value'] = lambda s: s
44+
self.env.filters['fmt_header_name'] = lambda s: s + '.h'
45+
self.env.filters['to_cpp_type'] = Generator.to_cpp_type
46+
self.env.filters['to_cpp_value'] = Generator.to_cpp_value
47+
self.env.filters['va_length_fields'] = Generator.va_length_fields
48+
49+
@staticmethod
50+
def to_cpp_type(value: str) -> str:
51+
return {
52+
'int8': 'std::int8_t',
53+
'int16': 'std::int16_t',
54+
'int32': 'std::int32_t',
55+
'int64': 'std::int64_t',
56+
'uint8': 'std::uint8_t',
57+
'uint16': 'std::uint16_t',
58+
'uint32': 'std::uint32_t',
59+
'uint64': 'std::uint64_t',
60+
'double': 'double',
61+
'float': 'float',
62+
'char': 'char'
63+
}.get(value)
64+
65+
@staticmethod
66+
def to_cpp_value(value: str, primitive_type_name: str) -> str:
67+
result = {
68+
'CHAR_NULL': '0',
69+
'CHAR_MIN': '0x20',
70+
'CHAR_MAX': '0x7e',
71+
'INT8_NULL': 'std::numeric_limits<std::int8_t>::min()',
72+
'INT8_MIN': 'std::numeric_limits<std::int8_t>::min() + 1',
73+
'INT8_MAX': 'std::numeric_limits<std::int8_t>::max()',
74+
'INT16_NULL': 'std::numeric_limits<std::int16_t>::min()',
75+
'INT16_MIN': 'std::numeric_limits<std::int16_t>::min() + 1',
76+
'INT16_MAX': 'std::numeric_limits<std::int16_t>::max()',
77+
'INT32_NULL': 'std::numeric_limits<std::int32_t>::min()',
78+
'INT32_MIN': 'std::numeric_limits<std::int32_t>::min() + 1',
79+
'INT32_MAX': 'std::numeric_limits<std::int32_t>::max()',
80+
'INT64_NULL': 'std::numeric_limits<std::int64_t>::min()',
81+
'INT64_MIN': 'std::numeric_limits<std::int64_t>::min() + 1',
82+
'INT64_MAX': 'std::numeric_limits<std::int64_t>::max()',
83+
'UINT8_NULL': 'std::numeric_limits<std::uint8_t>::max()',
84+
'UINT8_MIN': 'std::numeric_limits<std::uint8_t>::min()',
85+
'UINT8_MAX': 'std::numeric_limits<std::uint8_t>::max() - 1',
86+
'UINT16_NULL': 'std::numeric_limits<std::uint16_t>::max()',
87+
'UINT16_MIN': 'std::numeric_limits<std::uint16_t>::min()',
88+
'UINT16_MAX': 'std::numeric_limits<std::uint16_t>::max() - 1',
89+
'UINT32_NULL': 'std::numeric_limits<std::uint32_t>::max()',
90+
'UINT32_MIN': 'std::numeric_limits<std::uint32_t>::min()',
91+
'UINT32_MAX': 'std::numeric_limits<std::uint32_t>::max() - 1',
92+
'UINT64_NULL': 'std::numeric_limits<std::uint64_t>::max()',
93+
'UINT64_MIN': 'std::numeric_limits<std::uint64_t>::min()',
94+
'UINT64_MAX': 'std::numeric_limits<std::uint64_t>::max() - 1',
95+
'FLOAT_NULL': 'std::numeric_limits<float>::quiet_NaN()',
96+
'FLOAT_MIN': 'std::numeric_limits<float>::min()',
97+
'FLOAT_MAX': 'std::numeric_limits<float>::max()',
98+
'DOUBLE_NULL': 'std::numeric_limits<double>::quiet_NaN()',
99+
'DOUBLE_MIN': 'std::numeric_limits<double>::min()',
100+
'DOUBLE_MAX': 'std::numeric_limits<double>::max()'
101+
}.get(value)
102+
if result:
103+
return result
104+
if primitive_type_name in ('uint8', 'uint16', 'uint32', 'uint64'):
105+
return value + 'u'
106+
return value
107+
108+
@staticmethod
109+
def va_length_fields(entry: dict) -> list[str]:
110+
result = []
111+
for field in entry['fields']:
112+
if field['token'] == 'data':
113+
result.append(field)
114+
elif field['token'] == 'group':
115+
result.append(field)
116+
result = result + Generator.va_length_fields(field)
117+
return result

0 commit comments

Comments
 (0)