Skip to content

Commit ba62322

Browse files
committed
Port embedSdf script from Ruby to Python3
- removes Ruby dependency (see gazebosim#274) - improvements for cpplint checks (e.g. copyright header) Signed-off-by: Bi0T1N <Bi0T1N@users.noreply.github.com>
1 parent e92389e commit ba62322

File tree

3 files changed

+148
-46
lines changed

3 files changed

+148
-46
lines changed

sdf/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ add_dependencies(schema schema1_9)
1414
# Generate the EmbeddedSdf.cc file, which contains all the supported SDF
1515
# descriptions in a map of strings. The parser.cc file uses EmbeddedSdf.hh.
1616
execute_process(
17-
COMMAND ${RUBY} ${CMAKE_SOURCE_DIR}/sdf/embedSdf.rb
17+
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/sdf/embedSdf.py
1818
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/sdf"
1919
OUTPUT_FILE "${PROJECT_BINARY_DIR}/src/EmbeddedSdf.cc"
2020
)

sdf/embedSdf.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env python3
2+
from pathlib import Path
3+
4+
""""Script for generating a C++ file that contains the content from all SDF files"""
5+
6+
# The list of supported SDF specification versions. This will let us drop
7+
# versions without removing the directories.
8+
SUPPORTED_SDF_VERSIONS = ['1.9', '1.8', '1.7', '1.6', '1.5', '1.4', '1.3', '1.2']
9+
10+
# The list of supported SDF conversions. This list includes versions that
11+
# a user can convert an existing SDF version to.
12+
SUPPORTED_SDF_CONVERSIONS = ['1.9', '1.8', '1.7', '1.6', '1.5', '1.4', '1.3']
13+
14+
# whitespace indentation for C++ code
15+
INDENTATION = ' '
16+
17+
18+
def get_copyright_notice() -> str:
19+
"""
20+
Provides the copyrigt notice for the C++ file
21+
22+
:returns: copyright notice
23+
"""
24+
res = []
25+
res.append('/*')
26+
res.append(' * Copyright 2022 Open Source Robotics Foundation')
27+
res.append(' *')
28+
res.append(' * Licensed under the Apache License, Version 2.0 (the "License");')
29+
res.append(' * you may not use this file except in compliance with the License.')
30+
res.append(' * You may obtain a copy of the License at')
31+
res.append(' *')
32+
res.append(' * http://www.apache.org/licenses/LICENSE-2.0')
33+
res.append(' *')
34+
res.append(' * Unless required by applicable law or agreed to in writing, software')
35+
res.append(' * distributed under the License is distributed on an "AS IS" BASIS,')
36+
res.append(' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.')
37+
res.append(' * See the License for the specific language governing permissions and')
38+
res.append(' * limitations under the License.')
39+
res.append(' *')
40+
res.append('*/')
41+
res.append('')
42+
return '\n'.join(res)
43+
44+
45+
def get_file_header_prolog() -> str:
46+
"""
47+
Provides the include statement, namespace and variable declaration of the C++ file
48+
49+
:returns: prolog of the C++ file
50+
"""
51+
res = []
52+
res.append('#include "EmbeddedSdf.hh"')
53+
res.append('')
54+
res.append('namespace sdf')
55+
res.append('{')
56+
res.append('inline namespace SDF_VERSION_NAMESPACE')
57+
res.append('{')
58+
res.append('/////////////////////////////////////////////////')
59+
res.append('const std::map<std::string, std::string> &GetEmbeddedSdf()')
60+
res.append('{')
61+
res.append(INDENTATION + 'static const std::map<std::string, std::string> result {')
62+
res.append('')
63+
return '\n'.join(res)
64+
65+
66+
def embed_sdf_content(arg_path: str, arg_file_content: str) -> str:
67+
"""
68+
Generates a string pair with the folder and filename as well as the content of the file
69+
70+
:param arg_path: Foldername and filename of the SDF
71+
:param arg_file_content: Content of the provided file
72+
:returns: raw string literal mapping pair for the std::map
73+
"""
74+
res = []
75+
res.append('// NOLINT')
76+
res.append('{')
77+
res.append(f'"{arg_path}",')
78+
res.append('R"__sdf_literal__(')
79+
res.append(f'{arg_file_content}')
80+
res.append(')__sdf_literal__"')
81+
res.append('},')
82+
res.append('')
83+
return '\n'.join(res)
84+
85+
86+
def get_map_content(arg_pathlist: Path) -> str:
87+
"""
88+
Generates a string pair with the folder and filename as well as the content
89+
of the file in ascending order
90+
91+
:param arg_pathlist: Foldername and all filenames inside it
92+
:returns: mapping pairs for the std::map
93+
"""
94+
map_str = ''
95+
files = []
96+
for path in pathlist:
97+
files.append(str(path))
98+
# get ascending order
99+
files.sort()
100+
for file in files:
101+
with Path(file).open() as f:
102+
content = f.read()
103+
map_str += embed_sdf_content(file, content)
104+
return map_str
105+
106+
107+
def get_file_header_epilog() -> str:
108+
"""
109+
Provides the return statement and the closing brackets of the C++ file
110+
111+
:returns: epilog of the C++ file
112+
"""
113+
res = []
114+
res.append('')
115+
res.append(INDENTATION + '};')
116+
res.append('')
117+
res.append(INDENTATION + 'return result;')
118+
res.append('}')
119+
res.append('')
120+
res.append('}')
121+
res.append('} // namespace sdf')
122+
res.append('')
123+
return '\n'.join(res)
124+
125+
126+
if __name__ == "__main__":
127+
copyright = get_copyright_notice()
128+
prolog = get_file_header_prolog()
129+
130+
map_str = ""
131+
for sdf_version in SUPPORTED_SDF_VERSIONS:
132+
pathlist = Path(sdf_version).glob('*.sdf')
133+
map_str += get_map_content(pathlist)
134+
135+
for sdf_conversion in SUPPORTED_SDF_CONVERSIONS:
136+
pathlist = Path(sdf_conversion).glob('*.convert')
137+
map_str += get_map_content(pathlist)
138+
139+
# remove the last comma
140+
map_str = map_str[:-2]
141+
142+
epilog = get_file_header_epilog()
143+
144+
output = copyright + prolog + map_str + epilog
145+
146+
# output to stdin so that CMake can read it and create the appropriate file
147+
print(output)

sdf/embedSdf.rb

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)