1414
1515#include < csignal>
1616#include < cstdlib>
17+ #include < filesystem>
1718#include < iostream>
1819
1920#include < fastdds/dds/log/Log.hpp>
@@ -28,11 +29,16 @@ class CLIParser
2829
2930 struct example_config
3031 {
31- uint32_t expected_types_ = 0 ;
32- uint32_t expected_topics_ = 0 ;
33- uint32_t expected_data_ = 0 ;
34- uint32_t timeout_seconds = 30 ;
35- std::string config_file_path_ = " " ;
32+ uint32_t expected_types = 0 ;
33+ uint32_t expected_topics = 0 ;
34+ uint32_t expected_data = 0 ;
35+ uint32_t timeout = 30 ;
36+ std::string config_file_path = " " ;
37+ std::string persistence_path = " " ;
38+ std::string publish_path = " " ;
39+ std::string publish_topic = " " ;
40+ uint32_t publish_period = 500 ;
41+ uint32_t publish_initial_wait = 0 ;
3642 };
3743
3844 /* *
@@ -45,22 +51,31 @@ class CLIParser
4551 static void print_help (
4652 uint8_t return_code)
4753 {
48- std::cout <<
49- " Usage: ddsenabler_example <expected_types> <expected_topics> <expected_data> <timeout> <path/to/config/file>"
50- <<
51- std::endl;
52- std::cout << " " <<
53- std::endl;
54- std::cout << " expected_types: number of types to be expected" <<
55- std::endl;
56- std::cout << " expected_topics: number of topics to be expected" <<
57- std::endl;
58- std::cout << " expected_data: number of data to be expected" <<
59- std::endl;
60- std::cout << " timeout: time to wait before stopping the program if the data is not received" <<
61- std::endl;
62- std::cout << " path/to/config/file: absolute path to the configuration file" <<
63- std::endl;
54+ std::cout << " Usage: ddsenabler_example [options]" << std::endl;
55+ std::cout << " " << std::endl;
56+ std::cout << " --config <str> Path to the configuration file" << std::endl;
57+ std::cout << " (Default: '')" << std::endl;
58+ std::cout << " --expected-types <num> Number of types expected to be received" << std::endl;
59+ std::cout << " (Default: 0)" << std::endl;
60+ std::cout << " --expected-topics <num> Number of topics expected to be received" << std::endl;
61+ std::cout << " (Default: 0)" << std::endl;
62+ std::cout << " --expected-data <num> Number of samples expected to be received" << std::endl;
63+ std::cout << " (Default: 0)" << std::endl;
64+ std::cout << " --timeout <num> Time (seconds) to wait before stopping the" << std::endl;
65+ std::cout << " program if expectations are not met" << std::endl;
66+ std::cout << " (Default: 30)" << std::endl;
67+ std::cout << " --persistence-path <str> Path to the persistence directory" << std::endl;
68+ std::cout << " (Default: '')" << std::endl;
69+ std::cout << " --publish-path <str> Path to the directory with the samples" << std::endl;
70+ std::cout << " to be published" << std::endl;
71+ std::cout << " (Default: '')" << std::endl;
72+ std::cout << " --publish-topic <str> Topic name in which samples are published" << std::endl;
73+ std::cout << " (Default: '')" << std::endl;
74+ std::cout << " --publish-period <num> Data publication period in milliseconds" << std::endl;
75+ std::cout << " (Default: 500)" << std::endl;
76+ std::cout << " --publish-initial-wait <num> Time (seconds) to wait before starting" << std::endl;
77+ std::cout << " data publication" << std::endl;
78+ std::cout << " (Default: 0)" << std::endl;
6479 std::exit (return_code);
6580 }
6681
@@ -79,23 +94,224 @@ class CLIParser
7994 {
8095 example_config config;
8196
82- if (argc < 6 )
97+ if (argc < 2 )
8398 {
84- std::cerr << " Missing entity argument " << std::endl;
99+ std::cerr << " Configuration file path is required " << std::endl;
85100 print_help (EXIT_FAILURE );
86101 }
87102
88- try
103+ for ( int i = 1 ; i < argc; ++i)
89104 {
90- config.expected_types_ = std::stoi (argv[1 ]);
91- config.expected_topics_ = std::stoi (argv[2 ]);
92- config.expected_data_ = std::stoi (argv[3 ]);
93- config.timeout_seconds = std::stoi (argv[4 ]);
94- config.config_file_path_ = argv[5 ];
105+ std::string arg = argv[i];
106+
107+ if (arg == " -h" || arg == " --help" )
108+ {
109+ print_help (EXIT_SUCCESS );
110+ }
111+ else if (arg == " --config" )
112+ {
113+ if (++i < argc)
114+ {
115+ config.config_file_path = argv[i];
116+ if (!std::filesystem::exists (config.config_file_path ))
117+ {
118+ std::cerr << " Invalid configuration file path: " << config.config_file_path << std::endl;
119+ print_help (EXIT_FAILURE );
120+ }
121+ }
122+ else
123+ {
124+ std::cerr << " Failed to parse --config argument" << std::endl;
125+ print_help (EXIT_FAILURE );
126+ }
127+ }
128+ else if (arg == " --expected-types" )
129+ {
130+ if (++i < argc)
131+ {
132+ try
133+ {
134+ config.expected_types = static_cast <uint32_t >(std::stoi (argv[i]));
135+ }
136+ catch (const std::exception& e)
137+ {
138+ std::cerr << " Invalid --expected-types argument " << std::string (argv[i]) << " : " <<
139+ std::string (e.what ()) << std::endl;
140+ print_help (EXIT_FAILURE );
141+ }
142+ }
143+ else
144+ {
145+ std::cerr << " Failed to parse --expected-types argument" << std::endl;
146+ print_help (EXIT_FAILURE );
147+ }
148+ }
149+ else if (arg == " --expected-topics" )
150+ {
151+ if (++i < argc)
152+ {
153+ try
154+ {
155+ config.expected_topics = static_cast <uint32_t >(std::stoi (argv[i]));
156+ }
157+ catch (const std::exception& e)
158+ {
159+ std::cerr << " Invalid --expected-topics argument " << std::string (argv[i]) << " : " <<
160+ std::string (e.what ()) << std::endl;
161+ print_help (EXIT_FAILURE );
162+ }
163+ }
164+ else
165+ {
166+ std::cerr << " Failed to parse --expected-topics argument" << std::endl;
167+ print_help (EXIT_FAILURE );
168+ }
169+ }
170+ else if (arg == " --expected-data" )
171+ {
172+ if (++i < argc)
173+ {
174+ try
175+ {
176+ config.expected_data = static_cast <uint32_t >(std::stoi (argv[i]));
177+ }
178+ catch (const std::exception& e)
179+ {
180+ std::cerr << " Invalid --expected-data argument " << std::string (argv[i]) << " : " << std::string (
181+ e.what ()) << std::endl;
182+ print_help (EXIT_FAILURE );
183+ }
184+ }
185+ else
186+ {
187+ std::cerr << " Failed to parse --expected-data argument" << std::endl;
188+ print_help (EXIT_FAILURE );
189+ }
190+ }
191+ else if (arg == " --timeout" )
192+ {
193+ if (++i < argc)
194+ {
195+ try
196+ {
197+ config.timeout = static_cast <uint32_t >(std::stoi (argv[i]));
198+ }
199+ catch (const std::exception& e)
200+ {
201+ std::cerr << " Invalid --timeout argument " << std::string (argv[i]) << " : " << std::string (
202+ e.what ()) << std::endl;
203+ print_help (EXIT_FAILURE );
204+ }
205+ }
206+ else
207+ {
208+ std::cerr << " Failed to parse --timeout argument" << std::endl;
209+ print_help (EXIT_FAILURE );
210+ }
211+ }
212+ else if (arg == " --persistence-path" )
213+ {
214+ if (++i < argc)
215+ {
216+ config.persistence_path = argv[i];
217+ }
218+ else
219+ {
220+ std::cerr << " Failed to parse --persistence-path argument" << std::endl;
221+ print_help (EXIT_FAILURE );
222+ }
223+ }
224+ else if (arg == " --publish-path" )
225+ {
226+ if (++i < argc)
227+ {
228+ config.publish_path = argv[i];
229+ if (!std::filesystem::exists (config.publish_path ) ||
230+ !std::filesystem::is_directory (config.publish_path ))
231+ {
232+ std::cerr << " Invalid publish path: " << config.publish_path << std::endl;
233+ print_help (EXIT_FAILURE );
234+ }
235+ }
236+ else
237+ {
238+ std::cerr << " Failed to parse --publish-path argument" << std::endl;
239+ print_help (EXIT_FAILURE );
240+ }
241+ }
242+ else if (arg == " --publish-topic" )
243+ {
244+ if (++i < argc)
245+ {
246+ config.publish_topic = argv[i];
247+ }
248+ else
249+ {
250+ std::cerr << " Failed to parse --publish-topic argument" << std::endl;
251+ print_help (EXIT_FAILURE );
252+ }
253+ }
254+ else if (arg == " --publish-period" )
255+ {
256+ if (++i < argc)
257+ {
258+ try
259+ {
260+ config.publish_period = static_cast <uint32_t >(std::stoi (argv[i]));
261+ }
262+ catch (const std::exception& e)
263+ {
264+ std::cerr << " Invalid --publish-period argument " << std::string (argv[i]) << " : " <<
265+ std::string (
266+ e.what ()) << std::endl;
267+ print_help (EXIT_FAILURE );
268+ }
269+ }
270+ else
271+ {
272+ std::cerr << " Failed to parse --publish-period argument" << std::endl;
273+ print_help (EXIT_FAILURE );
274+ }
275+ }
276+ else if (arg == " --publish-initial-wait" )
277+ {
278+ if (++i < argc)
279+ {
280+ try
281+ {
282+ config.publish_initial_wait = static_cast <uint32_t >(std::stoi (argv[i]));
283+ }
284+ catch (const std::exception& e)
285+ {
286+ std::cerr << " Invalid --publish-initial-wait argument " << std::string (argv[i]) << " : " <<
287+ std::string (
288+ e.what ()) << std::endl;
289+ print_help (EXIT_FAILURE );
290+ }
291+ }
292+ else
293+ {
294+ std::cerr << " Failed to parse --publish-initial-wait argument" << std::endl;
295+ print_help (EXIT_FAILURE );
296+ }
297+ }
298+ else
299+ {
300+ std::cerr << " Failed to parse unknown argument: " << arg << std::endl;
301+ print_help (EXIT_FAILURE );
302+ }
95303 }
96- catch (const std::exception& e)
304+
305+ if (config.config_file_path .empty ())
97306 {
98- EPROSIMA_LOG_ERROR (CLI_PARSER , " Error parsing command line arguments: " << e.what ());
307+ std::cerr << " Configuration file path is required" << std::endl;
308+ print_help (EXIT_FAILURE );
309+ }
310+
311+ // Check that if publish path is set, publish topic is also set
312+ if (!config.publish_path .empty () && config.publish_topic .empty ())
313+ {
314+ std::cerr << " Publish topic is required when publish path is set" << std::endl;
99315 print_help (EXIT_FAILURE );
100316 }
101317
@@ -129,4 +345,3 @@ class CLIParser
129345 }
130346
131347};
132-
0 commit comments