2 /* Include this before everything else, for various large-file definitions */
4 /* Include this before everything else, as it declares functions used here. */
9 * We want a reentrant scanner.
14 * We don't use input, so don't generate code for it.
19 * We don't use unput, so don't generate code for it.
24 * We don't read interactively from the terminal.
26 %option never-interactive
29 * We want to stop processing when we get to the end of the input.
34 * The type for the state we keep for a scanner.
36 %option extra-type="Mate_scanner_state_t *"
39 * We have to override the memory allocators so that we don't get
40 * "unused argument" warnings from the yyscanner argument (which
41 * we don't use, as we have a global memory allocator).
43 * We provide, as macros, our own versions of the routines generated by Flex,
44 * which just call malloc()/realloc()/free() (as the Flex versions do),
45 * discarding the extra argument.
52 * Prefix scanner routines with "Mate_" rather than "yy", so this scanner
53 * can coexist with other scanners.
55 %option prefix="Mate_"
60 * lexical analyzer for MATE configuration files
62 * Copyright 2004, Luis E. Garcia Ontanon <luis@ontanon.org>
64 * Wireshark - Network traffic analyzer
65 * By Gerald Combs <gerald@wireshark.org>
66 * Copyright 1998 Gerald Combs
68 * This program is free software; you can redistribute it and/or
69 * modify it under the terms of the GNU General Public License
70 * as published by the Free Software Foundation; either version 2
71 * of the License, or (at your option) any later version.
73 * This program is distributed in the hope that it will be useful,
74 * but WITHOUT ANY WARRANTY; without even the implied warranty of
75 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76 * GNU General Public License for more details.
78 * You should have received a copy of the GNU General Public License
79 * along with this program; if not, write to the Free Software
80 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
83 #include "mate_grammar.h"
85 #include <wsutil/file_util.h>
88 * Disable diagnostics in the code generated by Flex.
92 void MateParseTrace(FILE*,char*);
94 #define MAX_INCLUDE_DEPTH 10
98 mate_config_frame* current_frame;
102 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
103 int include_stack_ptr;
104 } Mate_scanner_state_t;
106 #define MATE_PARSE(token_type) MateParser(yyextra->pParser, (token_type), g_strdup(yytext), yyextra->mc);
109 * Flex (v 2.5.35) uses this symbol to "exclude" unistd.h
112 #define YY_NO_UNISTD_H
115 static void free_config_frame(mate_config_frame *frame) {
116 g_free(frame->filename);
120 #define YY_USER_INIT BEGIN OUTSIDE;
123 * Sleazy hack to suppress compiler warnings in yy_fatal_error().
125 #define YY_EXIT_FAILURE ((void)yyscanner, 2)
128 * Macros for the allocators, to discard the extra argument.
130 #define Mate_alloc(size, yyscanner) (void *)malloc(size)
131 #define Mate_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
132 #define Mate_free(ptr, yyscanner) free((char *)ptr)
139 transform_kw Transform
153 show_tree_kw ShowTree
154 show_times_kw ShowTimes
155 expiration_kw Expiration
156 idle_timeout_kw IdleTimeout
160 frame_tree_kw FrameTree
161 basic_tree_kw BasicTree
162 true_kw [Tt][Rr][Uu][Ee]
163 false_kw [Ff][Aa][Ll][Ss][Ee]
166 transport_kw Transport
172 drop_unassigned_kw DropUnassigned
173 discard_pdu_data_kw DiscardPduData
192 floating ([0-9]+\.[0-9]+)
193 doted_ip [0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?
194 colonized [0-9A-Fa-f:]*[:][0-9A-Fa-f:]*
196 name [a-z][-\.a-zA-Z0-9_]*
197 avp_operator [$^~=<>!]
202 filename [-A-Za-z0-9_/.]+
204 whitespace [[:blank:]\r]+
213 %START OUTSIDE QUOTED INCLUDING COMMENT
216 {newline} yyextra->current_frame->linenum++;
219 <OUTSIDE>{include} BEGIN INCLUDING;
221 <INCLUDING>{filename} {
222 if ( yyextra->include_stack_ptr >= MAX_INCLUDE_DEPTH )
223 ws_error("dtd_preparse: include files nested too deeply");
225 yyextra->include_stack[yyextra->include_stack_ptr++] = YY_CURRENT_BUFFER;
226 yyin = ws_fopen( yytext, "r" );
229 Mate__delete_buffer(YY_CURRENT_BUFFER, yyscanner);
231 /* coverity[negative_sink] */
232 Mate__switch_to_buffer(yyextra->include_stack[--yyextra->include_stack_ptr], yyscanner);
235 g_string_append_printf(yyextra->mc->config_error, "Mate parser: Could not open file: '%s': %s", yytext, g_strerror(errno) );
239 yyextra->current_frame = g_new(mate_config_frame, 1);
240 yyextra->current_frame->filename = g_strdup(yytext);
241 yyextra->current_frame->linenum = 1;
243 g_ptr_array_add(yyextra->mc->config_stack,yyextra->current_frame);
245 Mate__switch_to_buffer(Mate__create_buffer(yyin, YY_BUF_SIZE, yyscanner), yyscanner);
252 /* coverity[check_after_sink] */
253 if ( --yyextra->include_stack_ptr < 0 ) {
256 Mate__delete_buffer(YY_CURRENT_BUFFER, yyscanner);
257 Mate__switch_to_buffer(yyextra->include_stack[yyextra->include_stack_ptr], yyscanner);
259 free_config_frame(yyextra->current_frame);
260 yyextra->current_frame = (mate_config_frame *)g_ptr_array_remove_index(yyextra->mc->config_stack,yyextra->mc->config_stack->len-1);
264 <OUTSIDE>{comment} yyextra->current_frame->linenum++;
266 <OUTSIDE>{blk_cmnt_start} BEGIN COMMENT;
267 <COMMENT>{cmnt_char} ;
268 <COMMENT>{blk_cmnt_stop} BEGIN OUTSIDE;
270 <OUTSIDE>{pdu_kw} MATE_PARSE(TOKEN_PDU_KW);
271 <OUTSIDE>{gop_kw} MATE_PARSE(TOKEN_GOP_KW);
272 <OUTSIDE>{gog_kw} MATE_PARSE(TOKEN_GOG_KW);
273 <OUTSIDE>{transform_kw} MATE_PARSE(TOKEN_TRANSFORM_KW);
274 <OUTSIDE>{match_kw} MATE_PARSE(TOKEN_MATCH_KW);
275 <OUTSIDE>{strict_kw} MATE_PARSE(TOKEN_STRICT_KW);
276 <OUTSIDE>{every_kw} MATE_PARSE(TOKEN_EVERY_KW);
277 <OUTSIDE>{loose_kw} MATE_PARSE(TOKEN_LOOSE_KW);
278 <OUTSIDE>{replace_kw} MATE_PARSE(TOKEN_REPLACE_KW);
279 <OUTSIDE>{insert_kw} MATE_PARSE(TOKEN_INSERT_KW);
280 <OUTSIDE>{gop_tree_kw} MATE_PARSE(TOKEN_GOP_TREE_KW);
281 <OUTSIDE>{member_kw} MATE_PARSE(TOKEN_MEMBER_KW);
282 <OUTSIDE>{on_kw} MATE_PARSE(TOKEN_ON_KW);
283 <OUTSIDE>{start_kw} MATE_PARSE(TOKEN_START_KW);
284 <OUTSIDE>{stop_kw} MATE_PARSE(TOKEN_STOP_KW);
285 <OUTSIDE>{extra_kw} MATE_PARSE(TOKEN_EXTRA_KW);
286 <OUTSIDE>{show_tree_kw} MATE_PARSE(TOKEN_SHOW_TREE_KW);
287 <OUTSIDE>{show_times_kw} MATE_PARSE(TOKEN_SHOW_TIMES_KW);
288 <OUTSIDE>{expiration_kw} MATE_PARSE(TOKEN_EXPIRATION_KW);
289 <OUTSIDE>{idle_timeout_kw} MATE_PARSE(TOKEN_IDLE_TIMEOUT_KW);
290 <OUTSIDE>{lifetime_kw} MATE_PARSE(TOKEN_LIFETIME_KW);
291 <OUTSIDE>{no_tree_kw} MATE_PARSE(TOKEN_NO_TREE_KW);
292 <OUTSIDE>{pdu_tree_kw} MATE_PARSE(TOKEN_PDU_TREE_KW);
293 <OUTSIDE>{frame_tree_kw} MATE_PARSE(TOKEN_FRAME_TREE_KW);
294 <OUTSIDE>{basic_tree_kw} MATE_PARSE(TOKEN_BASIC_TREE_KW);
295 <OUTSIDE>{true_kw} MATE_PARSE(TOKEN_TRUE_KW);
296 <OUTSIDE>{false_kw} MATE_PARSE(TOKEN_FALSE_KW);
297 <OUTSIDE>{proto_kw} MATE_PARSE(TOKEN_PROTO_KW);
298 <OUTSIDE>{payload_kw} MATE_PARSE(TOKEN_PAYLOAD_KW);
299 <OUTSIDE>{transport_kw} MATE_PARSE(TOKEN_TRANSPORT_KW);
300 <OUTSIDE>{criteria_kw} MATE_PARSE(TOKEN_CRITERIA_KW);
301 <OUTSIDE>{accept_kw} MATE_PARSE(TOKEN_ACCEPT_KW);
302 <OUTSIDE>{reject_kw} MATE_PARSE(TOKEN_REJECT_KW);
303 <OUTSIDE>{extract_kw} MATE_PARSE(TOKEN_EXTRACT_KW);
304 <OUTSIDE>{from_kw} MATE_PARSE(TOKEN_FROM_KW);
305 <OUTSIDE>{drop_unassigned_kw} MATE_PARSE(TOKEN_DROP_UNASSIGNED_KW);
306 <OUTSIDE>{discard_pdu_data_kw} MATE_PARSE(TOKEN_DISCARD_PDU_DATA_KW);
307 <OUTSIDE>{last_pdu_kw} MATE_PARSE(TOKEN_LAST_PDU_KW);
308 <OUTSIDE>{done_kw} MATE_PARSE(TOKEN_DONE_KW);
309 <OUTSIDE>{filename_kw} MATE_PARSE(TOKEN_FILENAME_KW);
310 <OUTSIDE>{debug_kw} MATE_PARSE(TOKEN_DEBUG_KW);
311 <OUTSIDE>{level_kw} MATE_PARSE(TOKEN_LEVEL_KW);
312 <OUTSIDE>{default_kw} MATE_PARSE(TOKEN_DEFAULT_KW);
314 <OUTSIDE>{open_parens} MATE_PARSE(TOKEN_OPEN_PARENS);
315 <OUTSIDE>{close_parens} MATE_PARSE(TOKEN_CLOSE_PARENS);
316 <OUTSIDE>{open_brace} MATE_PARSE(TOKEN_OPEN_BRACE);
317 <OUTSIDE>{close_brace} MATE_PARSE(TOKEN_CLOSE_BRACE);
318 <OUTSIDE>{comma} MATE_PARSE(TOKEN_COMMA);
319 <OUTSIDE>{semicolon} MATE_PARSE(TOKEN_SEMICOLON);
320 <OUTSIDE>{slash} MATE_PARSE(TOKEN_SLASH);
321 <OUTSIDE>{pipe} MATE_PARSE(TOKEN_PIPE);
323 <OUTSIDE>{integer} MATE_PARSE(TOKEN_INTEGER);
324 <OUTSIDE>{floating} MATE_PARSE(TOKEN_FLOATING);
325 <OUTSIDE>{doted_ip} MATE_PARSE(TOKEN_DOTED_IP);
326 <OUTSIDE>{colonized} MATE_PARSE(TOKEN_COLONIZED);
327 <OUTSIDE>{name} MATE_PARSE(TOKEN_NAME);
328 <OUTSIDE>{avp_operator} MATE_PARSE(TOKEN_AVP_OPERATOR);
331 <OUTSIDE>{quote} BEGIN QUOTED;
332 <QUOTED>{not_quoted} MATE_PARSE(TOKEN_QUOTED);
333 <QUOTED>{quote} BEGIN OUTSIDE;
338 * Turn diagnostics back on, so we check the code that we've written.
342 static void ptr_array_free(void *data, void *user_data _U_)
344 free_config_frame((mate_config_frame *)data);
347 extern bool mate_load_config(const char* filename, mate_config* mc) {
350 Mate_scanner_state_t state;
351 volatile bool status = true;
353 in = ws_fopen(filename,"r");
356 g_string_append_printf(mc->config_error,"Mate parser: Could not open file: '%s', error: %s", filename, g_strerror(errno) );
360 if (Mate_lex_init(&scanner) != 0) {
361 g_string_append_printf(mc->config_error, "Mate parse: Could not initialize scanner: %s", g_strerror(errno));
366 Mate_set_in(in, scanner);
368 mc->config_stack = g_ptr_array_new();
372 state.current_frame = g_new(mate_config_frame, 1);
373 state.current_frame->filename = g_strdup(filename);
374 state.current_frame->linenum = 1;
376 g_ptr_array_add(mc->config_stack,state.current_frame);
378 state.pParser = MateParserAlloc(g_malloc);
380 state.include_stack_ptr = 0;
382 /* Associate the state with the scanner */
383 Mate_set_extra(&state, scanner);
385 /* MateParserTrace(stdout,""); */
390 /* Inform parser that end of input has reached. */
391 MateParser(state.pParser, 0, NULL, mc);
393 MateParserFree(state.pParser, g_free);
394 } CATCH(MateConfigError) {
398 g_string_append_printf(mc->config_error,"An unexpected error occurred");
402 Mate_lex_destroy(scanner);
405 g_ptr_array_foreach(mc->config_stack, ptr_array_free, NULL);
406 g_ptr_array_free(mc->config_stack, true);