%{ /* This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* Copyright (c) 2006 Clive Nicolson clive@baby.bedroom.gen.nz */ #include #include #include "fmli.h" #define YYSTYPE char * #include "fmli_parse.h" #define YY_DECL int yylex(fgfg_param p1) YY_DECL; YYSTYPE yylval; static fgfg_param p1, *g_p1 = &p1; #define yyerror fgfgfg_msg static void yyfatalerror(fgfg_param p1, const char *msg) { yyerror(p1, msg); if (0) yy_fatal_error(msg); exit(2); } #define YY_FATAL_ERROR(msg) yyfatalerror(p1, msg) #define MAX_INCLUDE_DEPTH 10 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; static int include_stack_ptr; static void push_include_stack(fgfg_param p1) { if (include_stack_ptr >= sizeof(include_stack)/sizeof(include_stack[0])) YY_FATAL_ERROR("include stack underflows"); else include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; } static int pop_include_stack(fgfg_param p1) { int res; res = include_stack_ptr <= 0; if (!res) { yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(include_stack[--include_stack_ptr]); } return res; } static char * dblquote_bckquotestring(const char *bckquotestring) { char *ss; ss = malloc(strlen(bckquotestring)+2+1); strcpy(ss, "\""); strcat(ss, bckquotestring); strcat(ss, "\""); return ss; } static int eof(void); #define yyterminate() return (eof()) %} /* Definitions */ %option stack yymore noyy_top_state %option never-interactive %x value BCK SNG DBL WRD %% /* The rules */ %{ *g_p1 = p1; %} { [:blank:]+ | /* Eat white looking stuff */ #.* /* Eat comment */ ` yymore(); yy_push_state(BCK); [[:alpha:]_][[:alnum:]_.]* { yylval = strdup(yytext); return(name); } = { BEGIN(value); return(yytext[yyleng-1]); } .|\n return(yytext[yyleng-1]); } { ` yymore(); yy_push_state(BCK); ' yymore(); yy_push_state(SNG); \" yymore(); yy_push_state(DBL); . { unput(yytext[yyleng-1]); yy_push_state(WRD); } \n { unput(yytext[yyleng-1]); BEGIN(INITIAL); } } { <> { yyerror(p1, "Unterminated BCKquote string"); yyterminate(); } ((\\(.|\n))|[^\\`'"])+ yymore(); ` { yy_pop_state(); if (YY_START == INITIAL) { if (include_stack_ptr >= MAX_INCLUDE_DEPTH) yyerror(p1, "include_stack nesting too deep"); else { char *s; char *ss; ss = dblquote_bckquotestring(yytext); s = fgfgfg_eval(p1, ss); free(ss); push_include_stack(p1); yy_scan_string(s); free(s); } } else if (YY_START == value) { #if 0 yylval = dblquote_bckquotestring(yytext); #else yylval = strdup(yytext); #endif return(bckquote_string); } else yymore(); } ' yymore(); yy_push_state(SNG); \" yymore(); yy_push_state(DBL); } { <> { yyerror(p1, "Unterminated SNGquote string"); yyterminate(); } ((\\(.|\n))|[^\\'])+ yymore(); ' { yy_pop_state(); if (YY_START == value) { yylval = strdup(yytext); return(sngquote_string); } else yymore(); } } { <> { yyerror(p1, "Unterminated DBLquote string"); yyterminate(); } ((\\(.|\n))|[^\\`"])+ yymore(); ` yymore(); yy_push_state(BCK); \" { yy_pop_state(); if (YY_START == value) { yylval = strdup(yytext); return(dblquote_string); } else yymore(); } } { ((\\(.|\n))|[^\\`'"\n])+ { yylval = strdup(yytext); return(word_string); } [`'"\n] { unput(yytext[yyleng-1]); yy_pop_state(); } } { <> yyterminate(); } { \\ { yy_pop_state(); yyerror(p1, "Unterminated \\"); yyterminate(); } } %% /* User code */ int yywrap(void) { return pop_include_stack(p1); } static int eof(void) { BEGIN(INITIAL); yy_delete_buffer(YY_CURRENT_BUFFER); #ifdef FLEX_SCANNER if (yy_start_stack) { /*CLN:Nasty!!! Stop memory leak */ yy_flex_free(yy_start_stack); yy_start_stack = NULL; yy_start_stack_depth = 0; } #else free(yytext); yytext = NULL; yylength = 0; #endif return(YY_NULL); } /*The end*/