1 %{
2 /*
3 * libiio - Library for interfacing industrial I/O (IIO) devices
4 *
5 * Copyright (C) 2014 Analog Devices, Inc.
6 * Author: Paul Cercueil <paul.cercueil@analog.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * */
19
20 #include "ops.h"
21 #include "parser.h"
22
23 #include <errno.h>
24 #include <string.h>
25
26 void yyerror(yyscan_t scanner, const char *msg);
27 %}
28
29 %code requires {
30 #ifndef YY_TYPEDEF_YY_SCANNER_T
31 #define YY_TYPEDEF_YY_SCANNER_T
32 typedef void *yyscan_t;
33 #endif
34
35 #include "../iio-config.h"
36 #include "../debug.h"
37
38 #include <stdbool.h>
39 #include <sys/socket.h>
40
41 int yylex();
42 int yylex_init_extra(void *d, yyscan_t *scanner);
43 int yylex_destroy(yyscan_t yyscanner);
44
45 void * yyget_extra(yyscan_t scanner);
46 ssize_t yy_input(yyscan_t scanner, char *buf, size_t max_size);
47
48 #define ECHO do { \
49 struct parser_pdata *pdata = yyget_extra(yyscanner); \
50 write_all(pdata, yytext, yyleng); \
51 } while (0)
52
53 #define YY_INPUT(buf,result,max_size) do { \
54 ssize_t res = yy_input(yyscanner, buf, max_size); \
55 result = res <= 0 ? YY_NULL : (size_t) res; \
56 } while (0)
57 }
58
59 %define api.pure
60 %lex-param { yyscan_t scanner }
61 %parse-param { yyscan_t scanner }
62
63 %union {
64 char *word;
65 struct iio_device *dev;
66 struct iio_channel *chn;
67 long value;
68 }
69
70 %token SPACE
71 %token END
72
73 %token VERSION
74 %token EXIT
75 %token HELP
76 %token OPEN
77 %token CLOSE
78 %token PRINT
79 %token READ
80 %token READBUF
81 %token WRITEBUF
82 %token WRITE
83 %token SETTRIG
84 %token GETTRIG
85 %token TIMEOUT
86 %token DEBUG_ATTR
87 %token BUFFER_ATTR
88 %token IN_OUT
89 %token CYCLIC
90 %token SET
91 %token BUFFERS_COUNT
92
93 %token <word> WORD
94 %token <dev> DEVICE
95 %token <chn> CHANNEL
96 %token <value> VALUE;
97
98 %destructor { DEBUG("Freeing token \"%s\"\n", $$); free($$); } <word>
99
100 %start Line
101 %%
102
103 Line:
104 END {
105 YYACCEPT;
106 }
107 | EXIT END {
108 struct parser_pdata *pdata = yyget_extra(scanner);
109 pdata->stop = true;
110 YYACCEPT;
111 }
112 | HELP END {
113 struct parser_pdata *pdata = yyget_extra(scanner);
114 output(pdata, "Available commands:\n\n"
115 "\tHELP\n"
116 "\t\tPrint this help message\n"
117 "\tEXIT\n"
118 "\t\tClose the current session\n"
119 "\tPRINT\n"
120 "\t\tDisplays a XML string corresponding to the current IIO context\n"
121 "\tVERSION\n"
122 "\t\tGet the version of libiio in use\n"
123 "\tTIMEOUT <timeout_ms>\n"
124 "\t\tSet the timeout (in ms) for I/O operations\n"
125 "\tOPEN <device> <samples_count> <mask> [CYCLIC]\n"
126 "\t\tOpen the specified device with the given mask of channels\n"
127 "\tCLOSE <device>\n"
128 "\t\tClose the specified device\n"
129 "\tREAD <device> DEBUG|BUFFER|[INPUT|OUTPUT <channel>] [<attribute>]\n"
130 "\t\tRead the value of an attribute\n"
131 "\tWRITE <device> DEBUG|BUFFER|[INPUT|OUTPUT <channel>] [<attribute>] <bytes_count>\n"
132 "\t\tSet the value of an attribute\n"
133 "\tREADBUF <device> <bytes_count>\n"
134 "\t\tRead raw data from the specified device\n"
135 "\tWRITEBUF <device> <bytes_count>\n"
136 "\t\tWrite raw data to the specified device\n"
137 "\tGETTRIG <device>\n"
138 "\t\tGet the name of the trigger used by the specified device\n"
139 "\tSETTRIG <device> [<trigger>]\n"
140 "\t\tSet the trigger to use for the specified device\n"
141 "\tSET <device> BUFFERS_COUNT <count>\n"
142 "\t\tSet the number of kernel buffers for the specified device\n");
143 YYACCEPT;
144 }
145 | VERSION END {
146 struct parser_pdata *pdata = yyget_extra(scanner);
147 char buf[128];
148 snprintf(buf, sizeof(buf), "%u.%u.%-7.7s\n", LIBIIO_VERSION_MAJOR,
149 LIBIIO_VERSION_MINOR, LIBIIO_VERSION_GIT);
150 output(pdata, buf);
151 YYACCEPT;
152 }
153 | PRINT END {
154 struct parser_pdata *pdata = yyget_extra(scanner);
155 const char *xml = iio_context_get_xml(pdata->ctx);
156 if (!pdata->verbose) {
157 char buf[128];
158 sprintf(buf, "%lu\n", (unsigned long) strlen(xml));
159 output(pdata, buf);
160 }
161 output(pdata, xml);
162 output(pdata, "\n");
163 YYACCEPT;
164 }
165 | TIMEOUT SPACE WORD END {
166 char *word = $3;
167 struct parser_pdata *pdata = yyget_extra(scanner);
168 unsigned int timeout = (unsigned int) atoi(word);
169 int ret = set_timeout(pdata, timeout);
170 free(word);
171 if (ret < 0)
172 YYABORT;
173 else
174 YYACCEPT;
175 }
176 | OPEN SPACE DEVICE SPACE WORD SPACE WORD SPACE CYCLIC END {
177 char *nb = $5, *mask = $7;
178 struct parser_pdata *pdata = yyget_extra(scanner);
179 unsigned long samples_count = atol(nb);
180 int ret = open_dev(pdata, $3, samples_count, mask, true);
181 free(nb);
182 free(mask);
183 if (ret < 0)
184 YYABORT;
185 else
186 YYACCEPT;
187 }
188 | OPEN SPACE DEVICE SPACE WORD SPACE WORD END {
189 char *nb = $5, *mask = $7;
190 struct parser_pdata *pdata = yyget_extra(scanner);
191 unsigned long samples_count = atol(nb);
192 int ret = open_dev(pdata, $3, samples_count, mask, false);
193 free(nb);
194 free(mask);
195 if (ret < 0)
196 YYABORT;
197 else
198 YYACCEPT;
199 }
200 | CLOSE SPACE DEVICE END {
201 struct parser_pdata *pdata = yyget_extra(scanner);
202 int ret = close_dev(pdata, $3);
203 if (ret < 0)
204 YYABORT;
205 else
206 YYACCEPT;
207 }
208 | READ SPACE DEVICE END {
209 struct parser_pdata *pdata = yyget_extra(scanner);
210 if (read_dev_attr(pdata, $3, NULL, IIO_ATTR_TYPE_DEVICE) < 0)
211 YYABORT;
212 else
213 YYACCEPT;
214 }
215 | READ SPACE DEVICE SPACE WORD END {
216 char *attr = $5;
217 struct parser_pdata *pdata = yyget_extra(scanner);
218 ssize_t ret = read_dev_attr(pdata, $3, attr, IIO_ATTR_TYPE_DEVICE);
219 free(attr);
220 if (ret < 0)
221 YYABORT;
222 else
223 YYACCEPT;
224 }
225 | READ SPACE DEVICE SPACE DEBUG_ATTR END {
226 struct parser_pdata *pdata = yyget_extra(scanner);
227 if (read_dev_attr(pdata, $3, NULL, IIO_ATTR_TYPE_DEBUG) < 0)
228 YYABORT;
229 else
230 YYACCEPT;
231 }
232 | READ SPACE DEVICE SPACE DEBUG_ATTR SPACE WORD END {
233 char *attr = $7;
234 struct parser_pdata *pdata = yyget_extra(scanner);
235 ssize_t ret = read_dev_attr(pdata, $3, attr, IIO_ATTR_TYPE_DEBUG);
236 free(attr);
237 if (ret < 0)
238 YYABORT;
239 else
240 YYACCEPT;
241 }
242 | READ SPACE DEVICE SPACE BUFFER_ATTR END {
243 struct parser_pdata *pdata = yyget_extra(scanner);
244 if (read_dev_attr(pdata, $3, NULL, IIO_ATTR_TYPE_BUFFER) < 0)
245 YYABORT;
246 else
247 YYACCEPT;
248 }
249 | READ SPACE DEVICE SPACE BUFFER_ATTR SPACE WORD END {
250 char *attr = $7;
251 struct parser_pdata *pdata = yyget_extra(scanner);
252 ssize_t ret = read_dev_attr(pdata, $3, attr, IIO_ATTR_TYPE_BUFFER);
253 free(attr);
254 if (ret < 0)
255 YYABORT;
256 else
257 YYACCEPT;
258 }
259 | READ SPACE DEVICE SPACE IN_OUT SPACE CHANNEL END {
260 struct parser_pdata *pdata = yyget_extra(scanner);
261 if (read_chn_attr(pdata, $7, NULL) < 0)
262 YYABORT;
263 else
264 YYACCEPT;
265 }
266 | READ SPACE DEVICE SPACE IN_OUT SPACE CHANNEL SPACE WORD END {
267 char *attr = $9;
268 struct parser_pdata *pdata = yyget_extra(scanner);
269 ssize_t ret = read_chn_attr(pdata, $7, attr);
270 free(attr);
271 if (ret < 0)
272 YYABORT;
273 else
274 YYACCEPT;
275 }
276 | READBUF SPACE DEVICE SPACE WORD END {
277 char *len = $5;
278 unsigned long nb = atol(len);
279 struct parser_pdata *pdata = yyget_extra(scanner);
280 ssize_t ret = rw_dev(pdata, $3, nb, false);
281 free(len);
282 if (ret < 0)
283 YYABORT;
284 else
285 YYACCEPT;
286 }
287 | WRITEBUF SPACE DEVICE SPACE WORD END {
288 char *len = $5;
289 unsigned long nb = atol(len);
290 struct parser_pdata *pdata = yyget_extra(scanner);
291 ssize_t ret = rw_dev(pdata, $3, nb, true);
292
293 /* Discard additional data */
294 yyclearin;
295
296 free(len);
297 if (ret < 0)
298 YYABORT;
299 else
300 YYACCEPT;
301 }
302 | WRITE SPACE DEVICE SPACE WORD END {
303 char *len = $5;
304 unsigned long nb = atol(len);
305 struct parser_pdata *pdata = yyget_extra(scanner);
306 ssize_t ret = write_dev_attr(pdata, $3, NULL, nb, IIO_ATTR_TYPE_DEVICE);
307 free(len);
308 if (ret < 0)
309 YYABORT;
310 else
311 YYACCEPT;
312 }
313 | WRITE SPACE DEVICE SPACE WORD SPACE WORD END {
314 char *attr = $5, *len = $7;
315 unsigned long nb = atol(len);
316 struct parser_pdata *pdata = yyget_extra(scanner);
317 ssize_t ret = write_dev_attr(pdata, $3, attr, nb, IIO_ATTR_TYPE_DEVICE);
318 free(attr);
319 free(len);
320 if (ret < 0)
321 YYABORT;
322 else
323 YYACCEPT;
324 }
325 | WRITE SPACE DEVICE SPACE DEBUG_ATTR SPACE WORD END {
326 char *len = $7;
327 unsigned long nb = atol(len);
328 struct parser_pdata *pdata = yyget_extra(scanner);
329 ssize_t ret = write_dev_attr(pdata, $3, NULL, nb, IIO_ATTR_TYPE_DEBUG);
330 free(len);
331 if (ret < 0)
332 YYABORT;
333 else
334 YYACCEPT;
335 }
336 | WRITE SPACE DEVICE SPACE DEBUG_ATTR SPACE WORD SPACE WORD END {
337 char *attr = $7, *len = $9;
338 unsigned long nb = atol(len);
339 struct parser_pdata *pdata = yyget_extra(scanner);
340 ssize_t ret = write_dev_attr(pdata, $3, attr, nb, IIO_ATTR_TYPE_DEBUG);
341 free(attr);
342 free(len);
343 if (ret < 0)
344 YYABORT;
345 else
346 YYACCEPT;
347 }
348 | WRITE SPACE DEVICE SPACE BUFFER_ATTR SPACE WORD END {
349 char *len = $7;
350 unsigned long nb = atol(len);
351 struct parser_pdata *pdata = yyget_extra(scanner);
352 ssize_t ret = write_dev_attr(pdata, $3, NULL, nb, IIO_ATTR_TYPE_BUFFER);
353 free(len);
354 if (ret < 0)
355 YYABORT;
356 else
357 YYACCEPT;
358 }
359 | WRITE SPACE DEVICE SPACE BUFFER_ATTR SPACE WORD SPACE WORD END {
360 char *attr = $7, *len = $9;
361 unsigned long nb = atol(len);
362 struct parser_pdata *pdata = yyget_extra(scanner);
363 ssize_t ret = write_dev_attr(pdata, $3, attr, nb, IIO_ATTR_TYPE_BUFFER);
364 free(attr);
365 free(len);
366 if (ret < 0)
367 YYABORT;
368 else
369 YYACCEPT;
370 }
371 | WRITE SPACE DEVICE SPACE IN_OUT SPACE CHANNEL SPACE WORD END {
372 char *len = $9;
373 unsigned long nb = atol(len);
374 struct parser_pdata *pdata = yyget_extra(scanner);
375 ssize_t ret = write_chn_attr(pdata, $7, NULL, nb);
376 free(len);
377 if (ret < 0)
378 YYABORT;
379 else
380 YYACCEPT;
381 }
382 | WRITE SPACE DEVICE SPACE IN_OUT SPACE CHANNEL SPACE WORD SPACE WORD END {
383 char *attr = $9, *len = $11;
384 unsigned long nb = atol(len);
385 struct parser_pdata *pdata = yyget_extra(scanner);
386 ssize_t ret = write_chn_attr(pdata, $7, attr, nb);
387 free(attr);
388 free(len);
389 if (ret < 0)
390 YYABORT;
391 else
392 YYACCEPT;
393 }
394 | SETTRIG SPACE DEVICE SPACE WORD END {
395 char *trig = $5;
396 struct parser_pdata *pdata = yyget_extra(scanner);
397 ssize_t ret = set_trigger(pdata, $3, trig);
398 free(trig);
399 if (ret < 0)
400 YYABORT;
401 else
402 YYACCEPT;
403 }
404 | SETTRIG SPACE DEVICE END {
405 struct parser_pdata *pdata = yyget_extra(scanner);
406 if (set_trigger(pdata, $3, NULL) < 0)
407 YYABORT;
408 else
409 YYACCEPT;
410 }
411 | GETTRIG SPACE DEVICE END {
412 struct parser_pdata *pdata = yyget_extra(scanner);
413 if (get_trigger(pdata, $3) < 0)
414 YYABORT;
415 else
416 YYACCEPT;
417 }
418 | SET SPACE DEVICE SPACE BUFFERS_COUNT SPACE VALUE END {
419 struct parser_pdata *pdata = yyget_extra(scanner);
420 if (set_buffers_count(pdata, $3, $7) < 0)
421 YYABORT;
422 else
423 YYACCEPT;
424 }
425 | error END {
426 yyclearin;
427 yyerrok;
428 YYACCEPT;
429 }
430 ;
431
432 %%
433
434 void yyerror(yyscan_t scanner, const char *msg)
435 {
436 struct parser_pdata *pdata = yyget_extra(scanner);
437 if (pdata->verbose) {
438 output(pdata, "ERROR: ");
439 output(pdata, msg);
440 output(pdata, "\n");
441 } else {
442 char buf[128];
443 sprintf(buf, "%i\n", -EINVAL);
444 output(pdata, buf);
445 }
446 }
447
yy_input(yyscan_t scanner,char * buf,size_t max_size)448 ssize_t yy_input(yyscan_t scanner, char *buf, size_t max_size)
449 {
450 struct parser_pdata *pdata = yyget_extra(scanner);
451 ssize_t ret;
452
453 ret = read_line(pdata, buf, max_size);
454 if (ret < 0)
455 return ret;
456 if (ret == 0)
457 return -EIO;
458
459 if ((size_t) ret == max_size)
460 buf[max_size - 1] = '\0';
461
462 return ret;
463 }
464