diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-24 17:41:27 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-24 17:41:27 +0000 |
commit | 6baa8fbab851e094bc67dbe0dc67817e55a11075 (patch) | |
tree | 5ce36257d23c91be83f8acd95dbb5342a8b2dcfd /ast_expr2.fl | |
parent | e196b45892e129c7e3e877d4749b786c2cd8c2ee (diff) |
Merge Steve Murphy's (murf) complete re-implementation of AEL, which is now no longer considered experimental :-)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@22273 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'ast_expr2.fl')
-rw-r--r-- | ast_expr2.fl | 137 |
1 files changed, 129 insertions, 8 deletions
diff --git a/ast_expr2.fl b/ast_expr2.fl index 8eaea639f..6273bc8b1 100644 --- a/ast_expr2.fl +++ b/ast_expr2.fl @@ -19,7 +19,7 @@ /*! \file * - * \brief Dialplan Expression Parser + * \brief Dialplan Expression Lexical Scanner */ #include <sys/types.h> @@ -73,6 +73,7 @@ struct parse_io void ast_yyset_column(int column_no, yyscan_t yyscanner); int ast_yyget_column(yyscan_t yyscanner); static int curlycount = 0; +static char *expr2_token_subst(char *mess); %} %option prefix="ast_yy" @@ -89,6 +90,10 @@ static int curlycount = 0; \| { SET_COLUMNS; SET_STRING; return TOK_OR;} \& { SET_COLUMNS; SET_STRING; return TOK_AND;} \= { SET_COLUMNS; SET_STRING; return TOK_EQ;} +\|\| { SET_COLUMNS; SET_STRING; return TOK_OR;} +\&\& { SET_COLUMNS; SET_STRING; return TOK_AND;} +\=\= { SET_COLUMNS; SET_STRING; return TOK_EQ;} +\=~ { SET_COLUMNS; SET_STRING; return TOK_EQTILDE;} \> { SET_COLUMNS; SET_STRING; return TOK_GT;} \< { SET_COLUMNS; SET_STRING; return TOK_LT;} \>\= { SET_COLUMNS; SET_STRING; return TOK_GE;} @@ -100,6 +105,7 @@ static int curlycount = 0; \/ { SET_COLUMNS; SET_STRING; return TOK_DIV;} \% { SET_COLUMNS; SET_STRING; return TOK_MOD;} \? { SET_COLUMNS; SET_STRING; return TOK_COND;} +\! { SET_COLUMNS; SET_STRING; return TOK_COMPL;} \: { SET_COLUMNS; SET_STRING; return TOK_COLON;} \:\: { SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;} \( { SET_COLUMNS; SET_STRING; return TOK_LP;} @@ -114,14 +120,15 @@ static int curlycount = 0; [0-9]+ { SET_COLUMNS; /* the original behavior of the expression parser was to bring in numbers as a numeric string */ SET_NUMERIC_STRING; return TOKEN;} -[a-zA-Z0-9,.';\\_^%$#@!]+ {SET_COLUMNS; SET_STRING; return TOKEN;} + +[a-zA-Z0-9,.';\\_^$#@]+ {SET_COLUMNS; SET_STRING; return TOKEN;} <var>[^{}]*\} {curlycount--; if(curlycount < 0){ BEGIN(trail); yymore();} else { yymore();}} <var>[^{}]*\{ {curlycount++; yymore(); } <trail>[^-\t\r \n$():?%/+=*<>!|&]* {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN;} <trail>[-\t\r \n$():?%/+=*<>!|&] {char c = yytext[yyleng-1]; BEGIN(0); unput(c); SET_COLUMNS; SET_STRING; return TOKEN;} <trail>\$\{ {curlycount = 0; BEGIN(var); yymore(); } -<trail><<EOF>> {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /* actually, if an expr is only a variable ref, this could happen a LOT */} +<trail><<EOF>> {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /*actually, if an expr is only a variable ref, this could happen a LOT */} %% @@ -175,16 +182,129 @@ int ast_expr(char *expr, char *buf, int length) return return_value; } + +char extra_error_message[4095]; +int extra_error_message_supplied = 0; +void ast_expr_register_extra_error_info(char *message); +void ast_expr_clear_extra_error_info(void); + +void ast_expr_register_extra_error_info(char *message) +{ + extra_error_message_supplied=1; + strcpy(extra_error_message, message); +} + +void ast_expr_clear_extra_error_info(void) +{ + extra_error_message_supplied=0; + extra_error_message[0] = 0; +} + +static char *expr2_token_equivs1[] = +{ + "TOKEN", + "TOK_COND", + "TOK_COLONCOLON", + "TOK_OR", + "TOK_AND", + "TOK_EQ", + "TOK_GT", + "TOK_LT", + "TOK_GE", + "TOK_LE", + "TOK_NE", + "TOK_PLUS", + "TOK_MINUS", + "TOK_MULT", + "TOK_DIV", + "TOK_MOD", + "TOK_COMPL", + "TOK_COLON", + "TOK_EQTILDE", + "TOK_RP", + "TOK_LP" +}; + +static char *expr2_token_equivs2[] = +{ + "<token>", + "?", + "::", + "|", + "&", + "=", + ">", + "<", + ">=", + "<=", + "!=", + "+", + "-", + "*", + "/", + "%", + "!", + ":", + "=~", + ")", + "(" +}; + + +static char *expr2_token_subst(char *mess) +{ + /* calc a length, malloc, fill, and return; yyerror had better free it! */ + int len=0,i; + char *p; + char *res, *s,*t; + int expr2_token_equivs_entries = sizeof(expr2_token_equivs1)/sizeof(char*); + + for (p=mess; *p; p++) { + for (i=0; i<expr2_token_equivs_entries; i++) { + if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) + { + len+=strlen(expr2_token_equivs2[i])+2; + p += strlen(expr2_token_equivs1[i])-1; + break; + } + } + len++; + } + res = (char*)malloc(len+1); + res[0] = 0; + s = res; + for (p=mess; *p;) { + int found = 0; + for (i=0; i<expr2_token_equivs_entries; i++) { + if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) { + *s++ = '\''; + for (t=expr2_token_equivs2[i]; *t;) { + *s++ = *t++; + } + *s++ = '\''; + p += strlen(expr2_token_equivs1[i]); + found = 1; + break; + } + } + if( !found ) + *s++ = *p++; + } + *s++ = 0; + return res; +} + int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio ) { struct yyguts_t * yyg = (struct yyguts_t*)(parseio->scanner); char spacebuf[8000]; /* best safe than sorry */ char spacebuf2[8000]; /* best safe than sorry */ int i=0; + char *s2 = expr2_token_subst((char *)s); spacebuf[0] = 0; for(i=0;i< (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);i++) spacebuf2[i] = ' '; /* uh... assuming yyg is defined, then I can use the yycolumn macro, - which is the same thing as... get this: + which is the same thing as... get this: yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]->yy_bs_column I was tempted to just use yy_buf_pos in the STATE, but..., well: a. the yy_buf_pos is the current position in the buffer, which @@ -199,14 +319,15 @@ int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio ) #ifdef STANDALONE3 /* easier to read in the standalone version */ - printf("ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n", - s, parseio->string,spacebuf2); + printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n", + (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2); #else - ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n", - s, parseio->string,spacebuf2); + ast_log(LOG_WARNING,"ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n", + (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2); #endif #ifndef STANDALONE ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n"); #endif + free(s2); return(0); } |