net/softnic: add command interface
[dpdk.git] / drivers / net / softnic / rte_eth_softnic_cli.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "rte_eth_softnic_internals.h"
11 #include "parser.h"
12
13 #ifndef CMD_MAX_TOKENS
14 #define CMD_MAX_TOKENS     256
15 #endif
16
17 #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
18 #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
19 #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
20 #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
21 #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
22 #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
23 #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
24 #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
25 #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
26 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
27 #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
28
29 static int
30 is_comment(char *in)
31 {
32         if ((strlen(in) && index("!#%;", in[0])) ||
33                 (strncmp(in, "//", 2) == 0) ||
34                 (strncmp(in, "--", 2) == 0))
35                 return 1;
36
37         return 0;
38 }
39
40 void
41 softnic_cli_process(char *in, char *out, size_t out_size, void *arg __rte_unused)
42 {
43         char *tokens[CMD_MAX_TOKENS];
44         uint32_t n_tokens = RTE_DIM(tokens);
45         int status;
46
47         if (is_comment(in))
48                 return;
49
50         status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
51         if (status) {
52                 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
53                 return;
54         }
55
56         if (n_tokens == 0)
57                 return;
58
59         snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
60 }
61
62 int
63 softnic_cli_script_process(struct pmd_internals *softnic,
64         const char *file_name,
65         size_t msg_in_len_max,
66         size_t msg_out_len_max)
67 {
68         char *msg_in = NULL, *msg_out = NULL;
69         FILE *f = NULL;
70
71         /* Check input arguments */
72         if (file_name == NULL ||
73                 strlen(file_name) == 0 ||
74                 msg_in_len_max == 0 ||
75                 msg_out_len_max == 0)
76                 return -EINVAL;
77
78         msg_in = malloc(msg_in_len_max + 1);
79         msg_out = malloc(msg_out_len_max + 1);
80         if (msg_in == NULL ||
81                 msg_out == NULL) {
82                 free(msg_out);
83                 free(msg_in);
84                 return -ENOMEM;
85         }
86
87         /* Open input file */
88         f = fopen(file_name, "r");
89         if (f == NULL) {
90                 free(msg_out);
91                 free(msg_in);
92                 return -EIO;
93         }
94
95         /* Read file */
96         for ( ; ; ) {
97                 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
98                         break;
99
100                 printf("%s", msg_in);
101                 msg_out[0] = 0;
102
103                 softnic_cli_process(msg_in,
104                         msg_out,
105                         msg_out_len_max,
106                         softnic);
107
108                 if (strlen(msg_out))
109                         printf("%s", msg_out);
110         }
111
112         /* Close file */
113         fclose(f);
114         free(msg_out);
115         free(msg_in);
116         return 0;
117 }