%{ /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014 Analog Devices, Inc. * Author: Paul Cercueil * * 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 #include 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 #include 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 %token DEVICE %token CHANNEL %token VALUE; %destructor { DEBUG("Freeing token \"%s\"\n", $$); free($$); } %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 \n" "\t\tSet the timeout (in ms) for I/O operations\n" "\tOPEN [CYCLIC]\n" "\t\tOpen the specified device with the given mask of channels\n" "\tCLOSE \n" "\t\tClose the specified device\n" "\tREAD DEBUG|BUFFER|[INPUT|OUTPUT ] []\n" "\t\tRead the value of an attribute\n" "\tWRITE DEBUG|BUFFER|[INPUT|OUTPUT ] [] \n" "\t\tSet the value of an attribute\n" "\tREADBUF \n" "\t\tRead raw data from the specified device\n" "\tWRITEBUF \n" "\t\tWrite raw data to the specified device\n" "\tGETTRIG \n" "\t\tGet the name of the trigger used by the specified device\n" "\tSETTRIG []\n" "\t\tSet the trigger to use for the specified device\n" "\tSET BUFFERS_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; }