diff options
Diffstat (limited to 'src/cli_def.l')
-rw-r--r-- | src/cli_def.l | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/src/cli_def.l b/src/cli_def.l new file mode 100644 index 0000000..41994d6 --- /dev/null +++ b/src/cli_def.l @@ -0,0 +1,424 @@ +%{ +#include "cli_val.h" +#include "cli_parse.h" +FILE *yy_cli_def_in; +static void make_def_value(vtw_type_e type); +static int cli_last_nl_returned=0; +#define STR_DELTA 2 +%} +%x str +%option noyywrap +%option nounput +%option never-interactive + +/* + * Regular expressions of IP and MAC addresses, URLs, etc. + */ + +/* + * IPv4 address representation. + */ +RE_IPV4_BYTE 25[0-5]|2[0-4][0-9]|[01][0-9][0-9]|([0-9]{1,2}) +RE_IPV4 {RE_IPV4_BYTE}(\.{RE_IPV4_BYTE}){3} +RE_IPV4_PREFIXLEN (3[012]|[12][0-9]|[0-9]) +RE_IPV4NET {RE_IPV4}"/"{RE_IPV4_PREFIXLEN} + +/* + * IPv6 address representation in Augmented Backus-Naur Form (ABNF) + * as defined in RFC-2234. + * IPv6 address representation taken from RFC-3986: + * + * IPv6address = 6( h16 ":" ) ls32 + * / "::" 5( h16 ":" ) ls32 + * / [ h16 ] "::" 4( h16 ":" ) ls32 + * / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + * / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + * / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + * / [ *4( h16 ":" ) h16 ] "::" ls32 + * / [ *5( h16 ":" ) h16 ] "::" h16 + * / [ *6( h16 ":" ) h16 ] "::" + * + * h16 = 1*4HEXDIG + * ls32 = ( h16 ":" h16 ) / IPv4address + * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + * dec-octet = DIGIT ; 0-9 + * / %x31-39 DIGIT ; 10-99 + * / "1" 2DIGIT ; 100-199 + * / "2" %x30-34 DIGIT ; 200-249 + * / "25" %x30-35 ; 250-255 + */ + +RE_H16 [a-fA-F0-9]{1,4} +RE_H16_COLON {RE_H16}":" +RE_LS32 (({RE_H16}":"{RE_H16})|{RE_IPV4}) +RE_IPV6_P1 {RE_H16_COLON}{6}{RE_LS32} +RE_IPV6_P2 "::"{RE_H16_COLON}{5}{RE_LS32} +RE_IPV6_P3 ({RE_H16})?"::"{RE_H16_COLON}{4}{RE_LS32} +RE_IPV6_P4 ({RE_H16_COLON}{0,1}{RE_H16})?"::"{RE_H16_COLON}{3}{RE_LS32} +RE_IPV6_P5 ({RE_H16_COLON}{0,2}{RE_H16})?"::"{RE_H16_COLON}{2}{RE_LS32} +RE_IPV6_P6 ({RE_H16_COLON}{0,3}{RE_H16})?"::"{RE_H16_COLON}{1}{RE_LS32} +RE_IPV6_P7 ({RE_H16_COLON}{0,4}{RE_H16})?"::"{RE_LS32} +RE_IPV6_P8 ({RE_H16_COLON}{0,5}{RE_H16})?"::"{RE_H16} +RE_IPV6_P9 ({RE_H16_COLON}{0,6}{RE_H16})?"::" +RE_IPV6 {RE_IPV6_P1}|{RE_IPV6_P2}|{RE_IPV6_P3}|{RE_IPV6_P4}|{RE_IPV6_P5}|{RE_IPV6_P6}|{RE_IPV6_P7}|{RE_IPV6_P8}|{RE_IPV6_P9} +RE_IPV6_PREFIXLEN 12[0-8]|1[01][0-9]|[0-9][0-9]? +RE_IPV6NET {RE_IPV6}"/"{RE_IPV6_PREFIXLEN} + +/* + * Ethernet MAC address representation. + */ +RE_MACADDR [a-fA-F0-9]{1,2}(:[a-fA-F0-9]{1,2}){5} + +/* + * URL-related regular expressions. + * + * Implementation is based on the BNF-like specification from: + * - RFC-1738: HTTP, FTP, FILE + * - RFC-3617: TFTP + * - RFC-3986: update of RFC-1738 + */ +RE_URL {RE_URL_FILE}|{RE_URL_FTP}|{RE_URL_HTTP}|{RE_URL_TFTP} + +/* + * URL schemeparts for IP based protocols. + * Representation taken from RFC-1738, and some of it is updated by RFC-3986. + * + * login = [ user [ ":" password ] "@" ] hostport + * hostport = host [ ":" port ] + * host = hostname | hostnumber + * hostname = *[ domainlabel "." ] toplabel + * domainlabel = alphadigit | alphadigit *[ alphadigit | "-" ] alphadigit + * toplabel = alpha | alpha *[ alphadigit | "-" ] alphadigit + * alphadigit = alpha | digit + * hostnumber = digits "." digits "." digits "." digits + * port = digits + * user = *[ uchar | ";" | "?" | "&" | "=" ] + * password = *[ uchar | ";" | "?" | "&" | "=" ] + */ +RE_URL_LOGIN ({RE_URL_USER}(":"{RE_URL_PASSWORD})?"@")?{RE_URL_HOSTPORT} +RE_URL_HOSTPORT {RE_URL_HOST}(":"{RE_URL_PORT})? +RE_URL_HOST {RE_URL_HOSTNAME}|{RE_IPV4}|{RE_URL_IP_LITERAL} +RE_URL_IP_LITERAL "["({RE_IPV6}|{RE_URL_IPV_FUTURE})"]" +RE_URL_IPV_FUTURE "v"({RE_URL_HEXDIG})+"."({RE_URL_UNRESERVED}|{RE_URL_SUBDELIMS}|":")+ +RE_URL_HOSTNAME ({RE_URL_DOMAINLABEL}".")*{RE_URL_TOPLABEL} +RE_URL_DOMAINLABEL {RE_URL_ALPHADIGIT}|{RE_URL_ALPHADIGIT}({RE_URL_ALPHADIGIT}|"-")*{RE_URL_ALPHADIGIT} +RE_URL_TOPLABEL {RE_URL_ALPHA}|{RE_URL_ALPHA}({RE_URL_ALPHADIGIT}|"-")*{RE_URL_ALPHADIGIT} +RE_URL_ALPHADIGIT {RE_URL_ALPHA}|{RE_URL_DIGIT} +RE_URL_HOSTNUMBER {RE_URL_DIGITS}"."{RE_URL_DIGITS}"."{RE_URL_DIGITS}"."{RE_URL_DIGITS} +RE_URL_PORT {RE_URL_DIGITS} +RE_URL_USER ({RE_URL_UCHAR}|";"|"?"|"&"|"=")* +RE_URL_PASSWORD ({RE_URL_UCHAR}|";"|"?"|"&"|"=")* + +/* + * FILE URL regular expression. + * Representation taken from RFC-1738. + * + * fileurl = "file://" [ host | "localhost" ] "/" fpath + */ +RE_URL_FILE "file://"({RE_URL_HOST}|"localhost")?"/"{RE_URL_FPATH} + +/* + * FTP URL regular expression. + * Representation taken from RFC-1738. + * + * ftpurl = "ftp://" login [ "/" fpath [ ";type=" ftptype ] ] + * fpath = fsegment *[ "/" fsegment ] + * fsegment = *[ uchar | "?" | ":" | "@" | "&" | "=" ] + * ftptype = "A" | "I" | "D" | "a" | "i" | "d" + */ +RE_URL_FTP "ftp://"{RE_URL_LOGIN}("/"{RE_URL_FPATH}(";type="{RE_URL_FTPTYPE})?)? +RE_URL_FPATH {RE_URL_FSEGMENT}("/"{RE_URL_FSEGMENT})* +RE_URL_FSEGMENT ({RE_URL_UCHAR}|"?"|":"|"@"|"&"|"=")* +RE_URL_FTPTYPE "A"|"I"|"D"|"a"|"i"|"d" + +/* + * HTTP URL regular expression. + * Representation taken from RFC-1738. + * + * httpurl = "http://" hostport [ "/" hpath [ "?" search ] ] + * hpath = hsegment *[ "/" hsegment ] + * hsegment = *[ uchar | ";" | ":" | "@" | "&" | "=" ] + * search = *[ uchar | ";" | ":" | "@" | "&" | "=" ] + */ +RE_URL_HTTP "http://"{RE_URL_HOSTPORT}("/"{RE_URL_HPATH}("?"{RE_URL_SEARCH})?)? +RE_URL_HPATH {RE_URL_HSEGMENT}("/"{RE_URL_HSEGMENT})* +RE_URL_HSEGMENT ({RE_URL_UCHAR}|";"|":"|"@"|"&"|"=")* +RE_URL_SEARCH ({RE_URL_UCHAR}|";"|":"|"@"|"&"|"=")* + +/* + * TFTP URL regular expression. + * Representation taken from RFC-3617. + * + * tftpURI = "tftp://" host "/" file [ mode ] + * mode = ";" "mode=" ( "netascii" / "octet" ) + * file = *( unreserved / escaped ) + * host = <as specified by RFC 2732 [3]> + * unreserved = <as specified in RFC 2396 [4]> + * escaped = <as specified in RFC 2396> + */ +RE_URL_TFTP "tftp://"{RE_URL_HOST}"/"{RE_URL_TFTP_FILE}({RE_URL_TFTP_MODE})? +RE_URL_TFTP_MODE ";""mode="("netascii"|"octet") +RE_URL_TFTP_FILE ({RE_URL_UNRESERVED}|{RE_URL_ESCAPE})* + +/* + * URL-related miscellaneous definitions. + * Representation taken from RFC-1738 and from RFC-3986. + * + * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | + * "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | + * "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | + * "y" | "z" + * hialpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | + * "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | + * "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" + * alpha = lowalpha | hialpha + * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | + * "8" | "9" + * safe = "$" | "-" | "_" | "." | "+" + * extra = "!" | "*" | "'" | "(" | ")" | "," + * national = "{" | "}" | "|" | "\" | "^" | "~" | "[" | "]" | "`" + * punctuation = "<" | ">" | "#" | "%" | <"> + * + * + * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" + * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + * "a" | "b" | "c" | "d" | "e" | "f" + * escape = "%" hex hex + * + * unreserved = alpha | digit | safe | extra + * uchar = unreserved | escape + * xchar = unreserved | reserved | escape + * digits = 1*digit + * + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ +RE_URL_LOWALPHA [a-z] +RE_URL_HIALPHA [A-Z] +RE_URL_ALPHA {RE_URL_LOWALPHA}|{RE_URL_HIALPHA} +RE_URL_DIGIT [0-9] +RE_URL_SAFE "$"|"-"|"_"|"."|"+" +RE_URL_EXTRA "!"|"*"|"'"|"("|")"|"," +RE_URL_NATIONAL "{"|"}"|"|"|"\"|"^"|"~"|"["|"]"|"`" +RE_URL_PUNCTUATION "<"|">"|"#"|"%"|<"> +RE_URL_RESERVED ";"|"/"|"?"|":"|"@"|"&"|"=" +RE_URL_HEXDIG {RE_URL_DIGIT}|[A-F]|[a-f] +RE_URL_ESCAPE "%"{RE_URL_HEXDIG}{RE_URL_HEXDIG} +RE_URL_UNRESERVED {RE_URL_ALPHA}|{RE_URL_DIGIT}|{RE_URL_SAFE}|{RE_URL_EXTRA} +RE_URL_UCHAR {RE_URL_UNRESERVED}|{RE_URL_ESCAPE} +RE_URL_XCHAR {RE_URL_UNRESERVED}|{RE_URL_RESERVED}|{RE_URL_ESCAPE} +RE_URL_DIGITS {RE_URL_DIGIT}{1,} +RE_URL_SUBDELIMS "!"|"$"|"&"|"'"|"("|")"|"*"|"+"|","|";"|"=" + + +%% + char *string_buf=NULL; + char *string_buf_ptr=NULL; + int string_len=0, string_buf_len=0; + char str_delim=0; + +#[^\n]*(\\[ \t]*\n[^\n]*)*\n { /* comment */ } +\n {yy_cli_def_lineno++;return EOL;} +<<EOF>> { if(!cli_last_nl_returned) {cli_last_nl_returned=1;return EOL;} yyterminate(); } +[\`\"] { + BEGIN(str); + str_delim = yy_cli_def_text[0]; + string_buf_ptr = string_buf = my_malloc(STR_DELTA + 1, ""); + string_len = STR_DELTA; + string_buf_len = STR_DELTA; + } +<str>[\"\`] { + /* maybe a closing quote - all done */ + if(str_delim == yy_cli_def_text[0]) { + BEGIN(INITIAL); + *string_buf_ptr = 0; + /* return string constant token type and + * value to parser + */ + yy_cli_parse_lval.strp = string_buf; + return str_delim == '"'?STRING:EX_STRING; + }else{ + *string_buf_ptr++ = yy_cli_def_text[0]; + goto string_too_long; + } + } + +<str>\n { + /* error - unterminated string constant */ + yy_cli_def_lineno++; + } + +<str>\\n {*string_buf_ptr++ = '\n';goto string_too_long;} +<str>\\t {*string_buf_ptr++ = '\t';goto string_too_long;} +<str>\\r {*string_buf_ptr++ = '\r';goto string_too_long;} +<str>\\b {*string_buf_ptr++ = '\b';goto string_too_long;} +<str>\\f {*string_buf_ptr++ = '\f';goto string_too_long;} +<str>\\\n { yy_cli_def_lineno++; /* continuation => ignore */ } + +<str>\\. { + *string_buf_ptr++ = yy_cli_def_text[1]; +string_too_long: + *string_buf_ptr = 0; + /* printf("Cur string |%s|\n", string_buf); */ + if (!--string_len) { + string_buf = my_realloc(string_buf, + string_buf_len + STR_DELTA + 1, + "cli_def STRING"); + string_buf_ptr = string_buf + string_buf_len; + string_buf_len += STR_DELTA; + string_len = STR_DELTA; + } + } +<str>[^\\\n\"\`]+ { + char *yptr = yy_cli_def_text; + + while ( *yptr ){ + *string_buf_ptr++ = *yptr++; + if (!--string_len) { + string_buf = my_realloc(string_buf, + string_buf_len + STR_DELTA + 1, + "cli_def STRING"); + string_buf_ptr = string_buf + string_buf_len; + string_buf_len += STR_DELTA; + string_len = STR_DELTA; + } + } + *string_buf_ptr = 0; + } + +default: return DEFAULT; +tag: return TAG; +type: return TYPE; +help: return HELP; +syntax: return SYNTAX; +commit: return COMMIT; +check: yy_cli_parse_lval.action = syntax_act; return ACTION; +delete: yy_cli_parse_lval.action = delete_act; return ACTION; +update: yy_cli_parse_lval.action = update_act; return ACTION; +activate: yy_cli_parse_lval.action = activate_act; return ACTION; +create: yy_cli_parse_lval.action = create_act; return ACTION; +begin: yy_cli_parse_lval.action = begin_act; return ACTION; +end: yy_cli_parse_lval.action = end_act; return ACTION; +multi: return MULTI; + +:: { + make_def_value(IPV6_TYPE); + return VALUE; + } +txt { + yy_cli_parse_lval.type = TEXT_TYPE; + return TYPE_DEF; + } + +pattern return PATTERN; + +exec return EXEC; + +, return COMMA; +\|\| return OR; +\&\& return AND; +\= return ASSIGN; +\=\= {yy_cli_parse_lval.cond = EQ_COND; return COND;} +\!\= {yy_cli_parse_lval.cond = NE_COND; return COND;} +\< {yy_cli_parse_lval.cond = LT_COND; return COND;} +\> {yy_cli_parse_lval.cond = GT_COND; return COND;} +\<\= {yy_cli_parse_lval.cond = LE_COND; return COND;} +\>\= {yy_cli_parse_lval.cond = GE_COND; return COND;} +in {yy_cli_parse_lval.cond = IN_COND; return COND;} +\! { return NOT; } +\$\([^)]+\) { + yy_cli_parse_lval.strp = my_strdup(yy_cli_def_text, "TEXT"); + return VAR; + } +true { + make_def_value(BOOL_TYPE); + return VALUE; + } + +false { + make_def_value(BOOL_TYPE); + return VALUE; + } + +[0-9]+ { + make_def_value(INT_TYPE); + return VALUE; + } + +{RE_IPV4} { + make_def_value(IPV4_TYPE); + return VALUE; + } + +{RE_IPV4NET} { + make_def_value(IPV4NET_TYPE); + return VALUE; + } + +{RE_IPV6} { + make_def_value(IPV6_TYPE); + return VALUE; + } + +{RE_IPV6NET} { + make_def_value(IPV6NET_TYPE); + return VALUE; + } + +{RE_MACADDR} { + make_def_value(MACADDR_TYPE); + return VALUE; + } +u32 { + yy_cli_parse_lval.type = INT_TYPE; + return TYPE_DEF; + } + +ipv4 { + yy_cli_parse_lval.type = IPV4_TYPE; + return TYPE_DEF; + } + +ipv4net { + yy_cli_parse_lval.type = IPV4NET_TYPE; + return TYPE_DEF; + } +ipv6 { + yy_cli_parse_lval.type = IPV6_TYPE; + return TYPE_DEF; + } + +ipv6net { + yy_cli_parse_lval.type = IPV6NET_TYPE; + return TYPE_DEF; + } +bool { + yy_cli_parse_lval.type = BOOL_TYPE; + return TYPE_DEF; + } +macaddr { + yy_cli_parse_lval.type = MACADDR_TYPE; + return TYPE_DEF; + } +\( return LP; +\) return RP; +; return SEMI; + +\\\n { yy_cli_def_lineno++; /*whitespace -- continuation => ignore */ } + +[ \t]+ /* whitespace */ + +. { + /* everything else is a syntax error */ + return SYNTAX_ERROR; + } + +%% + +static void make_def_value(vtw_type_e type) +{ + memset(&yy_cli_parse_lval.val.val, 0, sizeof(yy_cli_parse_lval.val.val)); + yy_cli_parse_lval.val.free_me = TRUE; + yy_cli_parse_lval.val.val = my_strdup(yy_cli_def_text, "cli_parse.l"); + yy_cli_parse_lval.val.val_type = type; +} |