summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@samsung.com>2015-07-29 11:01:45 +0300
committerDaniel Zaoui <daniel.zaoui@samsung.com>2015-07-29 11:01:45 +0300
commitff456f5da13423ca519abdfb8275ae1783c9837a (patch)
tree21834a7b6e9eb569c81dd4b0f67cecff7e26c942
parent45278cd4bf784b774eb6b65d45e971bcfc72714a (diff)
CLI: Add command parsing
-rw-r--r--src/bin/cli.c218
1 files changed, 192 insertions, 26 deletions
diff --git a/src/bin/cli.c b/src/bin/cli.c
index e5466bf..4389602 100644
--- a/src/bin/cli.c
+++ b/src/bin/cli.c
@@ -5,34 +5,194 @@
5#include <Eina.h> 5#include <Eina.h>
6#include <Eolian.h> 6#include <Eolian.h>
7 7
8int _edbg_log_dom = -1; 8#define MAX_EVENTS 5
9 9
10#ifdef ERR 10static Eina_Hash *vars_hash = NULL;
11# undef ERR 11static Eina_Bool exit_required = EINA_FALSE;
12#endif
13#define ERR(...) EINA_LOG_DOM_ERR(_edbg_log_dom, __VA_ARGS__)
14 12
15#ifdef DBG 13static const char *good_commands [] =
16# undef DBG 14{
17#endif 15 "quit",
18#define DBG(...) EINA_LOG_DOM_DBG(_edbg_log_dom, __VA_ARGS__) 16 "list",
17 "print",
18 NULL
19};
19 20
20#ifdef INF 21enum
21# undef INF 22{
22#endif 23 QUIT_COMMAND,
23#define INF(...) EINA_LOG_DOM_INFO(_edbg_log_dom, __VA_ARGS__) 24 LIST_COMMAND,
25 PRINT_COMMAND,
26 UNKNOWN_COMMAND
27};
28
29typedef struct
30{
31 char buffer[128];
32 const char *current;
33 unsigned int buf_end;
34} Lexer;
24 35
25#ifdef WRN 36static void
26# undef WRN 37_lexer_reset(Lexer *l)
27#endif 38{
28#define WRN(...) EINA_LOG_DOM_WARN(_edbg_log_dom, __VA_ARGS__) 39 memset(l->buffer, 0, sizeof(l->buffer));
40 l->current = l->buffer;
41 l->buf_end = 0;
42}
29 43
30#ifdef CRIT 44static void
31# undef CRIT 45_ws_skip(Lexer *l)
32#endif 46{
33#define CRIT(...) EINA_LOG_DOM_CRIT(_edbg_log_dom, __VA_ARGS__) 47 while (*(l->current) == ' ') (l->current)++; /* Remove spaces */
48}
34 49
35#define MAX_EVENTS 5 50static Eina_Bool
51_next_token(Lexer *l, const char *token)
52{
53 _ws_skip(l);
54 if (!strncmp(l->current, token, strlen(token)))
55 {
56 l->current += strlen(token);
57 return EINA_TRUE;
58 }
59 return EINA_FALSE;
60}
61
62static char *
63_next_word(Lexer *l, const char *special)
64{
65 if (!special) special = "";
66 _ws_skip(l);
67 const char *str = l->current;
68 while (*str &&
69 ((*str >= 'a' && *str <= 'z') ||
70 (*str >= 'A' && *str <= 'Z') ||
71 (*str >= '0' && *str <= '9') ||
72 strchr(special, *str) ||
73 *str == '_')) str++;
74 if (str == l->current) return NULL;
75 char *word = malloc(str - l->current);
76 memcpy(word, l->current, str - l->current);
77 l->current = str;
78 return word;
79}
80
81static int
82_next_command(Lexer *l)
83{
84 int i = 0, ret = -1;
85 char *word = _next_word(l, NULL);
86 if (!word) return ret;
87 const char *cmd = good_commands[0];
88 while (cmd)
89 {
90 int len = strlen(cmd);
91 if (cmd && !strncmp(cmd, word, len)) ret = i;
92 i++;
93 cmd = good_commands[i];
94 }
95 if (ret == -1) l->current = l->buffer;
96 free(word);
97 return ret;
98}
99
100static char *
101_function_invoke(const char *func_str, const char *obj_str)
102{
103 /*
104 * Packet preparation
105 * May be parenthesis with parameter
106 * Sending
107 * Receiving
108 * Parsing response
109 */
110 return strdup("37");
111}
112
113static Eina_Bool
114_char_consume(Lexer *l, char c)
115{
116 if (l->buf_end >= sizeof(l->buffer) - 2) return EINA_FALSE;
117 if (c == '\n')
118 {
119 int cmd_type = _next_command(l);
120 switch (cmd_type)
121 {
122 case QUIT_COMMAND:
123 exit_required = EINA_TRUE;
124 break;
125 case LIST_COMMAND:
126 break;
127 case PRINT_COMMAND:
128 {
129 char *word = _next_word(l, NULL);
130 const char *value = eina_hash_find(vars_hash, word);
131 if (value)
132 {
133 if (_next_token(l, "->"))
134 {
135 char *res = _function_invoke(l->current, value);
136 printf("Result = %s\n", res);
137 free(res);
138 }
139 else
140 printf("Word: %s Value: %s\n", word, value);
141 }
142 else
143 printf("Unknown variable: %s\n", word);
144
145 break;
146 }
147 default:
148 {
149 char *variable = _next_word(l, NULL);
150 Eina_Bool match = EINA_FALSE;
151 if (variable)
152 {
153 /* variable = value
154 * value is simple */
155 if (_next_token(l, "="))
156 {
157 char *value = _next_word(l, NULL);
158 printf("Variable %s = %s\n", variable, value);
159 if (_next_word(l, NULL))
160 printf("Wrong value after %s\n", value);
161 else
162 eina_hash_set(vars_hash, variable, eina_stringshare_add(value));
163 free(value);
164 match = EINA_TRUE;
165 }
166 /* variable->func = value */
167 else if (_next_token(l, "->"))
168 {
169 char *func = _next_word(l, ".");
170 if (func)
171 {
172 if (_next_token(l, "="))
173 {
174 char *value = _next_word(l, NULL);
175 printf("Set %s on object %s via %s\n", value, variable, func);
176 match = EINA_TRUE;
177 }
178 }
179 }
180 }
181 if (!match)
182 printf("Wrong command: %s\n", l->buffer);
183 break;
184 }
185 }
186
187 _lexer_reset(l);
188 }
189 else
190 {
191 l->buffer[l->buf_end++] = c;
192 l->buffer[l->buf_end] = '\0';
193 }
194 return EINA_TRUE;
195}
36 196
37int 197int
38main() 198main()
@@ -41,6 +201,11 @@ main()
41 int poll = epoll_create(10); 201 int poll = epoll_create(10);
42 struct epoll_event event, *events; 202 struct epoll_event event, *events;
43 203
204 Lexer l;
205 _lexer_reset(&l);
206
207 vars_hash = eina_hash_string_small_new(NULL);
208
44 tcgetattr(STDIN_FILENO, &oldt); 209 tcgetattr(STDIN_FILENO, &oldt);
45 newt = oldt; 210 newt = oldt;
46 newt.c_lflag &= ~(ICANON); 211 newt.c_lflag &= ~(ICANON);
@@ -52,22 +217,23 @@ main()
52 217
53 events = calloc(MAX_EVENTS, sizeof(event)); 218 events = calloc(MAX_EVENTS, sizeof(event));
54 219
55 while(1) 220 while(!exit_required)
56 { 221 {
57 int i, n = epoll_wait(poll, events, MAX_EVENTS, -1); 222 int i, n = epoll_wait(poll, events, MAX_EVENTS, -1);
58 for (i = 0; i < n; i++) 223 for (i = 0; i < n; i++)
59 { 224 {
60 if (events[i].data.fd == STDIN_FILENO) 225 if (events[i].data.fd == STDIN_FILENO)
61 { 226 {
62 char c; 227 char c = '\0';
63 while (read(0, &c, 1)) 228 if (read(0, &c, 1) == 1)
64 { 229 {
65 printf("Character %c received\n", c); 230 _char_consume(&l, c);
66 } 231 }
67 } 232 }
68 } 233 }
69 } 234 }
70 tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 235 tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
236
71 return 0; 237 return 0;
72} 238}
73 239