123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- %{
- #include <sys/types.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <locale.h>
- #include <ctype.h>
- #if !defined(SOLARIS) && !defined(__CYGWIN__)
- #include <err.h>
- #else
- #define quad_t int64_t
- #endif
- #include <errno.h>
- #include <regex.h>
- #include <limits.h>
- #include <asterisk/ast_expr.h>
- #include <asterisk/logger.h>
- #include <asterisk/strings.h>
- enum valtype {
- AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
- } ;
- struct val {
- enum valtype type;
- union {
- char *s;
- quad_t i;
- } u;
- } ;
- #include "ast_expr2.h" /* the o/p of the bison on ast_expr2.y */
- #define SET_COLUMNS yylloc_param->first_column = (int)(yyg->yytext_r - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);yylloc_param->last_column = yylloc_param->last_column + yyleng - 1; yylloc_param->first_line = yylloc_param->last_line = 1
- #define SET_STRING yylval_param->val = (struct val *)calloc(sizeof(struct val),1); yylval_param->val->type = AST_EXPR_string; yylval_param->val->u.s = strdup(yytext);
- #define SET_NUMERIC_STRING yylval_param->val = (struct val *)calloc(sizeof(struct val),1); yylval_param->val->type = AST_EXPR_numeric_string; yylval_param->val->u.s = strdup(yytext);
- struct parse_io
- {
- char *string;
- struct val *val;
- yyscan_t scanner;
- };
-
- void ast_yyset_column(int column_no, yyscan_t yyscanner);
- int ast_yyget_column(yyscan_t yyscanner);
- %}
- %option prefix="ast_yy"
- %option batch
- %option outfile="ast_expr2f.c"
- %option reentrant
- %option bison-bridge
- %option bison-locations
- %option noyywrap
- %%
- \| { 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_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_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_COLON;}
- \:\: { SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
- \( { SET_COLUMNS; SET_STRING; return TOK_LP;}
- \) { SET_COLUMNS; SET_STRING; return TOK_RP;}
- [ \r] {}
- \"[^"]*\" {SET_COLUMNS; SET_STRING; return TOKEN;}
- [\n] {/* what to do with eol */}
- [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;}
- %%
- /* I'm putting the interface routine to the whole parse here in the flexer input file
- mainly because of all the flexer initialization that has to be done. Shouldn't matter
- where it is, as long as it's somewhere. I didn't want to define a prototype for the
- ast_yy_scan_string in the .y file, because then, I'd have to define YY_BUFFER_STATE there...
- UGH! that would be inappropriate. */
- int ast_yyparse(void *); /* need to/should define this prototype for the call to yyparse */
- int ast_yyerror(const char *, YYLTYPE *, struct parse_io *); /* likewise */
- int ast_expr(char *expr, char *buf, int length)
- {
- struct parse_io *io;
-
- io = calloc(sizeof(struct parse_io),1);
- io->string = expr; /* to pass to the error routine */
-
- ast_yylex_init(&io->scanner);
-
- ast_yy_scan_string(expr, io->scanner);
-
- ast_yyparse ((void *) io);
- ast_yylex_destroy(io->scanner);
- if (io->val == NULL) {
- if (length > 1) {
- strcpy(buf, "0");
- return 1;
- }
- } else {
- if (io->val->type == AST_EXPR_integer) {
- int res_length;
- res_length = snprintf(buf, length, "%ld", (long int) io->val->u.i);
- return res_length <= length ? res_length : length;
- } else {
- #ifdef STANDALONE
- strncpy(buf, io->val->u.s, length - 1);
- #else /* !STANDALONE */
- ast_copy_string(buf, io->val->u.s, length);
- #endif /* STANDALONE */
- return strlen(buf);
- }
- free(io->val);
- }
- free(io);
- return 0;
- }
- 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;
- spacebuf[0] = 0;
-
- #ifdef WHEN_LOC_MEANS_SOMETHING
- if( loc->first_column > 7990 ) /* if things get out of whack, why crash? */
- loc->first_column = 7990;
- if( loc->last_column > 7990 )
- loc->last_column = 7990;
- for(i=0;i<loc->first_column;i++) spacebuf[i] = ' ';
- for( ;i<loc->last_column;i++) spacebuf[i] = '^';
- spacebuf[i] = 0;
- #endif
- 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:
- 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
- may not relate to the entire string/buffer because of the
- buffering.
- b. but, analysis of the situation is that when you use the
- yy_scan_string func, it creates a single buffer the size of
- string, so the two would be the same...
- so, in the end, the yycolumn macro is available, shorter, therefore easier. */
- spacebuf2[i++]='^';
- spacebuf2[i]= 0;
- #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);
- #else
- ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",
- s, parseio->string,spacebuf2);
- #endif
- #ifndef STANDALONE
- ast_log(LOG_WARNING,"If you have questions, please refer to doc/README.variables in the asterisk source.\n");
- #endif
- return(0);
- }
|