Skip to content
Snippets Groups Projects
ast_expr2f.c 105 KiB
Newer Older
  • Learn to ignore specific revisions
  • /* Defined in main.c */
    #ifdef YY_STDINIT
        yyin = stdin;
        yyout = stdout;
    #else
        yyin = (FILE *) 0;
        yyout = (FILE *) 0;
    #endif
    
        /* For future reference: Set errno on error, since we are called by
         * ast_yylex_init()
         */
        return 0;
    }
    
    /* ast_yylex_destroy is for both reentrant and non-reentrant scanners. */
    int ast_yylex_destroy  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
        /* Pop the buffer stack, destroying each element. */
    	while(YY_CURRENT_BUFFER){
    		ast_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
    		YY_CURRENT_BUFFER_LVALUE = NULL;
    		ast_yypop_buffer_state(yyscanner);
    	}
    
    	/* Destroy the stack itself. */
    	ast_yyfree(yyg->yy_buffer_stack ,yyscanner);
    	yyg->yy_buffer_stack = NULL;
    
        /* Destroy the start condition stack. */
            ast_yyfree(yyg->yy_start_stack ,yyscanner );
            yyg->yy_start_stack = NULL;
    
    
        /* Reset the globals. This is important in a non-reentrant scanner so the next time
         * ast_yylex() is called, initialization will occur. */
        yy_init_globals( yyscanner);
    
    
        /* Destroy the main struct (reentrant only). */
        ast_yyfree ( yyscanner , yyscanner );
    
        return 0;
    }
    
    /*
     * Internal utility routines.
     */
    
    #ifndef yytext_ptr
    static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
    {
    	register int i;
    	for ( i = 0; i < n; ++i )
    		s1[i] = s2[i];
    }
    #endif
    
    #ifdef YY_NEED_STRLEN
    static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
    {
    	register int n;
    	for ( n = 0; s[n]; ++n )
    		;
    
    	return n;
    }
    #endif
    
    void *ast_yyalloc (yy_size_t  size , yyscan_t yyscanner)
    {
    	return (void *) malloc( size );
    }
    
    void *ast_yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
    {
    	/* The cast to (char *) in the following accommodates both
    	 * implementations that use char* generic pointers, and those
    	 * that use void* generic pointers.  It works with the latter
    	 * because both ANSI C and C++ allow castless assignment from
    	 * any pointer type to void*, and deal with argument conversions
    	 * as though doing an assignment.
    	 */
    	return (void *) realloc( (char *) ptr, size );
    }
    
    void ast_yyfree (void * ptr , yyscan_t yyscanner)
    {
    	free( (char *) ptr );	/* see ast_yyrealloc() for (char *) cast */
    }
    
    #define YYTABLES_NAME "yytables"
    
    
    #line 203 "ast_expr2.fl"
    
    
    
    
    /* 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;
    	int return_value = 0;
    
    	memset(&io, 0, sizeof(io));
    	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);
    
    			return_value = 1;
    
    		if (io.val->type == AST_EXPR_integer) {
    
    			res_length = snprintf(buf, length, "%ld", (long int) io.val->u.i);
    			return_value = (res_length <= length) ? res_length : length;
    
    			strncpy(buf, io.val->u.s, length - 1);
    
    			ast_copy_string(buf, io.val->u.s, length);
    
    			return_value = strlen(buf);
    
    Tilghman Lesher's avatar
     
    Tilghman Lesher committed
    			free(io.val->u.s);
    
    	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;
    
    	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,
    
    													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
    															ast_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(): %s syntax error: %s; Input:\n%s\n%s\n",  
    			(extra_error_message_supplied?extra_error_message:""), s2, 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);
    
    	ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n");