YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include <vector>
7
8#include <cstdio>
9#include <cmath>
10#include <mutex>
11
12#include <iostream>
13#include <fstream>
14#include <yarp/os/Log.h>
15#include <yarp/os/LogStream.h>
16
17#include "generator.h"
18
19using namespace yarp::os;
20#define RETURN_CODE_ERROR 1
21#define RETURN_CODE_OK 0
22
24{
25 for (const auto& param : m_params)
26 {
27 std::cout << "Full Parameter name: " << param.getFullParamName() << std::endl;
28 std::cout << "Type: " << param.type << std::endl;
29 std::cout << "Units: " << param.units << std::endl;
30 std::cout << "Default Value: " << param.defaultValue << std::endl;
31 std::cout << "Required: " << param.required << std::endl;
32 std::cout << "Description: " << param.description << std::endl;
33 std::cout << "Notes: " << param.notes << std::endl;
34 std::cout << "------------------------" << std::endl;
35 }
36}
37
39{
40 bool b = true;
41 for (auto param : m_params)
42 {
43 //aaa::bbb is not nested (size == 1)
44 //aaa::bbb::ccc is nested (size == 2)
45 if (param.getListOfGroups().size() > 1)
46 b = false;
47 }
48 return !b;
49}
50
52{
53 std::cout << "Welcome to YarpDeviceParamParserGenerator tool. Syntax:\n";
54 std::cout << "1) yarpDeviceParamParserGenerator --class_name \"className\" --module_name \"moduleName\" --input_filename_md \"filename.md\" [--input_extra_comments \"comments.md\"] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir \"output_path\"] [--debug_mode]\n";
55 std::cout << "or:\n";
56 std::cout << "2) yarpDeviceParamParserGenerator --class_name \"className\" --module_name \"moduleName\" --input_filename_ini \"filename.ini\" [--input_extra_comments \"comments.md\"] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir \"output_path\"] [--debug_mode]\n";
57}
58
59int main(int argc, char *argv[])
60{
61 bool generate_ini_input_file = false;
62 bool generate_md_input_file = false;
63 bool generate_readme_md_file = false;
65 bool generate_yarpdev_file = false;
66 bool generate_code = true;
67 bool debug_mode = false;
68
69 std::string input_filename_type;
70 std::string input_filename;
71 std::string input_extra_comments;
72 std::string output_dir=".";
73 std::string class_name;
74 std::string module_name;
75
76#if 0 //debug only!
77 std::cout << "Invocation command " << argc << ":";
78 for (size_t i = 0; i < argc; ++i)
79 {
80 std::cout << argv[i] << " ";
81 }
82 std::cout << "<EOL>"<<std::endl;
83#endif
84
85 if (argc == 1)
86 {
87 print_help();
88 return RETURN_CODE_ERROR;
89 }
90
91 for (int i = 1; i < argc; ++i)
92 {
93 std::string arg = argv[i];
94 if (arg == "--help") {
95 print_help();
96 return RETURN_CODE_ERROR;
97 }
98 else if (arg == "--generate_md") {
100 }
101 else if (arg == "--generate_ini") {
103 }
104 else if (arg == "--generate_yarpdev") {
106 }
107 else if (arg == "--generate_yarprobotinterface") {
109 }
110 else if (arg == "--generate_readme_md_file") {
112 }
113 else if (arg == "--generate_all") {
119 }
120 else if (arg == "--input_filename_md" && i+1 < argc && argv[i+1][0] != '-') {
121 input_filename_type = "md";
122 input_filename = argv[i+1];
123 i++;
124 }
125 else if (arg == "--input_filename_ini" && i+1 < argc && argv[i+1][0] != '-') {
126 input_filename_type = "ini";
127 input_filename = argv[i+1];
128 i++;
129 }
130 else if (arg == "--input_extra_comments" && i + 1 < argc && argv[i + 1][0] != '-') {
131 input_extra_comments = argv[i + 1];
132 i++;
133 }
134 else if (arg == "--output_dir" && i+1 < argc && argv[i+1][0] != '-') {
135 output_dir = argv[i+1];
136 i++;
137 }
138 else if (arg == "--class_name" && i + 1 < argc && argv[i + 1][0] != '-') {
139 class_name = argv[i + 1];
140 i++;
141 }
142 else if (arg == "--module_name" && i + 1 < argc && argv[i + 1][0] != '-') {
143 module_name = argv[i + 1];
144 i++;
145 }
146 else if (arg == "--debug_mode") {
147 debug_mode = true;
148 }
149 }
150
151 if (input_filename_type.empty())
152 {
153 std::cerr << "Invalid file type. Check parameter --input_filename_md or --input_filename_ini\n";
154 return RETURN_CODE_ERROR;
155 }
156 if (input_filename.empty())
157 {
158 std::cerr << "Invalid file name. Check parameter --input_filename_md or --input_filename_ini\n";
159 return RETURN_CODE_ERROR;
160 }
161 if (class_name.empty())
162 {
163 std::cerr << "Invalid class name. Check parameter --class_name\n";
164 return RETURN_CODE_ERROR;
165 }
166 if (module_name.empty())
167 {
168 std::cerr << "Invalid module name. Check parameter --module_name\n";
169 return RETURN_CODE_ERROR;
170 }
171
173 if (input_filename_type == "md")
174 {
175 if (!pgen.parseMdParams(input_filename))
176 {
177 std::cerr<<"parseMdParams failed";
178 return RETURN_CODE_ERROR;
179 }
180 }
181 else if (input_filename_type == "ini")
182 {
183 if (!pgen.parseIniParams(input_filename))
184 {
185 std::cerr << "parseMdParams failed";
186 return RETURN_CODE_ERROR;
187 }
188 }
189 else
190 {
191 std::cerr << "Invalid input file name";
192 return RETURN_CODE_ERROR;
193 }
194
195 //read the extra comments (if available)
196 if (!input_extra_comments.empty())
197 {pgen.parseExtraComments(input_extra_comments);}
198
199 //prepare the output path
200 while (!output_dir.empty() && (output_dir.back() == '\\' || output_dir.back() == '/')) {
201 output_dir.pop_back();}
202 output_dir += '/';
203 pgen.m_classname = class_name;
204 pgen.m_modulename = module_name;
205 pgen.m_component = pgen.m_classname + "ParamsCOMPONENT";
206 std::string output_filename = class_name + "_ParamsParser";
207 pgen.m_output_header_filename = output_dir + output_filename + ".h";
208 pgen.m_output_cpp_filename = output_dir + output_filename + ".cpp";
209 pgen.m_output_ini_filename = output_dir + output_filename + ".bot";
210 pgen.m_output_md_filename = output_dir + output_filename + ".md";
211 pgen.m_output_readme_md_filename = output_dir + "readme.md";
212 pgen.m_output_yarpdev_filename = output_dir + output_filename + ".ini";
213 pgen.m_output_yarprobotinterface_filename = output_dir + output_filename + ".xml";
214
215 //print params
216 if (debug_mode)
217 {
218 pgen.printParams();
219 }
220
222 {
223 std::string iniParamfile = pgen.generateIniParams();
224 std::ofstream file_iniParamfile(pgen.m_output_ini_filename);
225 bool b = file_iniParamfile.is_open();
226 if (!b) { std::cerr << "Failed to write file:" << pgen.m_output_ini_filename; return RETURN_CODE_ERROR; }
229 }
230
232 {
233 std::string mdParamfile = pgen.generateMdParams();
234 std::ofstream file_mdParamfile(pgen.m_output_md_filename);
235 bool b = file_mdParamfile.is_open();
236 if (!b) { std::cerr << "Failed to write file:" << pgen.m_output_md_filename; return RETURN_CODE_ERROR; }
239 }
240
242 {
243 std::string readmeFile = pgen.generateReadmeMd();
244 std::ofstream file_readmeParamfile(pgen.m_output_readme_md_filename);
245 bool b = file_readmeParamfile.is_open();
246 if (!b) { std::cerr << "Failed to write file:" << pgen.m_output_md_filename; return RETURN_CODE_ERROR; }
249 }
250
252 {
253 //yarpdev files (.ini format) have some limitations: they cannot be nested. For example:
254 //aaa::bbb This is ok, it is not nested (size of getListOfGroups() of param bbbb == 1)
255 //aaa::bbb::ccc is nested (size of getListOfGroups of param ccc == 2)
256 if (!pgen.nested_sections_found())
257 {
258 std::string yarpdevParamfile = pgen.generateYarpdevFile();
259 std::ofstream file_yarpdevParamfile(pgen.m_output_yarpdev_filename);
260 bool b = file_yarpdevParamfile.is_open();
261 if (!b) { std::cerr << "Failed to write file:" << pgen.m_output_yarpdev_filename; return RETURN_CODE_ERROR; }
264 }
265 else
266 {
267 std::cerr << "a yarpdev file with nested sections cannot be generated";
268 std::ofstream file_yarpdevParamfile(pgen.m_output_yarpdev_filename);
269 file_yarpdevParamfile << "a yarpdev file with nested sections cannot be generated";
271 }
272 }
273
275 {
276 //yarprobotinterface files (.xml format) support multiple levels of nesting
277 std::string yrobotParamfile = pgen.generateYarprobotinterface();
278 std::ofstream file_yrobotParamfile(pgen.m_output_yarprobotinterface_filename);
279 bool b = file_yrobotParamfile.is_open();
280 if (!b) { std::cerr << "Failed to write file:" << pgen.m_output_yarprobotinterface_filename; return RETURN_CODE_ERROR; }
283 }
284
285 if (generate_code)
286 {
287 std::string hfile = pgen.generateHeader();
288 std::ofstream file_hfile(pgen.m_output_header_filename);
289 bool bh = file_hfile.is_open();
290 if (!bh) { std::cerr << "Failed to write file:" << pgen.m_output_header_filename; return RETURN_CODE_ERROR; }
291 file_hfile << hfile;
293
294 std::string cppfile = pgen.generateCpp();
295 std::ofstream file_cppfile(pgen.m_output_cpp_filename);
296 bool bc = file_cppfile.is_open();
297 if (!bc) { std::cerr << "Failed to write file:" << pgen.m_output_cpp_filename; return RETURN_CODE_ERROR; }
300 }
301
302 std::cout << "Generation process successfully completed.";
303 return RETURN_CODE_OK;
304}
305
307{
308 std::ostringstream s;
309s << license_banner;
310s << version_banner;
311s << current_time();
312s << "\
313\n\
314#include \"" << m_classname << "_ParamsParser.h\"\n\
315#include <yarp/os/LogStream.h>\n\
316#include <yarp/os/Value.h>\n\
317\n\
318namespace {\n\
319 YARP_LOG_COMPONENT("<< m_component << ", \"yarp.device." << m_classname << "\")\n\
320}\n\
321\n";
322
323 s << generateConstructor();
330
331 return s.str();
332}
std::string m_component
Definition generator.h:40
std::string generateCpp()
Definition main.cpp:306
std::string generateFunction_getDocumentationOfDeviceParams()
std::string m_classname
Definition generator.h:38
std::string generateFunction_getParamValue()
std::string generateFunction_getListOfParams()
std::string generateFunction_getConfiguration()
std::string generateFunction_getDeviceType()
Definition generator.h:57
std::deque< Parameter > m_params
Definition generator.h:34
bool nested_sections_found()
Definition main.cpp:38
A mini-server for performing network communication in the background.
void close() override
Stop port activity.
int main(int argc, char *argv[])
Definition main.cpp:59
#define RETURN_CODE_ERROR
Definition main.cpp:20
void print_help()
Definition main.cpp:51
#define RETURN_CODE_OK
Definition main.cpp:21
std::string current_time()
Definition utils.h:24
const std::string license_banner
Definition generator.h:80
const std::string version_banner
Definition generator.h:88
An interface to the operating system, including Port based communication.