X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=tc%2Femp_ematch.l;fp=tc%2Femp_ematch.l;h=09d535d0510cfc34c91c8dc59226b46081795fe8;hb=b4a5a91c5a4ca186690479ddc0fff26644c98c93;hp=0000000000000000000000000000000000000000;hpb=143d7e99faac73b7f2947e37df31a75738eeadde;p=iproute2.git diff --git a/tc/emp_ematch.l b/tc/emp_ematch.l new file mode 100644 index 0000000..09d535d --- /dev/null +++ b/tc/emp_ematch.l @@ -0,0 +1,145 @@ +%{ + #include "emp_ematch.yacc.h" + #include "m_ematch.h" + + extern int ematch_argc; + extern char **ematch_argv; + + #define yylval ematch_lval + + #define NEXT_EM_ARG() do { ematch_argc--; ematch_argv++; } while(0); + + #define YY_INPUT(buf, result, max_size) \ + { \ + next: \ + if (ematch_argc <= 0) \ + result = YY_NULL; \ + else if (**ematch_argv == '\0') { \ + NEXT_EM_ARG(); \ + goto next; \ + } else { \ + if (max_size <= strlen(*ematch_argv) + 1) { \ + fprintf(stderr, "match argument too long.\n"); \ + result = YY_NULL; \ + } else { \ + strcpy(buf, *ematch_argv); \ + result = strlen(*ematch_argv) + 1; \ + buf[result-1] = ' '; \ + buf[result] = '\0'; \ + NEXT_EM_ARG(); \ + } \ + } \ + } + + static void __attribute__ ((unused)) yyunput (int c,char *buf_ptr ); + static void __attribute__ ((unused)) yy_push_state (int new_state ); + static void __attribute__ ((unused)) yy_pop_state (void); + static int __attribute__ ((unused)) yy_top_state (void ); + + static char *strbuf; + static unsigned int strbuf_size; + static unsigned int strbuf_index; + + static void strbuf_enlarge(void) + { + strbuf_size += 512; + strbuf = realloc(strbuf, strbuf_size); + } + + static void strbuf_append_char(char c) + { + while (strbuf_index >= strbuf_size) + strbuf_enlarge(); + strbuf[strbuf_index++] = c; + } + + static void strbuf_append_charp(char *s) + { + while (strbuf_index >= strbuf_size) + strbuf_enlarge(); + memcpy(strbuf + strbuf_index, s, strlen(s)); + strbuf_index += strlen(s); + } + +%} + +%x str + +%option 8bit stack warn noyywrap prefix="ematch_" +%% +[ \t\r\n]+ + +\" { + if (strbuf == NULL) { + strbuf_size = 512; + strbuf = calloc(1, strbuf_size); + if (strbuf == NULL) + return ERROR; + } + strbuf_index = 0; + + BEGIN(str); + } + +\" { + BEGIN(INITIAL); + yylval.b = bstr_new(strbuf, strbuf_index); + yylval.b->quoted = 1; + return ATTRIBUTE; + } + +\\[0-7]{1,3} { /* octal escape sequence */ + int res; + + sscanf(yytext + 1, "%o", &res); + if (res > 0xFF) { + fprintf(stderr, "error: octal escape sequence" \ + " out of range\n"); + return ERROR; + } + strbuf_append_char((unsigned char) res); + } + +\\[0-9]+ { /* catch wrong octal escape seq. */ + fprintf(stderr, "error: invalid octale escape sequence\n"); + return ERROR; + } + +\\x[0-9a-fA-F]{1,2} { + int res; + + sscanf(yytext + 2, "%x", &res); + + if (res > 0xFF) { + fprintf(stderr, "error: hexadecimal escape " \ + "sequence out of range\n"); + return ERROR; + } + strbuf_append_char((unsigned char) res); + } + +\\n strbuf_append_char('\n'); +\\r strbuf_append_char('\r'); +\\t strbuf_append_char('\t'); +\\v strbuf_append_char('\v'); +\\b strbuf_append_char('\b'); +\\f strbuf_append_char('\f'); +\\a strbuf_append_char('\a'); + +\\(.|\n) strbuf_append_char(yytext[1]); +[^\\\n\"]+ strbuf_append_charp(yytext); + +[aA][nN][dD] return AND; +[oO][rR] return OR; +[nN][oO][tT] return NOT; +"(" | +")" { + return yylval.i = *yytext; + } +[^ \t\r\n()]+ { + yylval.b = bstr_alloc(yytext); + if (yylval.b == NULL) + return ERROR; + return ATTRIBUTE; + } +%%