| %{ |
| /* |
| * 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; |
| } |
| |
| |
| |