📄 ael.flex
字号:
STORE_LOC; ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c); BEGIN(0); yylval->str = malloc(yyleng+1); strncpy(yylval->str, yytext, yyleng); yylval->str[yyleng] = 0; return word; } yymore(); } /* * handlers for arguments to a macro or application calls. * We enter this context when we find the initial '(' and * stay here until we close all matching parentheses, * and find the comma (argument separator) or the closing ')' * of the (external) call, which happens when parencount == 0 * before the decrement. */<argg>{NOARGG}[\(\[\{] { char c = yytext[yyleng-1]; if (c == '(') parencount++; pbcpush(c); yymore(); }<argg>{NOARGG}\) { if ( pbcpop(')') ) { /* error */ STORE_LOC; ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno, my_col); BEGIN(0); yylval->str = malloc(yyleng+1); strncpy(yylval->str, yytext, yyleng); yylval->str[yyleng] = 0; return word; } parencount--; if( parencount >= 0){ yymore(); } else { STORE_LOC; BEGIN(0); if ( !strcmp(yytext, ")") ) return RP; yylval->str = malloc(yyleng); strncpy(yylval->str, yytext, yyleng); yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */ unput(')'); return word; } }<argg>{NOARGG}\, { if( parencount != 0) { /* ast_log(LOG_NOTICE,"Folding in a comma!\n"); */ yymore(); } else { STORE_LOC; if( !strcmp(yytext,"," ) ) return COMMA; yylval->str = malloc(yyleng); strncpy(yylval->str, yytext, yyleng); yylval->str[yyleng-1] = '\0'; /* trim trailing ',' */ unput(','); return word; } }<argg>{NOARGG}[\]\}] { char c = yytext[yyleng-1]; if ( pbcpop(c) ) { /* error */ STORE_LOC; ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c); BEGIN(0); yylval->str = malloc(yyleng+1); strncpy(yylval->str, yytext, yyleng); yylval->str[yyleng] = '\0'; return word; } yymore(); } /* * context used to find tokens in the right hand side of assignments, * or in the first and second operand of a 'for'. As above, match * commas and use ';' as a separator (hence return it as a separate token). */<semic>{NOSEMIC}[\(\[\{] { char c = yytext[yyleng-1]; yymore(); pbcpush(c); }<semic>{NOSEMIC}[\)\]\}] { char c = yytext[yyleng-1]; if ( pbcpop(c) ) { /* error */ STORE_LOC; ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c); BEGIN(0); yylval->str = malloc(yyleng+1); strncpy(yylval->str, yytext, yyleng); yylval->str[yyleng] = '\0'; return word; } yymore(); }<semic>{NOSEMIC}; { STORE_LOC; yylval->str = malloc(yyleng); strncpy(yylval->str, yytext, yyleng); yylval->str[yyleng-1] = '\0'; /* trim trailing ';' */ unput(';'); BEGIN(0); return word; }\#include[ \t]+\"[^\"]+\" { char fnamebuf[1024],*p1,*p2; int glob_ret; glob_t globbuf; /* the current globbuf */ int globbuf_pos = -1; /* where we are in the current globbuf */ globbuf.gl_offs = 0; /* initialize it to silence gcc */ p1 = strchr(yytext,'"'); p2 = strrchr(yytext,'"'); if ( include_stack_index >= MAX_INCLUDE_DEPTH ) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col); } else if ( (int)(p2-p1) > sizeof(fnamebuf) - 1 ) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10); } else { strncpy(fnamebuf, p1+1, p2-p1-1); fnamebuf[p2-p1-1] = 0; if (fnamebuf[0] != '/') { char fnamebuf2[1024]; snprintf(fnamebuf2,sizeof(fnamebuf2), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, fnamebuf); ast_copy_string(fnamebuf,fnamebuf2,sizeof(fnamebuf)); }#ifdef SOLARIS glob_ret = glob(fnamebuf, GLOB_NOCHECK, NULL, &globbuf);#else glob_ret = glob(fnamebuf, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);#endif if (glob_ret == GLOB_NOSPACE) { ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Not enough memory\n", fnamebuf); } else if (glob_ret == GLOB_ABORTED) { ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Read error\n", fnamebuf); } else if (glob_ret == GLOB_NOMATCH) { ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: No matches!\n", fnamebuf); } else { globbuf_pos = 0; } } if (globbuf_pos > -1) { setup_filestack(fnamebuf, sizeof(fnamebuf), &globbuf, 0, yyscanner, 1); } }<<EOF>> { char fnamebuf[2048]; if (include_stack_index > 0 && include_stack[include_stack_index-1].globbuf_pos < include_stack[include_stack_index-1].globbuf.gl_pathc-1) { yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner ); include_stack[include_stack_index-1].globbuf_pos++; setup_filestack(fnamebuf, sizeof(fnamebuf), &include_stack[include_stack_index-1].globbuf, include_stack[include_stack_index-1].globbuf_pos, yyscanner, 0); /* finish this */ } else { if (include_stack[include_stack_index].fname) { free(include_stack[include_stack_index].fname); include_stack[include_stack_index].fname = 0; } if (my_file) { free(my_file); my_file = 0; } if ( --include_stack_index < 0 ) { yyterminate(); } else { globfree(&include_stack[include_stack_index].globbuf); include_stack[include_stack_index].globbuf_pos = -1; yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner ); yy_switch_to_buffer(include_stack[include_stack_index].bufstate, yyscanner ); my_lineno = include_stack[include_stack_index].lineno; my_col = include_stack[include_stack_index].colno; my_file = strdup(include_stack[include_stack_index].fname); } } }<*>.|\n { /* default rule */ ast_log(LOG_ERROR,"Unhandled char(s): %s\n", yytext); }%%static void pbcpush(char x){ pbcstack[pbcpos++] = x;}void ael_yyfree(void *ptr, yyscan_t yyscanner){ if (ptr) free( (char*) ptr );}static int pbcpop(char x){ if ( ( x == ')' && pbcstack[pbcpos-1] == '(' ) || ( x == ']' && pbcstack[pbcpos-1] == '[' ) || ( x == '}' && pbcstack[pbcpos-1] == '{' )) { pbcpos--; return 0; } return 1; /* error */}static void pbcpush2(char x){ pbcstack2[pbcpos2++] = x;}static int pbcpop2(char x){ if ( ( x == ')' && pbcstack2[pbcpos2-1] == '(' ) || ( x == ']' && pbcstack2[pbcpos2-1] == '[' ) || ( x == '}' && pbcstack2[pbcpos2-1] == '{' )) { pbcpos2--; return 0; } return 1; /* error */}static void pbcpush3(char x){ pbcstack3[pbcpos3++] = x;}static int pbcpop3(char x){ if ( ( x == ')' && pbcstack3[pbcpos3-1] == '(' ) || ( x == ']' && pbcstack3[pbcpos3-1] == '[' ) || ( x == '}' && pbcstack3[pbcpos3-1] == '{' )) { pbcpos3--; return 0; } return 1; /* error */}static int c_prevword(void){ char *c = prev_word; if (c == NULL) return 0; while ( *c ) { switch (*c) { case '{': case '[': case '(': pbcpush(*c); break; case '}': case ']': case ')': if (pbcpop(*c)) return 1; break; } c++; } return 0;}/* * The following three functions, reset_*, are used in the bison * code to switch context. As a consequence, we need to * declare them global and add a prototype so that the * compiler does not complain. * * NOTE: yyg is declared because it is used in the BEGIN macros, * though that should be hidden as the macro changes * depending on the flex options that we use - in particular, * %reentrant changes the way the macro is declared; * without %reentrant, BEGIN uses yystart instead of yyg */void reset_parencount(yyscan_t yyscanner );void reset_parencount(yyscan_t yyscanner ){ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; parencount = 0; pbcpos = 0; pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */ c_prevword(); BEGIN(paren);}void reset_semicount(yyscan_t yyscanner );void reset_semicount(yyscan_t yyscanner ){ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; pbcpos = 0; BEGIN(semic);}void reset_argcount(yyscan_t yyscanner );void reset_argcount(yyscan_t yyscanner ){ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; parencount = 0; pbcpos = 0; pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */ c_prevword(); BEGIN(argg);}/* used elsewhere, but some local vars */struct pval *ael2_parse(char *filename, int *errors){ struct pval *pval; struct parse_io *io; char *buffer; struct stat stats; FILE *fin; /* extern int ael_yydebug; */ io = calloc(sizeof(struct parse_io),1); /* reset the global counters */ prev_word = 0; my_lineno = 1; include_stack_index=0; my_col = 0; /* ael_yydebug = 1; */ ael_yylex_init(&io->scanner); fin = fopen(filename,"r"); if ( !fin ) { ast_log(LOG_ERROR,"File %s could not be opened\n", filename); *errors = 1; return 0; } if (my_file) free(my_file); my_file = strdup(filename); stat(filename, &stats); buffer = (char*)malloc(stats.st_size+2); if (fread(buffer, 1, stats.st_size, fin) != stats.st_size) { ast_log(LOG_ERROR, "fread() failed: %s\n", strerror(errno)); } buffer[stats.st_size]=0; fclose(fin); ael_yy_scan_string (buffer ,io->scanner); ael_yyset_lineno(1 , io->scanner); /* ael_yyset_in (fin , io->scanner); OLD WAY */ ael_yyparse(io); pval = io->pval; *errors = io->syntax_error_count; ael_yylex_destroy(io->scanner); free(buffer); free(io); return pval;}static void setup_filestack(char *fnamebuf2, int fnamebuf_siz, glob_t *globbuf, int globpos, yyscan_t yyscanner, int create){ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; int error, i; FILE *in1; char fnamebuf[2048]; if (globbuf && globbuf->gl_pathv && globbuf->gl_pathc > 0)#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL) strncpy(fnamebuf, globbuf->gl_pathv[globpos], fnamebuf_siz);#else ast_copy_string(fnamebuf, globbuf->gl_pathv[globpos], fnamebuf_siz);#endif else { ast_log(LOG_ERROR,"Include file name not present!\n"); return; } for (i=0; i<include_stack_index; i++) { if ( !strcmp(fnamebuf,include_stack[i].fname )) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n", my_file, my_lineno, my_col, fnamebuf); break; } } error = 1; if (i == include_stack_index) error = 0; /* we can use this file */ if ( !error ) { /* valid file name */ /* relative vs. absolute */ if (fnamebuf[0] != '/') snprintf(fnamebuf2, fnamebuf_siz, "%s/%s", ast_config_AST_CONFIG_DIR, fnamebuf); else#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL) strncpy(fnamebuf2, fnamebuf, fnamebuf_siz);#else ast_copy_string(fnamebuf2, fnamebuf, fnamebuf_siz);#endif in1 = fopen( fnamebuf2, "r" ); if ( ! in1 ) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf2); } else { char *buffer; struct stat stats; stat(fnamebuf2, &stats); buffer = (char*)malloc(stats.st_size+1); if (fread(buffer, 1, stats.st_size, in1) != stats.st_size) { ast_log(LOG_ERROR, "fread() failed: %s\n", strerror(errno)); } buffer[stats.st_size] = 0; ast_log(LOG_NOTICE," --Read in included file %s, %d chars\n",fnamebuf2, (int)stats.st_size); fclose(in1); if (include_stack[include_stack_index].fname) { free(include_stack[include_stack_index].fname); include_stack[include_stack_index].fname = 0; } include_stack[include_stack_index].fname = strdup(my_file); include_stack[include_stack_index].lineno = my_lineno; include_stack[include_stack_index].colno = my_col+yyleng; if (my_file) free(my_file); my_file = strdup(fnamebuf2); if (create) include_stack[include_stack_index].globbuf = *globbuf; include_stack[include_stack_index].globbuf_pos = 0; include_stack[include_stack_index].bufstate = YY_CURRENT_BUFFER; if (create) include_stack_index++; yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner); free(buffer); my_lineno = 1; my_col = 1; BEGIN(INITIAL); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -