| %{ |
| /* |
| * libiio - Library for interfacing industrial I/O (IIO) devices |
| * |
| * Copyright (C) 2014 Analog Devices, Inc. |
| * Author: Paul Cercueil <paul.cercueil@analog.com> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * */ |
| |
| #include "ops.h" |
| #include "parser.h" |
| |
| #include <errno.h> |
| #include <string.h> |
| |
| void yyerror(yyscan_t scanner, const char *msg); |
| %} |
| |
| %code requires { |
| #ifndef YY_TYPEDEF_YY_SCANNER_T |
| #define YY_TYPEDEF_YY_SCANNER_T |
| typedef void *yyscan_t; |
| #endif |
| |
| #include "../iio-config.h" |
| #include "../debug.h" |
| |
| #include <stdbool.h> |
| #include <sys/socket.h> |
| |
| int yylex(); |
| int yylex_init_extra(void *d, yyscan_t *scanner); |
| int yylex_destroy(yyscan_t yyscanner); |
| |
| void * yyget_extra(yyscan_t scanner); |
| ssize_t yy_input(yyscan_t scanner, char *buf, size_t max_size); |
| |
| #define ECHO do { \ |
| struct parser_pdata *pdata = yyget_extra(yyscanner); \ |
| write_all(pdata, yytext, yyleng); \ |
| } while (0) |
| |
| #define YY_INPUT(buf,result,max_size) do { \ |
| ssize_t res = yy_input(yyscanner, buf, max_size); \ |
| result = res <= 0 ? YY_NULL : (size_t) res; \ |
| } while (0) |
| } |
| |
| %define api.pure |
| %lex-param { yyscan_t scanner } |
| %parse-param { yyscan_t scanner } |
| |
| %union { |
| char *word; |
| struct iio_device *dev; |
| struct iio_channel *chn; |
| long value; |
| } |
| |
| %token SPACE |
| %token END |
| |
| %token VERSION |
| %token EXIT |
| %token HELP |
| %token OPEN |
| %token CLOSE |
| %token PRINT |
| %token READ |
| %token READBUF |
| %token WRITEBUF |
| %token WRITE |
| %token SETTRIG |
| %token GETTRIG |
| %token TIMEOUT |
| %token DEBUG_ATTR |
| %token BUFFER_ATTR |
| %token IN_OUT |
| %token CYCLIC |
| %token SET |
| %token BUFFERS_COUNT |
| |
| %token <word> WORD |
| %token <dev> DEVICE |
| %token <chn> CHANNEL |
| %token <value> VALUE; |
| |
| %destructor { DEBUG("Freeing token \"%s\"\n", $$); free($$); } <word> |
| |
| %start Line |
| %% |
| |
| Line: |
| END { |
| YYACCEPT; |
| } |
| | EXIT END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| pdata->stop = true; |
| YYACCEPT; |
| } |
| | HELP END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| output(pdata, "Available commands:\n\n" |
| "\tHELP\n" |
| "\t\tPrint this help message\n" |
| "\tEXIT\n" |
| "\t\tClose the current session\n" |
| "\tPRINT\n" |
| "\t\tDisplays a XML string corresponding to the current IIO context\n" |
| "\tVERSION\n" |
| "\t\tGet the version of libiio in use\n" |
| "\tTIMEOUT <timeout_ms>\n" |
| "\t\tSet the timeout (in ms) for I/O operations\n" |
| "\tOPEN <device> <samples_count> <mask> [CYCLIC]\n" |
| "\t\tOpen the specified device with the given mask of channels\n" |
| "\tCLOSE <device>\n" |
| "\t\tClose the specified device\n" |
| "\tREAD <device> DEBUG|BUFFER|[INPUT|OUTPUT <channel>] [<attribute>]\n" |
| "\t\tRead the value of an attribute\n" |
| "\tWRITE <device> DEBUG|BUFFER|[INPUT|OUTPUT <channel>] [<attribute>] <bytes_count>\n" |
| "\t\tSet the value of an attribute\n" |
| "\tREADBUF <device> <bytes_count>\n" |
| "\t\tRead raw data from the specified device\n" |
| "\tWRITEBUF <device> <bytes_count>\n" |
| "\t\tWrite raw data to the specified device\n" |
| "\tGETTRIG <device>\n" |
| "\t\tGet the name of the trigger used by the specified device\n" |
| "\tSETTRIG <device> [<trigger>]\n" |
| "\t\tSet the trigger to use for the specified device\n" |
| "\tSET <device> BUFFERS_COUNT <count>\n" |
| "\t\tSet the number of kernel buffers for the specified device\n"); |
| YYACCEPT; |
| } |
| | VERSION END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| char buf[128]; |
| snprintf(buf, sizeof(buf), "%u.%u.%-7.7s\n", LIBIIO_VERSION_MAJOR, |
| LIBIIO_VERSION_MINOR, LIBIIO_VERSION_GIT); |
| output(pdata, buf); |
| YYACCEPT; |
| } |
| | PRINT END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| const char *xml = iio_context_get_xml(pdata->ctx); |
| if (!pdata->verbose) { |
| char buf[128]; |
| sprintf(buf, "%lu\n", (unsigned long) strlen(xml)); |
| output(pdata, buf); |
| } |
| output(pdata, xml); |
| output(pdata, "\n"); |
| YYACCEPT; |
| } |
| | TIMEOUT SPACE WORD END { |
| char *word = $3; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| unsigned int timeout = (unsigned int) atoi(word); |
| int ret = set_timeout(pdata, timeout); |
| free(word); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | OPEN SPACE DEVICE SPACE WORD SPACE WORD SPACE CYCLIC END { |
| char *nb = $5, *mask = $7; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| unsigned long samples_count = atol(nb); |
| int ret = open_dev(pdata, $3, samples_count, mask, true); |
| free(nb); |
| free(mask); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | OPEN SPACE DEVICE SPACE WORD SPACE WORD END { |
| char *nb = $5, *mask = $7; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| unsigned long samples_count = atol(nb); |
| int ret = open_dev(pdata, $3, samples_count, mask, false); |
| free(nb); |
| free(mask); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | CLOSE SPACE DEVICE END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| int ret = close_dev(pdata, $3); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (read_dev_attr(pdata, $3, NULL, IIO_ATTR_TYPE_DEVICE) < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE SPACE WORD END { |
| char *attr = $5; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = read_dev_attr(pdata, $3, attr, IIO_ATTR_TYPE_DEVICE); |
| free(attr); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE SPACE DEBUG_ATTR END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (read_dev_attr(pdata, $3, NULL, IIO_ATTR_TYPE_DEBUG) < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE SPACE DEBUG_ATTR SPACE WORD END { |
| char *attr = $7; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = read_dev_attr(pdata, $3, attr, IIO_ATTR_TYPE_DEBUG); |
| free(attr); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE SPACE BUFFER_ATTR END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (read_dev_attr(pdata, $3, NULL, IIO_ATTR_TYPE_BUFFER) < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE SPACE BUFFER_ATTR SPACE WORD END { |
| char *attr = $7; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = read_dev_attr(pdata, $3, attr, IIO_ATTR_TYPE_BUFFER); |
| free(attr); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE SPACE IN_OUT SPACE CHANNEL END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (read_chn_attr(pdata, $7, NULL) < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READ SPACE DEVICE SPACE IN_OUT SPACE CHANNEL SPACE WORD END { |
| char *attr = $9; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = read_chn_attr(pdata, $7, attr); |
| free(attr); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | READBUF SPACE DEVICE SPACE WORD END { |
| char *len = $5; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = rw_dev(pdata, $3, nb, false); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITEBUF SPACE DEVICE SPACE WORD END { |
| char *len = $5; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = rw_dev(pdata, $3, nb, true); |
| |
| /* Discard additional data */ |
| yyclearin; |
| |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE WORD END { |
| char *len = $5; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_dev_attr(pdata, $3, NULL, nb, IIO_ATTR_TYPE_DEVICE); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE WORD SPACE WORD END { |
| char *attr = $5, *len = $7; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_dev_attr(pdata, $3, attr, nb, IIO_ATTR_TYPE_DEVICE); |
| free(attr); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE DEBUG_ATTR SPACE WORD END { |
| char *len = $7; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_dev_attr(pdata, $3, NULL, nb, IIO_ATTR_TYPE_DEBUG); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE DEBUG_ATTR SPACE WORD SPACE WORD END { |
| char *attr = $7, *len = $9; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_dev_attr(pdata, $3, attr, nb, IIO_ATTR_TYPE_DEBUG); |
| free(attr); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE BUFFER_ATTR SPACE WORD END { |
| char *len = $7; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_dev_attr(pdata, $3, NULL, nb, IIO_ATTR_TYPE_BUFFER); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE BUFFER_ATTR SPACE WORD SPACE WORD END { |
| char *attr = $7, *len = $9; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_dev_attr(pdata, $3, attr, nb, IIO_ATTR_TYPE_BUFFER); |
| free(attr); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE IN_OUT SPACE CHANNEL SPACE WORD END { |
| char *len = $9; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_chn_attr(pdata, $7, NULL, nb); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | WRITE SPACE DEVICE SPACE IN_OUT SPACE CHANNEL SPACE WORD SPACE WORD END { |
| char *attr = $9, *len = $11; |
| unsigned long nb = atol(len); |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = write_chn_attr(pdata, $7, attr, nb); |
| free(attr); |
| free(len); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | SETTRIG SPACE DEVICE SPACE WORD END { |
| char *trig = $5; |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret = set_trigger(pdata, $3, trig); |
| free(trig); |
| if (ret < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | SETTRIG SPACE DEVICE END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (set_trigger(pdata, $3, NULL) < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | GETTRIG SPACE DEVICE END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (get_trigger(pdata, $3) < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | SET SPACE DEVICE SPACE BUFFERS_COUNT SPACE VALUE END { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (set_buffers_count(pdata, $3, $7) < 0) |
| YYABORT; |
| else |
| YYACCEPT; |
| } |
| | error END { |
| yyclearin; |
| yyerrok; |
| YYACCEPT; |
| } |
| ; |
| |
| %% |
| |
| void yyerror(yyscan_t scanner, const char *msg) |
| { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| if (pdata->verbose) { |
| output(pdata, "ERROR: "); |
| output(pdata, msg); |
| output(pdata, "\n"); |
| } else { |
| char buf[128]; |
| sprintf(buf, "%i\n", -EINVAL); |
| output(pdata, buf); |
| } |
| } |
| |
| ssize_t yy_input(yyscan_t scanner, char *buf, size_t max_size) |
| { |
| struct parser_pdata *pdata = yyget_extra(scanner); |
| ssize_t ret; |
| |
| ret = read_line(pdata, buf, max_size); |
| if (ret < 0) |
| return ret; |
| if (ret == 0) |
| return -EIO; |
| |
| if ((size_t) ret == max_size) |
| buf[max_size - 1] = '\0'; |
| |
| return ret; |
| } |