• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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