1 C	[^\n\t ]
2 
3 L	[a-zA-Z���������0-9_%]
4 G	[a-zA-Z0-9]
5 V	[a-zA-Z_]+[a-zA-Z0-9_]*
6 E	[\ ]*"="[\ ]*
7 
8 %{
9 
10 #define YYDEBUG 1
11 
12 /*
13  * AIDE (Advanced Intrusion Detection Environment)
14  *
15  * Copyright (C) 1999-2002, 2004-2006, 2010-2013, 2015-2016, 2019-2021
16  *               Rami Lehti, Pablo Virolainen, Richard van den Berg,
17  *               Hannes von Haugwitz
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License as
21  * published by the Free Software Foundation; either version 2 of the
22  * License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful, but
25  * WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27  * General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along
30  * with this program; if not, write to the Free Software Foundation, Inc.,
31  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32  */
33 
34 #include "aide.h"
35 #include <string.h>
36 #include <stdlib.h>
37 #include "gen_list.h"
38 #include "util.h"
ThreadParamsbase::__anonb666fa2f0111::ThreadParams39 #include "conf_yacc.h"
40 #include "list.h"
41 #include "errorcodes.h"
42 #include "symboltable.h"
43 #include "commandconf.h"
44 
45 #include "conf_ast.h"
46 
47 #define LOG_LEX_TOKEN(log_level, token, text) \
48     log_msg(log_level, "%s:%d: \u2502 " #token " (text: '%s')", conf_filename, conf_linenumber, text);
49 
50 #define LOG_CONFIG_LINE(log_level, msg) \
51      log_msg(log_level, "%s:%d: %s (line: '%s')", conf_filename, conf_linenumber, msg, conf_linebuf);
52 
53 #define DEPRECATION_WARNING(deprecated_option, new_option) \
54      log_msg(LOG_LEVEL_WARNING, "%s:%d: Using '%s' is DEPRECATED. Update your config and use '%s' instead (line: '%s')", conf_filename, conf_linenumber, deprecated_option, new_option ,conf_linebuf); \
55 
56 int conf_linenumber = 0;
57 char *conf_filename;
58 char *conf_linebuf;
59 
60 LOG_LEVEL lex_log_level = LOG_LEVEL_CONFIG;
61 
62 #define YY_INPUT(buf,result,max_size) \
63         if( ((result=conf_input_wrapper(buf,max_size,confin)) == 0) \
64             && ferror(yyin) ) \
65           YY_FATAL_ERROR( "input in flex scanner failed" );
66 
67 %}
68 
69 %option noinput nounput
70 
71 %x CONFIG DEFSTMT ENVVAR EXPR EXPREQUHUNT PATH STRING STRINGS STRINGEQHUNT STRINGHUNT
72 
73 %%
74 <INITIAL>^[\t\ ]*"#"[^\n]*"\n" {
75             conf_linebuf = checked_strndup(conftext, confleng-1);
76             ++conf_linenumber;
CreateThread(size_t stack_size,bool joinable,PlatformThread::Delegate * delegate,PlatformThreadHandle * thread_handle,ThreadPriority priority)77             LOG_CONFIG_LINE(lex_log_level, "- skip comment line")
78             free(conf_linebuf);
79            }
80 <INITIAL>^[\t\ ]*"\n" {
81             conf_linebuf = "";
82             ++conf_linenumber;
83             LOG_CONFIG_LINE(lex_log_level, "- skip empty line")
84            }
85 <INITIAL>^[^\n]* {
86             conf_linebuf = checked_strndup(conftext, confleng);
87             ++conf_linenumber;
88             log_msg(lex_log_level,"%s:%d: \u252c '%s'", conf_filename, conf_linenumber, conf_linebuf);
89             yyless(0);
90             BEGIN(CONFIG);
91            }
92 <CONFIG>"#"[^\n]* { /* inline comment */
93   LOG_LEX_TOKEN(lex_log_level, skip inline comment, conftext)
94  }
95 
96 <CONFIG>"=/" {
97   LOG_LEX_TOKEN(lex_log_level, TEQURXRULE, "=")
98   yyless(strchr(conftext,'/')-conftext);
99   BEGIN(PATH);
100   return (TEQURXRULE);
101 }
102 
103 <CONFIG>"/" {
104   LOG_LEX_TOKEN(lex_log_level, TSELRXRULE, "")
105   yyless(strchr(conftext,'/')-conftext);
106   BEGIN(PATH);
107   return (TSELRXRULE);
108 }
109 
110 <CONFIG>"!/" {
111   LOG_LEX_TOKEN(lex_log_level, TNEGRXRULE, "!")
112   yyless(strchr(conftext,'/')-conftext);
113   BEGIN(PATH);
114   return (TNEGRXRULE);
115 }
116 
117 <EXPREQUHUNT>{E} {
118   LOG_LEX_TOKEN(lex_log_level, '=', conftext)
119   BEGIN(EXPR);
120   return('=');
121 }
122 
123 <EXPR>({L}|">")+ {
124   LOG_LEX_TOKEN(lex_log_level, TEXPR, conftext)
125   conflval.s=checked_strdup(conftext);
126   return (TEXPR);
CurrentId()127 }
128 
129 <EXPR>\+ { /* attribute operator */
130   LOG_LEX_TOKEN(lex_log_level, '+', conftext)
131   return ('+');
132 }
133 
134 <EXPR>\- { /* attribute operator */
135   LOG_LEX_TOKEN(lex_log_level, '-', conftext)
136   return ('-');
137 }
138 
139 <EXPR>, { /* restriction seperator */
140   LOG_LEX_TOKEN(lex_log_level, ',', conftext)
141   return (',');
142 }
143 
144 <DEFSTMT>({L})+ {
145   LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conftext)
146   conflval.s=checked_strdup(conftext);
147   BEGIN(STRINGHUNT);
148   return (TVARIABLE);
CurrentRef()149 }
150 
151 <CONFIG>"\@\@define" {
152   LOG_LEX_TOKEN(lex_log_level, TDEFINE, conftext)
153   BEGIN DEFSTMT;
154   return (TDEFINE);
155 }
156 
157 <CONFIG>"\@\@undef" {
158   LOG_LEX_TOKEN(lex_log_level, TUNDEFINE, conftext)
YieldCurrentThread()159   BEGIN DEFSTMT;
160   return (TUNDEFINE);
161 }
162 
163 <CONFIG>"\@\@ifdef" {
Sleep(TimeDelta duration)164   LOG_LEX_TOKEN(lex_log_level, TIFDEF, conftext)
165   BEGIN(STRINGHUNT);
166   return (TIFDEF);
167 }
168 
169 <CONFIG>"\@\@ifndef" {
170   LOG_LEX_TOKEN(lex_log_level, TIFNDEF, conftext)
171   BEGIN(STRINGHUNT);
172   return (TIFNDEF);
173 }
174 
175 <CONFIG>"\@\@else" {
176   LOG_LEX_TOKEN(lex_log_level, TELSE, conftext)
177   BEGIN CONFIG;
178   return (TELSE);
GetName()179 }
180 
181 <CONFIG>"\@\@endif" {
182   LOG_LEX_TOKEN(lex_log_level, TENDIF, conftext)
183   BEGIN CONFIG;
184   return (TENDIF);
185 }
186 
187 <CONFIG>"\@\@ifhost" {
188   LOG_LEX_TOKEN(lex_log_level, TIFHOST, conftext)
189   BEGIN(STRINGHUNT);
190   return (TIFHOST);
191 }
CreateNonJoinable(size_t stack_size,Delegate * delegate)192 
193 <CONFIG>"\@\@ifnhost" {
194   LOG_LEX_TOKEN(lex_log_level, TIFNHOST, conftext)
195   BEGIN(STRINGHUNT);
196   return (TIFNHOST);
197 }
198 
199 <CONFIG>"\@\@include" {
200   LOG_LEX_TOKEN(lex_log_level, TINCLUDE, conftext)
Join(PlatformThreadHandle thread_handle)201   BEGIN(STRINGS);
202   return (TINCLUDE);
203 }
204 
205 <CONFIG>"\@\@x_include" {
206   LOG_LEX_TOKEN(lex_log_level, TXINCLUDE, conftext)
207   BEGIN(STRINGS);
208   return (TXINCLUDE);
209 }
210 
211 <CONFIG>"\@\@x_include_setenv" {
212   LOG_LEX_TOKEN(lex_log_level, TSETENV, conftext)
SetCurrentThreadPriority(ThreadPriority priority)213   BEGIN ENVVAR;
214   return (TSETENV);
215 }
216 
217 <ENVVAR>({V})+ {
218   LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conftext)
219   conflval.s=checked_strdup(conftext);
220   BEGIN(STRINGHUNT);
221   return (TVARIABLE);
222 }
223 
224 <CONFIG,DEFSTMT,ENVVAR,EXPR>[\t\ ]+ {
225     LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
226 }
227 
228 <CONFIG>"database_in" {
229   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_IN_OPTION), conftext)
230   conflval.option = DATABASE_IN_OPTION;
231   BEGIN (STRINGEQHUNT);
232   return (CONFIGOPTION);
233 }
234 
GetCurrentThreadPriority()235 <CONFIG>"database" {
236   DEPRECATION_WARNING("database", "database_in")
237   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_IN_OPTION), conftext)
238   conflval.option = DATABASE_IN_OPTION;
239   BEGIN (STRINGEQHUNT);
240   return (CONFIGOPTION);
241 }
242 
243 <CONFIG>"database_out" {
244   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_OUT_OPTION), conftext)
245   conflval.option = DATABASE_OUT_OPTION;
246   BEGIN (STRINGEQHUNT);
247   return (CONFIGOPTION);
248 }
249 
250 <CONFIG>"database_new" {
251   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_NEW_OPTION), conftext)
252   conflval.option = DATABASE_NEW_OPTION;
253   BEGIN (STRINGEQHUNT);
254   return (CONFIGOPTION);
255 }
256 
257 <CONFIG>"database_attrs" {
258   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_ATTRIBUTES_OPTION), conftext)
259   conflval.option = DATABASE_ATTRIBUTES_OPTION;
260   BEGIN (EXPREQUHUNT);
261   return (CONFIGOPTION);
262 }
263 
264 <CONFIG>"warn_dead_symlinks" {
265   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (WARN_DEAD_SYMLINKS_OPTION), conftext)
266   conflval.option = WARN_DEAD_SYMLINKS_OPTION;
267   BEGIN (STRINGEQHUNT);
268   return (CONFIGOPTION);
269 }
270 
271 <CONFIG>"grouped" {
272   DEPRECATION_WARNING("grouped", "report_grouped")
273   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_GROUPED_OPTION), conftext)
274   conflval.option = REPORT_GROUPED_OPTION;
275   BEGIN (STRINGEQHUNT);
276   return (CONFIGOPTION);
277 }
278 
279 <CONFIG>"report_grouped" {
280   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_GROUPED_OPTION), conftext)
281   conflval.option = REPORT_GROUPED_OPTION;
282   BEGIN (STRINGEQHUNT);
283   return (CONFIGOPTION);
284 }
285 
286 <CONFIG>"summarize_changes" {
287   DEPRECATION_WARNING("summarize_changes", "report_summarize_changes")
288   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_SUMMARIZE_CHANGES_OPTION), conftext)
289   conflval.option = REPORT_SUMMARIZE_CHANGES_OPTION;
290   BEGIN (STRINGEQHUNT);
291   return (CONFIGOPTION);
292 }
293 
294 <CONFIG>"report_summarize_changes" {
295   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_SUMMARIZE_CHANGES_OPTION), conftext)
296   conflval.option = REPORT_SUMMARIZE_CHANGES_OPTION;
297   BEGIN (STRINGEQHUNT);
298   return (CONFIGOPTION);
299 }
300 <CONFIG>"acl_no_symlink_follow" {
301   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (ACL_NO_SYMLINK_FOLLOW_OPTION), conftext)
302   conflval.option = ACL_NO_SYMLINK_FOLLOW_OPTION;
303   BEGIN (STRINGEQHUNT);
304   return (CONFIGOPTION);
305 }
306 
307 <CONFIG>"report_level" {
308   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_LEVEL_OPTION), conftext)
309   conflval.option = REPORT_LEVEL_OPTION;
310   BEGIN (STRINGEQHUNT);
311   return (CONFIGOPTION);
312 }
313 
314 <CONFIG>"report_ignore_added_attrs" {
315   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_ADDED_ATTRS_OPTION), conftext)
316   conflval.option = REPORT_IGNORE_ADDED_ATTRS_OPTION;
317   BEGIN (EXPREQUHUNT);
318   return (CONFIGOPTION);
319 }
320 
321 <CONFIG>"report_ignore_removed_attrs" {
322   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_REMOVED_ATTRS_OPTION), conftext)
323   conflval.option = REPORT_IGNORE_REMOVED_ATTRS_OPTION;
324   BEGIN (EXPREQUHUNT);
325   return (CONFIGOPTION);
326 }
327 
328 <CONFIG>"report_ignore_changed_attrs" {
329   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_CHANGED_ATTRS_OPTION), conftext)
330   conflval.option = REPORT_IGNORE_CHANGED_ATTRS_OPTION;
331   BEGIN (EXPREQUHUNT);
332   return (CONFIGOPTION);
333 }
334 
335 <CONFIG>"report_force_attrs" {
336   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_FORCE_ATTRS_OPTION), conftext)
337   conflval.option = REPORT_FORCE_ATTRS_OPTION;
338   BEGIN (EXPREQUHUNT);
339   return (CONFIGOPTION);
340 }
341 
342 <CONFIG>"verbose" {
343   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (VERBOSE_OPTION), conftext)
344   conflval.option = VERBOSE_OPTION;
345   BEGIN (STRINGEQHUNT);
346   return (CONFIGOPTION);
347 }
348 
349 <CONFIG>"log_level" {
350   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (LOG_LEVEL_OPTION), conftext)
351   conflval.option = LOG_LEVEL_OPTION;
352   BEGIN(STRINGEQHUNT);
353   return (CONFIGOPTION);
354 }
355 
356 <CONFIG>"database_add_metadata" {
357   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_ADD_METADATA_OPTION), conftext)
358   conflval.option = DATABASE_ADD_METADATA_OPTION;
359   BEGIN (STRINGEQHUNT);
360   return (CONFIGOPTION);
361 }
362 
363 <CONFIG>"report_url" {
364   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_URL_OPTION), conftext)
365   conflval.option = REPORT_URL_OPTION;
366   BEGIN (STRINGEQHUNT);
367   return (CONFIGOPTION);
368 }
369 
370 <CONFIG>"report_detailed_init" {
371   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_DETAILED_INIT_OPTION), conftext)
372   conflval.option = REPORT_DETAILED_INIT_OPTION;
373   BEGIN (STRINGEQHUNT);
374   return (CONFIGOPTION);
375 }
376 
377 <CONFIG>"report_base16" {
378   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_BASE16_OPTION), conftext)
379   conflval.option = REPORT_BASE16_OPTION;
380   BEGIN (STRINGEQHUNT);
381   return (CONFIGOPTION);
382 }
383 
384 <CONFIG>"report_quiet" {
385   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_QUIET_OPTION), conftext)
386   conflval.option = REPORT_QUIET_OPTION;
387   BEGIN (STRINGEQHUNT);
388   return (CONFIGOPTION);
389 }
390 
391 <CONFIG>"report_append" {
392   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_APPEND_OPTION), conftext)
393   conflval.option = REPORT_APPEND_OPTION;
394   BEGIN (STRINGEQHUNT);
395   return (CONFIGOPTION);
396 }
397 
398 <CONFIG>"report_ignore_e2fsattrs" {
399   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_E2FSATTRS_OPTION), conftext)
400   conflval.option = REPORT_IGNORE_E2FSATTRS_OPTION;
401   BEGIN (STRINGEQHUNT);
402   return (CONFIGOPTION);
403 }
404 
405 <CONFIG>"gzip_dbout" {
406   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_GZIP_OPTION), conftext)
407   conflval.option = DATABASE_GZIP_OPTION;
408   BEGIN (STRINGEQHUNT);
409   return (CONFIGOPTION);
410 }
411 
412 <CONFIG>"root_prefix" {
413   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (ROOT_PREFIX_OPTION), conftext)
414   conflval.option = ROOT_PREFIX_OPTION;
415   BEGIN (STRINGEQHUNT);
416   return (CONFIGOPTION);
417 }
418 
419 <CONFIG>"config_version" {
420   LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (CONFIG_VERSION), conftext)
421   conflval.option = CONFIG_VERSION;
422   BEGIN (STRINGEQHUNT);
423   return (CONFIGOPTION);
424 }
425 
426 <CONFIG>({G})+ { /* group definition */
427   conflval.s=checked_strdup(conftext);
428   LOG_LEX_TOKEN(lex_log_level, TGROUP, conftext)
429   BEGIN(EXPREQUHUNT);
430   return (TGROUP);
431 }
432 
433 <CONFIG>({L})+ { /* group definition, deprecated group names */
434   log_msg(LOG_LEVEL_WARNING, "%s:%d: special characters in group names are DEPRECATED. Update your config and only use alphanumeric characters (A-Za-z0-9) (line: '%s')", conf_filename, conf_linenumber, conf_linebuf); \
435   conflval.s=checked_strdup(conftext);
436   LOG_LEX_TOKEN(lex_log_level, TGROUP, conftext)
437   BEGIN(EXPREQUHUNT);
438   return (TGROUP);
439 }
440 
441 <STRINGEQHUNT>{E} {
442   LOG_LEX_TOKEN(lex_log_level, '=', conftext)
443   BEGIN(STRING);
444   return('=');
445 }
446 
447 <STRINGS,STRING,PATH>"@@{"({L}+)"}" {
448   size_t length = strlen(conftext)-4;
449   conflval.s=checked_malloc(length+1);
450   strncpy(conflval.s, conftext+3, length);
451   conflval.s[length] = '\0';
452   LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conflval.s)
453   return (TVARIABLE);
454 }
455 
456 <STRINGS,STRING,PATH>[^@\\ \t\n]+ {
457   LOG_LEX_TOKEN(lex_log_level, TSTRING, conftext)
458   conflval.s=checked_strdup(conftext);
459   return (TSTRING);
460 }
461 
462 <STRINGS,STRING,PATH>\\[\\@ ] {
463   LOG_LEX_TOKEN(lex_log_level, (escaped) TSTRING, conftext)
464   conflval.s=checked_strdup(conftext+1);
465   return (TSTRING);
466 }
467 
468 <STRINGS,STRING,PATH>[\\@] {
469   LOG_LEX_TOKEN(lex_log_level, (single-character) TSTRING, conftext)
470   conflval.s=checked_strdup(conftext);
471   return (TSTRING);
472 }
473 
474 <STRINGS>[\ \t]+ {
475   LOG_LEX_TOKEN(lex_log_level, TSPACE, conftext)
476   return (TSPACE);
477 }
478 
479 <STRING>[\ \t]+ {
480   LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
481   BEGIN(CONFIG);
482 }
483 
484 <PATH>[\ \t]+ {
485   LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
486   BEGIN(EXPR);
487 }
488 
489 <STRINGHUNT>[\ \t]+ {
490   LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
491   BEGIN(STRING);
492 }
493 
494 <STRINGHUNT>[^\ \t\n] {
495   LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, found string -> unput, conftext)
496   yyless(0);
497   BEGIN(STRING);
498 }
499 
500 <CONFIG,DEFSTMT,ENVVAR,EXPR,EXPREQUHUNT,PATH,STRINGS,STRING,STRINGEQHUNT,STRINGHUNT>[\t\ ]*"\n" {
501   log_msg(lex_log_level,"%s:%d: \u2534 TNEWLINE (text: '\\n')", conf_filename, conf_linenumber);
502   BEGIN 0;
503   return (TNEWLINE);
504 }
505 
506 <*>. {
507      log_msg(LOG_LEVEL_ERROR,"%s:%d: unexpected character: '%c' (line: '%s')", conf_filename, conf_linenumber, *conftext, conf_linebuf);
508      exit(INVALID_CONFIGURELINE_ERROR);
509 }
510 
511 %%
512 
513 int confwrap(void){
514   return 1;
515 }
516 
517 void conf_lex_string(const char * name, const char *string) {
518     log_msg(LOG_LEVEL_DEBUG, "parse: '%s'", name);
519     conf_linenumber = 0;
520     conf_filename = checked_strdup(name); /* not to be freed, needed for logging */
521     conf_scan_string(string);
522 }
523 
524 void conf_lex_file(const char * config) {
525     log_msg(LOG_LEVEL_DEBUG, "parse: '%s'", config);
526     conf_linenumber = 0;
527 
528     if (strcmp(config,"-") == 0) {
529         conf_filename = checked_strdup("(stdin)"); /* not to be freed, needed for logging */
530         confin = stdin;
531     } else {
532         conf_filename = checked_strdup(config);  /* not to be freed, needed for logging */
533         char *expanded_config = expand_tilde(checked_strdup(config));
534         confin = fopen( expanded_config, "r" );
535         if (!confin) {
536             log_msg(LOG_LEVEL_ERROR,"cannot open config file '%s': %s", config, strerror(errno));
537             exit(IO_ERROR);
538         }
539         free(expanded_config);
540         expanded_config=NULL;
541     }
542     conf_switch_to_buffer(conf_create_buffer( confin, YY_BUF_SIZE ));
543 }
544 
545 void conf_lex_delete_buffer() {
546     conf_delete_buffer( YY_CURRENT_BUFFER );
547 }
548