11 #define yylval tmpl_yylval
14 extern char* fileToParse;
16 static int yyerror(char *s, int line);
17 static int getIdent(char *word);
19 static char *strbuf = NULL;
22 static void addstring(char *s, int l);
23 static void addchar(char s);
24 static MemoryContext *lexContext;
29 %option never-interactive
33 %option prefix="tmpl_yy"
42 LEXEMCHARSTART [a-zA-Z_]
43 LEXEMCHAR [a-zA-Z0-9_]
69 yylval.punct = *yytext;
80 strbuf = mcalloc(lexContext, total);
86 <xQUOTED>\\(.|\n) { addchar(yytext[1]); }
95 <xQUOTED>[^\"\\]+ { addstring(yytext, yyleng); }
98 /* This is only needed for \ just before EOF */
102 <xEXPR,xVAR>{DIGIT}+ {
103 yylval.intval = strtoll(yytext, NULL, 0);
107 <xEXPR,xVAR>{LEXEMCHARSTART}{LEXEMCHAR}* {
108 yylval.str = strlower(mcnstrdup(lexContext, yytext, yyleng));
109 return getIdent(yylval.str);
112 <xEXPR,xVAR>\|\| { return OR_P; }
114 <xEXPR,xVAR>\&\& { return AND_P; }
116 <xEXPR,xVAR>\! { return NOT_P; }
118 <xEXPR,xVAR>[\^\%\+\*\/\-\(\)\?\:] {
119 yylval.punct = *yytext;
123 <xEXPR,xVAR>(\<|\<=|\>=|\>|==|\!=|\<\>) {
124 yylval.str = mcnstrdup(lexContext, yytext, yyleng);
128 <xEXPR,xVAR>{DIGIT}+"."{DIGIT}+ {
129 yylval.floatval = atof(yytext);
133 <xEXPR,xVAR>{DIGIT}+[eE]["+""-"]?{DIGIT}+ {
134 yylval.floatval = atof(yytext);
138 <xEXPR,xVAR>{DIGIT}+"."{DIGIT}+[eE]["+""-"]?{DIGIT}+ {
139 yylval.floatval = atof(yytext);
149 yylval.str = mcnstrdup(lexContext, yytext, yyleng);
155 return INCLUDE_CLOSE;
162 <xVAR,xINCLUDE,xEXPR,xCOMMENT>\n+ ;
164 <xVAR,xINCLUDE,xEXPR,xCOMMENT>[\r\t ]+ ;
168 <xVAR,xINCLUDE,xEXPR>. {
169 return yyerror("Syntax error in template tag", yylineno);
172 <xVAR,xQUOTED,xINCLUDE,xEXPR,xCOMMENT><<EOF>> {
173 return yyerror("unterminated template tag", yylineno);
177 yylval.str = mcnstrdup(lexContext, yytext, yyleng);
181 <INITIAL>([^\<]*\<[^\&\#\@\%][^\<]*)+ {
182 yylval.str = mcnstrdup(lexContext, yytext, yyleng);
188 /* This is only needed for < just before EOF */
189 yylval.str = mcnstrdup(lexContext, yytext, yyleng);
199 typedef struct KeyWord {
205 static KeyWord keywords[] = {
206 { "H", 0, HTMLESCAPE },
207 { "U", 0, URLESCAPE },
209 { "ELSE", 0, ELSE_P },
210 { "LOOP", 0, LOOP_P },
211 { "SELF", 0, SELF_P },
212 { "ELSIF", 0, ELSIF_P },
213 { "ENDIF", 0, ENDIF_P },
214 { "ENDLOOP", 0, ENDLOOP_P }
218 startTemplateLex(Template tmpl, FILE *in) {
219 if ( keywords->len == 0 ) {
221 for(i=0; i<sizeof(keywords)/sizeof(KeyWord);i++)
222 keywords[i].len = strlen(keywords[i].word);
225 lexContext = tmpl->templateContext;
233 getIdent(char *word) {
234 int len = strlen(word);
237 if ( len > keywords[ sizeof(keywords)/sizeof(KeyWord)-1 ].len )
240 for(i=0; i<sizeof(keywords)/sizeof(KeyWord) && len >= keywords[i].len; i++)
241 if ( len == keywords[i].len && strcasecmp(word, keywords[i].word) == 0 )
242 return keywords[i].id;
248 yyerror(char *s, int line) {
250 tlog(TL_CRIT,"template error at line %d in '%s': %s", line, fileToParse, s);
256 addstring(char *s, int l) {
257 while( length + l + 1 >= total ) {
259 strbuf=mcrealloc(strbuf, total);
262 memcpy( strbuf+length, s, l);
264 strbuf[length] = '\0';
269 if( length + 2 >= total ) {
271 strbuf=mcrealloc(strbuf, total);
274 strbuf[ length++ ] = s;
275 strbuf[length] = '\0';