Newer
Older
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
/* 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 );
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
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_yylex_destroy(io.scanner);
if (length > 1) {
strcpy(buf, "0");
}
} else {
if (io.val->type == AST_EXPR_integer) {
int res_length;
res_length = snprintf(buf, length, "%ld", (long int) io.val->u.i);
return_value = (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 */
}
Kevin P. Fleming
committed
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
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;
Kevin P. Fleming
committed
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,
Kevin P. Fleming
committed
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
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 */
Kevin P. Fleming
committed
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
Kevin P. Fleming
committed
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
Kevin P. Fleming
committed
free(s2);
return(0);
}