summaryrefslogtreecommitdiff
path: root/src/cli_def.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli_def.l')
-rw-r--r--src/cli_def.l424
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;
+}