blob: e4d0507a01a3f153c6531b70b3d13fac88b91fa8 [file] [log] [blame]
%{
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "servercmd.h"
static int acc_byte = 0;
static int acc_len = 0;
%}
%option noyywrap
%option nounput
/* We need reentratnt scanner for multiple connections */
%option reentrant
/* %option c++ */
%x str
DIGIT [0-9]
HEXDIGIT [0-9A-Fa-f]
ID [A-Za-z_!][A-Za-z_!0-9]*
%%
"get_interfaces" {
if(cb_cmd(yyextra, CMD_GET_INTERFACES))
yyterminate();
}
"open_interface" {
if(cb_cmd(yyextra, CMD_OPEN_INTERFACE))
yyterminate();
}
"close_interface" {
if(cb_cmd(yyextra, CMD_CLOSE_INTERFACE))
yyterminate();
}
"r" {
if(cb_cmd(yyextra, CMD_R))
yyterminate();
}
"rb" {
if(cb_cmd(yyextra, CMD_RB))
yyterminate();
}
"w" {
if(cb_cmd(yyextra, CMD_W))
yyterminate();
}
"wb" {
if(cb_cmd(yyextra, CMD_WB))
yyterminate();
}
"alloc_pmc" {
if(cb_cmd(yyextra, CMD_ALLOC_PMC))
yyterminate();
}
"read_pmc" {
if(cb_cmd(yyextra, CMD_READ_PMC))
yyterminate();
}
"read_pmc_file" {
if(cb_cmd(yyextra, CMD_READ_PMC_FILE))
yyterminate();
}
"interface_reset" {
if(cb_cmd(yyextra, CMD_INTERFACE_RESET))
yyterminate();
}
"sw_reset" {
if(cb_cmd(yyextra, CMD_SW_RESET))
yyterminate();
}
"exit" {
if(cb_cmd(yyextra, CMD_EXIT))
yyterminate();
}
"set_host_alias" {
if(cb_cmd(yyextra, CMD_SET_HOST_ALIAS))
yyterminate();
}
{DIGIT}+ {
/* A decimal number represents the address/value */
if(cb_number(yyextra, yytext))
yyterminate();
}
{ID} {
/* The protocol doesn't separate between interface id and command */
if(cb_id(yyextra, yytext))
yyterminate();
}
\" {
/* Start of string */
BEGIN(str);
acc_byte = 0;
acc_len = 0;
}
<str>\" {
/* End of string */
if(acc_len > 0) {
if(cb_hexbyte(yyextra, acc_byte))
yyterminate();
}
/* Callback for end of hex string */
if(cb_endhex(yyextra))
yyterminate();
BEGIN(INITIAL);
}
<str>{HEXDIGIT} {
/* We get hex bytes in the string */
if(acc_len == 10) {
cb_error(yyextra, ERR_BAD_HEX_VALUE, "");
yyterminate();
}else if(acc_len <= 1){
acc_len++;
// do nothing on the 0x
}
else {
acc_len++;
acc_byte = acc_byte * 16 + hexdigit(yytext[0]);
}
}
<str>[ \t] {
/* Hex bytes separated by spaces */
if(acc_len > 0) {
if(cb_hexbyte(yyextra, acc_byte))
yyterminate();
acc_len = 0;
acc_byte = 0;
}
}
<str><<EOF>> {
/* Check the end of string with unterminated quote */
cb_error(yyextra, ERR_UNTERMINATED_STRING, "");
yyterminate();
}
<str>x {
/* if we ancounter 0x, remove the x and continue */
if(acc_len != 1){
cb_error(yyextra, ERR_BAD_HEX_VALUE, "");
}
acc_len++;
}
<str>. {
/* Anything except the hex bytes is not allowed in the string parameter */
cb_error(yyextra, ERR_BAD_HEX_VALUE, "");
yyterminate();
}
[ \t\r\n]+ {
/* Whitespace */
if(cb_separator(yyextra))
yyterminate();
}
. {
cb_error(yyextra, ERR_BAD_TOKEN, yytext);
yyterminate();
}
%%
/*
Parses the input line
*/
int parse_line(const char *line, servercmd_t *s)
{
yyscan_t scanner;
YY_BUFFER_STATE bs;
cb_parser_start(s);
yylex_init(&scanner);
if (!scanner)
{
return 1;
}
yyset_extra(s, scanner);
bs = yy_scan_string(line, scanner);
yylex(scanner);
yy_delete_buffer(bs, scanner);
yylex_destroy(scanner);
cb_parser_end(s);
return s->error;
}