123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- %{
- ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- enum valtype {
- AST_EXPR_number, AST_EXPR_numeric_string, AST_EXPR_string
- } ;
- struct val {
- enum valtype type;
- union {
- char *s;
- FP___TYPE i;
- } u;
- } ;
- yylloc_param->first_column = (int)(yyg->yytext_r - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf); \
- yylloc_param->last_column += yyleng - 1; \
- yylloc_param->first_line = yylloc_param->last_line = 1; \
- } while (0)
- yylval_param->val = calloc(1, sizeof(struct val)); \
- yylval_param->val->type = AST_EXPR_string; \
- yylval_param->val->u.s = strdup(yytext); \
- } while (0)
- yylval_param->val = calloc(1, sizeof(struct val)); \
- yylval_param->val->type = AST_EXPR_numeric_string; \
- yylval_param->val->u.s = strdup(yytext); \
- } while (0)
- struct parse_io
- {
- char *string;
- struct val *val;
- yyscan_t scanner;
- struct ast_channel *chan;
- };
-
- 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(const char *mess);
- %}
- %option prefix="ast_yy"
- %option batch
- %option 8bit
- %option outfile="ast_expr2f.c"
- %option reentrant
- %option bison-bridge
- %option bison-locations
- %option noyywrap
- %option noyyfree
- %x var trail
- %%
- \| { 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_TILDETILDE;}
- \> { SET_COLUMNS; SET_STRING; return TOK_GT;}
- \< { SET_COLUMNS; SET_STRING; return TOK_LT;}
- \>\= { SET_COLUMNS; SET_STRING; return TOK_GE;}
- \<\= { SET_COLUMNS; SET_STRING; return TOK_LE;}
- \!\= { SET_COLUMNS; SET_STRING; return TOK_NE;}
- \+ { SET_COLUMNS; SET_STRING; return TOK_PLUS;}
- \, { SET_COLUMNS; SET_STRING; return TOK_COMMA;}
- \- { SET_COLUMNS; SET_STRING; return TOK_MINUS;}
- \* { SET_COLUMNS; SET_STRING; return TOK_MULT;}
- \/ { 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;}
- \) { SET_COLUMNS; SET_STRING; return TOK_RP;}
- \$\{ {
-
- curlycount = 0;
- BEGIN(var);
- yymore();
- }
- [ \t\r] {}
- \"[^"]*\" {SET_COLUMNS; SET_STRING; return TOKEN;}
- [\n] {}
- [0-9]+(\.[0-9]+)? {
- SET_COLUMNS;
-
- SET_NUMERIC_STRING;
- return TOKEN;
- }
- ([a-zA-Z0-9\.';\\_^#@]|[\x80-\xff]|($[^{]))+ {
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
- ([a-zA-Z0-9\.';\\_^#@]|[\x80-\xff]|($[^{]))+\$\{ {
- curlycount = 0;
- BEGIN(var);
- yymore();
- }
- <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$():?%/+=*<>!|&]*\$\{ {
- curlycount = 0;
- BEGIN(var);
- yymore();
- }
-
- <trail>[-\t\r \n$():?%/+=*<>!|&] {
- char c = yytext[yyleng-1];
- BEGIN(0);
- unput(c);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
-
- <trail><<EOF>> {
- BEGIN(0);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
-
- }
- %%
- int ast_yyparse(void *);
- int ast_yyerror(const char *, YYLTYPE *, struct parse_io *);
- void ast_yyfree(void *ptr, yyscan_t yyscanner)
- {
-
- free( (char *) ptr );
- }
- int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
- {
- struct parse_io io = { .string = expr, .chan = chan };
- int return_value = 0;
- ast_yylex_init(&io.scanner);
- ast_yy_scan_string(expr, io.scanner);
- ast_yyparse ((void *) &io);
- ast_yylex_destroy(io.scanner);
- if (!io.val) {
- if (length > 1) {
- strcpy(buf, "0");
- return_value = 1;
- }
- } else {
- if (io.val->type == AST_EXPR_number) {
- int res_length;
- res_length = snprintf(buf, length, FP___PRINTF, io.val->u.i);
- return_value = (res_length <= length) ? res_length : length;
- } else {
- if (io.val->u.s)
- strncpy(buf, io.val->u.s, length - 1);
- ast_copy_string(buf, io.val->u.s, length);
- else
- buf[0] = 0;
- return_value = strlen(buf);
- free(io.val->u.s);
- }
- free(io.val);
- }
- return return_value;
- }
- int ast_str_expr(struct ast_str **str, ssize_t maxlen, struct ast_channel *chan, char *expr)
- {
- struct parse_io io = { .string = expr, .chan = chan };
- ast_yylex_init(&io.scanner);
- ast_yy_scan_string(expr, io.scanner);
- ast_yyparse ((void *) &io);
- ast_yylex_destroy(io.scanner);
- if (!io.val) {
- ast_str_set(str, maxlen, "0");
- } else {
- if (io.val->type == AST_EXPR_number) {
- ast_str_set(str, maxlen, FP___PRINTF, io.val->u.i);
- } else if (io.val->u.s) {
- ast_str_set(str, maxlen, "%s", io.val->u.s);
- free(io.val->u.s);
- }
- free(io.val);
- }
- return ast_str_strlen(*str);
- }
- 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 const char * const 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_COMMA",
- "TOK_RP",
- "TOK_LP"
- };
- static const char * const expr2_token_equivs2[] =
- {
- "<token>",
- "?",
- "::",
- "|",
- "&",
- "=",
- ">",
- "<",
- ">=",
- "<=",
- "!=",
- "+",
- "-",
- "*",
- "/",
- "%",
- "!",
- ":",
- "=~",
- ",",
- ")",
- "("
- };
- static char *expr2_token_subst(const char *mess)
- {
-
- int len=0,i;
- const char *p;
- char *res, *s;
- const char *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];
- int i=0;
- char *s2 = expr2_token_subst(s);
- spacebuf[0] = 0;
- for (i = 0; i < (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf); i++) {
- spacebuf[i] = ' ';
- }
-
- spacebuf[i++] = '^';
- spacebuf[i] = 0;
-
- printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
- (extra_error_message_supplied ? extra_error_message : ""), s2, parseio->string, spacebuf);
- 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, spacebuf);
- ast_log(LOG_WARNING,"If you have questions, please refer to https://wiki.asterisk.org/wiki/display/AST/Channel+Variables\n");
- free(s2);
- return(0);
- }
|