1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation.
3a9de470cSBruce Richardson * Copyright(c) 2014 6WIND S.A.
4a9de470cSBruce Richardson */
5a9de470cSBruce Richardson
6a9de470cSBruce Richardson #include <stdio.h>
7a9de470cSBruce Richardson #include <stdarg.h>
8a9de470cSBruce Richardson #include <stdint.h>
9a9de470cSBruce Richardson #include <string.h>
10a9de470cSBruce Richardson #include <stdlib.h>
11a9de470cSBruce Richardson #include <inttypes.h>
12a9de470cSBruce Richardson #include <errno.h>
13a9de470cSBruce Richardson #include <sys/queue.h>
14a9de470cSBruce Richardson
15a9de470cSBruce Richardson #include <rte_common.h>
16a9de470cSBruce Richardson #include <rte_log.h>
17a9de470cSBruce Richardson #include <rte_debug.h>
18a9de470cSBruce Richardson #include <rte_memory.h>
19a9de470cSBruce Richardson #include <rte_memcpy.h>
20a9de470cSBruce Richardson #include <rte_memzone.h>
21a9de470cSBruce Richardson #include <rte_launch.h>
22a9de470cSBruce Richardson #include <rte_cycles.h>
23a9de470cSBruce Richardson #include <rte_eal.h>
24a9de470cSBruce Richardson #include <rte_per_lcore.h>
25a9de470cSBruce Richardson #include <rte_lcore.h>
26a9de470cSBruce Richardson #include <rte_branch_prediction.h>
27a9de470cSBruce Richardson #include <rte_ring.h>
28a9de470cSBruce Richardson #include <rte_malloc.h>
29a9de470cSBruce Richardson #include <rte_mempool.h>
30a9de470cSBruce Richardson #include <rte_mbuf.h>
31a9de470cSBruce Richardson #include <rte_devargs.h>
32a9de470cSBruce Richardson
33a9de470cSBruce Richardson #include <cmdline_rdline.h>
34a9de470cSBruce Richardson #include <cmdline_parse.h>
35a9de470cSBruce Richardson #include <cmdline_parse_ipaddr.h>
36a9de470cSBruce Richardson #include <cmdline_parse_num.h>
37a9de470cSBruce Richardson #include <cmdline_parse_string.h>
38a9de470cSBruce Richardson #include <cmdline.h>
3932364372SPallantla Poornima #include <rte_string_fns.h>
40a9de470cSBruce Richardson
41a9de470cSBruce Richardson #include "test.h"
42a9de470cSBruce Richardson
43a9de470cSBruce Richardson /****************/
44a9de470cSBruce Richardson
45a9de470cSBruce Richardson static struct test_commands_list commands_list =
46a9de470cSBruce Richardson TAILQ_HEAD_INITIALIZER(commands_list);
47a9de470cSBruce Richardson
48a9de470cSBruce Richardson void
add_test_command(struct test_command * t)49a9de470cSBruce Richardson add_test_command(struct test_command *t)
50a9de470cSBruce Richardson {
51a9de470cSBruce Richardson TAILQ_INSERT_TAIL(&commands_list, t, next);
52a9de470cSBruce Richardson }
53a9de470cSBruce Richardson
54a9de470cSBruce Richardson struct cmd_autotest_result {
55a9de470cSBruce Richardson cmdline_fixed_string_t autotest;
56a9de470cSBruce Richardson };
57a9de470cSBruce Richardson
cmd_autotest_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)58a9de470cSBruce Richardson static void cmd_autotest_parsed(void *parsed_result,
59f2fc83b4SThomas Monjalon __rte_unused struct cmdline *cl,
60f2fc83b4SThomas Monjalon __rte_unused void *data)
61a9de470cSBruce Richardson {
62a9de470cSBruce Richardson struct test_command *t;
63a9de470cSBruce Richardson struct cmd_autotest_result *res = parsed_result;
64a9de470cSBruce Richardson int ret = 0;
65a9de470cSBruce Richardson
66a9de470cSBruce Richardson TAILQ_FOREACH(t, &commands_list, next) {
67a9de470cSBruce Richardson if (!strcmp(res->autotest, t->command))
68a9de470cSBruce Richardson ret = t->callback();
69a9de470cSBruce Richardson }
70a9de470cSBruce Richardson
71a9de470cSBruce Richardson last_test_result = ret;
72a9de470cSBruce Richardson if (ret == 0)
73a9de470cSBruce Richardson printf("Test OK\n");
74a9de470cSBruce Richardson else if (ret == TEST_SKIPPED)
75a9de470cSBruce Richardson printf("Test Skipped\n");
76a9de470cSBruce Richardson else
77a9de470cSBruce Richardson printf("Test Failed\n");
78a9de470cSBruce Richardson fflush(stdout);
79a9de470cSBruce Richardson }
80a9de470cSBruce Richardson
81a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_autotest_autotest =
82a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
83a9de470cSBruce Richardson "");
84a9de470cSBruce Richardson
85a9de470cSBruce Richardson cmdline_parse_inst_t cmd_autotest = {
86a9de470cSBruce Richardson .f = cmd_autotest_parsed, /* function to call */
87a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */
88a9de470cSBruce Richardson .help_str = "launch autotest",
89a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */
90a9de470cSBruce Richardson (void *)&cmd_autotest_autotest,
91a9de470cSBruce Richardson NULL,
92a9de470cSBruce Richardson },
93a9de470cSBruce Richardson };
94a9de470cSBruce Richardson
95a9de470cSBruce Richardson /****************/
96a9de470cSBruce Richardson
97a9de470cSBruce Richardson struct cmd_dump_result {
98a9de470cSBruce Richardson cmdline_fixed_string_t dump;
99a9de470cSBruce Richardson };
100a9de470cSBruce Richardson
101a9de470cSBruce Richardson static void
dump_struct_sizes(void)102a9de470cSBruce Richardson dump_struct_sizes(void)
103a9de470cSBruce Richardson {
104a9de470cSBruce Richardson #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
105a9de470cSBruce Richardson DUMP_SIZE(struct rte_mbuf);
106a9de470cSBruce Richardson DUMP_SIZE(struct rte_mempool);
107a9de470cSBruce Richardson DUMP_SIZE(struct rte_ring);
108a9de470cSBruce Richardson #undef DUMP_SIZE
109a9de470cSBruce Richardson }
110a9de470cSBruce Richardson
111*449dc649SBruce Richardson /* Add the dump_* tests cases 8< */
cmd_dump_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)112a9de470cSBruce Richardson static void cmd_dump_parsed(void *parsed_result,
113f2fc83b4SThomas Monjalon __rte_unused struct cmdline *cl,
114f2fc83b4SThomas Monjalon __rte_unused void *data)
115a9de470cSBruce Richardson {
116a9de470cSBruce Richardson struct cmd_dump_result *res = parsed_result;
117a9de470cSBruce Richardson
118a9de470cSBruce Richardson if (!strcmp(res->dump, "dump_physmem"))
119a9de470cSBruce Richardson rte_dump_physmem_layout(stdout);
120a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_memzone"))
121a9de470cSBruce Richardson rte_memzone_dump(stdout);
122a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_struct_sizes"))
123a9de470cSBruce Richardson dump_struct_sizes();
124a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_ring"))
125a9de470cSBruce Richardson rte_ring_list_dump(stdout);
126a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_mempool"))
127a9de470cSBruce Richardson rte_mempool_list_dump(stdout);
128a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_devargs"))
129a9de470cSBruce Richardson rte_devargs_dump(stdout);
130a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_log_types"))
131a9de470cSBruce Richardson rte_log_dump(stdout);
132a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_malloc_stats"))
133a9de470cSBruce Richardson rte_malloc_dump_stats(stdout, NULL);
134a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_malloc_heaps"))
135a9de470cSBruce Richardson rte_malloc_dump_heaps(stdout);
136a9de470cSBruce Richardson }
137a9de470cSBruce Richardson
138a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_dump_dump =
139a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
140a9de470cSBruce Richardson "dump_physmem#"
141a9de470cSBruce Richardson "dump_memzone#"
142a9de470cSBruce Richardson "dump_struct_sizes#"
143a9de470cSBruce Richardson "dump_ring#"
144a9de470cSBruce Richardson "dump_mempool#"
145a9de470cSBruce Richardson "dump_malloc_stats#"
146a9de470cSBruce Richardson "dump_malloc_heaps#"
147a9de470cSBruce Richardson "dump_devargs#"
148a9de470cSBruce Richardson "dump_log_types");
149a9de470cSBruce Richardson
150a9de470cSBruce Richardson cmdline_parse_inst_t cmd_dump = {
151a9de470cSBruce Richardson .f = cmd_dump_parsed, /* function to call */
152a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */
153a9de470cSBruce Richardson .help_str = "dump status",
154a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */
155a9de470cSBruce Richardson (void *)&cmd_dump_dump,
156a9de470cSBruce Richardson NULL,
157a9de470cSBruce Richardson },
158a9de470cSBruce Richardson };
159*449dc649SBruce Richardson /* >8 End of add the dump_* tests cases */
160a9de470cSBruce Richardson
161a9de470cSBruce Richardson /****************/
162a9de470cSBruce Richardson
163a9de470cSBruce Richardson struct cmd_dump_one_result {
164a9de470cSBruce Richardson cmdline_fixed_string_t dump;
165a9de470cSBruce Richardson cmdline_fixed_string_t name;
166a9de470cSBruce Richardson };
167a9de470cSBruce Richardson
cmd_dump_one_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)168a9de470cSBruce Richardson static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
169f2fc83b4SThomas Monjalon __rte_unused void *data)
170a9de470cSBruce Richardson {
171a9de470cSBruce Richardson struct cmd_dump_one_result *res = parsed_result;
172a9de470cSBruce Richardson
173a9de470cSBruce Richardson if (!strcmp(res->dump, "dump_ring")) {
174a9de470cSBruce Richardson struct rte_ring *r;
175a9de470cSBruce Richardson r = rte_ring_lookup(res->name);
176a9de470cSBruce Richardson if (r == NULL) {
177a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find ring\n");
178a9de470cSBruce Richardson return;
179a9de470cSBruce Richardson }
180a9de470cSBruce Richardson rte_ring_dump(stdout, r);
181a9de470cSBruce Richardson }
182a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_mempool")) {
183a9de470cSBruce Richardson struct rte_mempool *mp;
184a9de470cSBruce Richardson mp = rte_mempool_lookup(res->name);
185a9de470cSBruce Richardson if (mp == NULL) {
186a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find mempool\n");
187a9de470cSBruce Richardson return;
188a9de470cSBruce Richardson }
189a9de470cSBruce Richardson rte_mempool_dump(stdout, mp);
190a9de470cSBruce Richardson }
191a9de470cSBruce Richardson }
192a9de470cSBruce Richardson
193a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_dump_one_dump =
194a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
195a9de470cSBruce Richardson "dump_ring#dump_mempool");
196a9de470cSBruce Richardson
197a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_dump_one_name =
198a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
199a9de470cSBruce Richardson
200a9de470cSBruce Richardson cmdline_parse_inst_t cmd_dump_one = {
201a9de470cSBruce Richardson .f = cmd_dump_one_parsed, /* function to call */
202a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */
203a9de470cSBruce Richardson .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
204a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */
205a9de470cSBruce Richardson (void *)&cmd_dump_one_dump,
206a9de470cSBruce Richardson (void *)&cmd_dump_one_name,
207a9de470cSBruce Richardson NULL,
208a9de470cSBruce Richardson },
209a9de470cSBruce Richardson };
210a9de470cSBruce Richardson
211a9de470cSBruce Richardson /****************/
212a9de470cSBruce Richardson
213a9de470cSBruce Richardson struct cmd_quit_result {
214a9de470cSBruce Richardson cmdline_fixed_string_t quit;
215a9de470cSBruce Richardson };
216a9de470cSBruce Richardson
217a9de470cSBruce Richardson static void
cmd_quit_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)218f2fc83b4SThomas Monjalon cmd_quit_parsed(__rte_unused void *parsed_result,
219a9de470cSBruce Richardson struct cmdline *cl,
220f2fc83b4SThomas Monjalon __rte_unused void *data)
221a9de470cSBruce Richardson {
222a9de470cSBruce Richardson cmdline_quit(cl);
223a9de470cSBruce Richardson }
224a9de470cSBruce Richardson
225a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_quit_quit =
226a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit,
227a9de470cSBruce Richardson "quit");
228a9de470cSBruce Richardson
229a9de470cSBruce Richardson cmdline_parse_inst_t cmd_quit = {
230a9de470cSBruce Richardson .f = cmd_quit_parsed, /* function to call */
231a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */
232a9de470cSBruce Richardson .help_str = "exit application",
233a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */
234a9de470cSBruce Richardson (void *)&cmd_quit_quit,
235a9de470cSBruce Richardson NULL,
236a9de470cSBruce Richardson },
237a9de470cSBruce Richardson };
238a9de470cSBruce Richardson
239a9de470cSBruce Richardson /****************/
240a9de470cSBruce Richardson
241a9de470cSBruce Richardson struct cmd_set_rxtx_result {
242a9de470cSBruce Richardson cmdline_fixed_string_t set;
243a9de470cSBruce Richardson cmdline_fixed_string_t mode;
244a9de470cSBruce Richardson };
245a9de470cSBruce Richardson
cmd_set_rxtx_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)246a9de470cSBruce Richardson static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl,
247f2fc83b4SThomas Monjalon __rte_unused void *data)
248a9de470cSBruce Richardson {
249a9de470cSBruce Richardson struct cmd_set_rxtx_result *res = parsed_result;
250a9de470cSBruce Richardson if (test_set_rxtx_conf(res->mode) < 0)
251a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find such mode\n");
252a9de470cSBruce Richardson }
253a9de470cSBruce Richardson
254a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_set =
255a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set,
256a9de470cSBruce Richardson "set_rxtx_mode");
257a9de470cSBruce Richardson
258a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_mode =
259a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL);
260a9de470cSBruce Richardson
261a9de470cSBruce Richardson cmdline_parse_inst_t cmd_set_rxtx = {
262a9de470cSBruce Richardson .f = cmd_set_rxtx_parsed, /* function to call */
263a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */
264a9de470cSBruce Richardson .help_str = "set rxtx routine: "
265a9de470cSBruce Richardson "set_rxtx <mode>",
266a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */
267a9de470cSBruce Richardson (void *)&cmd_set_rxtx_set,
268a9de470cSBruce Richardson (void *)&cmd_set_rxtx_mode,
269a9de470cSBruce Richardson NULL,
270a9de470cSBruce Richardson },
271a9de470cSBruce Richardson };
272a9de470cSBruce Richardson
273a9de470cSBruce Richardson /****************/
274a9de470cSBruce Richardson
275a9de470cSBruce Richardson struct cmd_set_rxtx_anchor {
276a9de470cSBruce Richardson cmdline_fixed_string_t set;
277a9de470cSBruce Richardson cmdline_fixed_string_t type;
278a9de470cSBruce Richardson };
279a9de470cSBruce Richardson
280a9de470cSBruce Richardson static void
cmd_set_rxtx_anchor_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)281a9de470cSBruce Richardson cmd_set_rxtx_anchor_parsed(void *parsed_result,
282a9de470cSBruce Richardson struct cmdline *cl,
283f2fc83b4SThomas Monjalon __rte_unused void *data)
284a9de470cSBruce Richardson {
285a9de470cSBruce Richardson struct cmd_set_rxtx_anchor *res = parsed_result;
286a9de470cSBruce Richardson if (test_set_rxtx_anchor(res->type) < 0)
287a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find such anchor\n");
288a9de470cSBruce Richardson }
289a9de470cSBruce Richardson
290a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_anchor_set =
291a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set,
292a9de470cSBruce Richardson "set_rxtx_anchor");
293a9de470cSBruce Richardson
294a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_anchor_type =
295a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL);
296a9de470cSBruce Richardson
297a9de470cSBruce Richardson cmdline_parse_inst_t cmd_set_rxtx_anchor = {
298a9de470cSBruce Richardson .f = cmd_set_rxtx_anchor_parsed, /* function to call */
299a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */
300a9de470cSBruce Richardson .help_str = "set rxtx anchor: "
301a9de470cSBruce Richardson "set_rxtx_anchor <type>",
302a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */
303a9de470cSBruce Richardson (void *)&cmd_set_rxtx_anchor_set,
304a9de470cSBruce Richardson (void *)&cmd_set_rxtx_anchor_type,
305a9de470cSBruce Richardson NULL,
306a9de470cSBruce Richardson },
307a9de470cSBruce Richardson };
308a9de470cSBruce Richardson
309a9de470cSBruce Richardson /****************/
310a9de470cSBruce Richardson
311a9de470cSBruce Richardson /* for stream control */
312a9de470cSBruce Richardson struct cmd_set_rxtx_sc {
313a9de470cSBruce Richardson cmdline_fixed_string_t set;
314a9de470cSBruce Richardson cmdline_fixed_string_t type;
315a9de470cSBruce Richardson };
316a9de470cSBruce Richardson
317a9de470cSBruce Richardson static void
cmd_set_rxtx_sc_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)318a9de470cSBruce Richardson cmd_set_rxtx_sc_parsed(void *parsed_result,
319a9de470cSBruce Richardson struct cmdline *cl,
320f2fc83b4SThomas Monjalon __rte_unused void *data)
321a9de470cSBruce Richardson {
322a9de470cSBruce Richardson struct cmd_set_rxtx_sc *res = parsed_result;
323a9de470cSBruce Richardson if (test_set_rxtx_sc(res->type) < 0)
324a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find such stream control\n");
325a9de470cSBruce Richardson }
326a9de470cSBruce Richardson
327a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_sc_set =
328a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set,
329a9de470cSBruce Richardson "set_rxtx_sc");
330a9de470cSBruce Richardson
331a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_sc_type =
332a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL);
333a9de470cSBruce Richardson
334a9de470cSBruce Richardson cmdline_parse_inst_t cmd_set_rxtx_sc = {
335a9de470cSBruce Richardson .f = cmd_set_rxtx_sc_parsed, /* function to call */
336a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */
337a9de470cSBruce Richardson .help_str = "set rxtx stream control: "
338a9de470cSBruce Richardson "set_rxtx_sc <type>",
339a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */
340a9de470cSBruce Richardson (void *)&cmd_set_rxtx_sc_set,
341a9de470cSBruce Richardson (void *)&cmd_set_rxtx_sc_type,
342a9de470cSBruce Richardson NULL,
343a9de470cSBruce Richardson },
344a9de470cSBruce Richardson };
345a9de470cSBruce Richardson
346a9de470cSBruce Richardson /****************/
347a9de470cSBruce Richardson
348a9de470cSBruce Richardson
349a9de470cSBruce Richardson cmdline_parse_ctx_t main_ctx[] = {
350a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_autotest,
351a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_dump,
352a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_dump_one,
353a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_quit,
354a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_set_rxtx,
355a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,
356a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_set_rxtx_sc,
357a9de470cSBruce Richardson NULL,
358a9de470cSBruce Richardson };
359a9de470cSBruce Richardson
commands_init(void)360a9de470cSBruce Richardson int commands_init(void)
361a9de470cSBruce Richardson {
362a9de470cSBruce Richardson struct test_command *t;
36332364372SPallantla Poornima char *commands;
364a9de470cSBruce Richardson int commands_len = 0;
365a9de470cSBruce Richardson
366a9de470cSBruce Richardson TAILQ_FOREACH(t, &commands_list, next) {
367a9de470cSBruce Richardson commands_len += strlen(t->command) + 1;
368a9de470cSBruce Richardson }
369a9de470cSBruce Richardson
37032364372SPallantla Poornima commands = (char *)calloc(commands_len, sizeof(char));
371a9de470cSBruce Richardson if (!commands)
372a9de470cSBruce Richardson return -1;
373a9de470cSBruce Richardson
374a9de470cSBruce Richardson TAILQ_FOREACH(t, &commands_list, next) {
37532364372SPallantla Poornima strlcat(commands, t->command, commands_len);
37632364372SPallantla Poornima if (TAILQ_NEXT(t, next) != NULL)
37732364372SPallantla Poornima strlcat(commands, "#", commands_len);
378a9de470cSBruce Richardson }
379a9de470cSBruce Richardson
380a9de470cSBruce Richardson cmd_autotest_autotest.string_data.str = commands;
381a9de470cSBruce Richardson return 0;
382a9de470cSBruce Richardson }
383