0a284a4a45342d04308a7dfb58a33642b435d2c6
[obnox/wireshark/wip.git] / plugins / mate / mate_parser.l
1 /*
2  * We don't use unput, so don't generate code for it.
3  */
4 %option nounput 
5
6 /*
7  * We don't read from the terminal.
8  */
9 %option never-interactive
10
11 /*
12  * Prefix scanner routines with "Mate" rather than "yy", so this scanner
13  * can coexist with other scanners.
14  */
15 %option prefix="Mate"
16
17 %{
18
19         /* mate_parser.l
20         * lexical analyzer for MATE configuration files
21         *
22         * Copyright 2004, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
23         *
24         * $Id$
25         *
26         * Wireshark - Network traffic analyzer
27         * By Gerald Combs <gerald@wireshark.org>
28         * Copyright 1998 Gerald Combs
29         *
30         * This program is free software; you can redistribute it and/or
31         * modify it under the terms of the GNU General Public License
32         * as published by the Free Software Foundation; either version 2
33         * of the License, or (at your option) any later version.
34         * 
35         * This program is distributed in the hope that it will be useful,
36         * but WITHOUT ANY WARRANTY; without even the implied warranty of
37         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38         * GNU General Public License for more details.
39         * 
40         * You should have received a copy of the GNU General Public License
41         * along with this program; if not, write to the Free Software
42         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
43         */
44         
45 #include <wiretap/file_util.h>
46
47 #include "mate.h"       
48 #include "mate_grammar.h"
49 #include "mate_parser_lex.h"
50
51 #ifdef _WIN32
52 /* disable Windows VC compiler warning "signed/unsigned mismatch" associated  */
53 /* with YY_INPUT code generated by flex versions such as 2.5.35.              */
54 #pragma warning (disable:4018)
55 #endif
56
57         void MateParser(void*,int, gchar*, mate_config* matecfg);
58 #if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 16))
59         void *MateParserAlloc(void *(*)(gsize));
60 #else
61         void *MateParserAlloc(void *(*)(gulong));
62 #endif
63         void MateParserFree( void*, void(*)(void*) );
64         void MateParseTrace(FILE*,char*);
65         
66 #define MAX_INCLUDE_DEPTH 10
67         static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
68         static int include_stack_ptr = 0;
69         
70         static void* pParser;
71         static mate_config_frame* current_frame;
72         
73         static mate_config* mc;
74         
75 #define MATE_PARSE(token_type) MateParser(pParser, (token_type), g_strdup(yytext), mc );
76
77 /*
78  * Flex (v 2.5.35) uses this symbol to "exclude" unistd.h
79  */
80 #ifdef _WIN32
81 #define YY_NO_UNISTD_H
82 #endif
83
84 %}
85
86 pdu_kw                          Pdu
87 gop_kw                          Gop
88 gog_kw                          Gog
89 transform_kw            Transform
90 match_kw                        Match
91 always_kw                       Always
92 strict_kw                       Strict
93 every_kw                        Every
94 loose_kw                        Loose
95 replace_kw                      Replace
96 insert_kw                       Insert
97 gop_tree_kw                     GopTree
98 member_kw                       Member
99 on_kw                           On
100 start_kw                        Start
101 stop_kw                         Stop
102 extra_kw                        Extra
103 show_tree_kw            ShowTree
104 show_times_kw           ShowTimes
105 expiration_kw           Expiration
106 idle_timeout_kw         IdleTimeout
107 lifetime_kw                     Lifetime
108 no_tree_kw                      NoTree
109 pdu_tree_kw                     PduTree
110 frame_tree_kw           FrameTree
111 basic_tree_kw           BasicTree
112 true_kw                         [Tt][Rr][Uu][Ee]
113 false_kw                        [Ff][Aa][Ll][Ss][Ee]
114 proto_kw                        Proto
115 payload_kw          Payload
116 transport_kw            Transport
117 criteria_kw                     Criteria
118 accept_kw                       Accept
119 reject_kw                       Reject
120 extract_kw                      Extract
121 from_kw                         From
122 drop_unassigned_kw  DropUnassigned
123 discard_pdu_data_kw DiscardPduData
124 last_pdu_kw                     LastPdu
125 done_kw                         Done
126 filename_kw         Filename
127 debug_kw            Debug
128 level_kw            Level
129 default_kw          Default
130
131
132 open_parens                     "("
133 close_parens            ")"
134 open_brace                      "{"
135 close_brace                     "}"
136 comma                           ","
137 semicolon                       ";"
138 slash                           "/"
139 pipe                            "|"
140
141 integer                         [0-9]+
142 floating                        ([0-9]+\.[0-9]+)
143 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]?
144 colonized                       [0-9A-Fa-f:]*[:][0-9A-Fa-f:]*
145
146 name                            [a-z][-\.a-zA-Z0-9_]*
147 avp_operator            [$^~=<>!]
148 quote                           ["]
149 not_quoted                      [^"]*
150
151 include                 "#include"
152 filename                [-A-Za-z0-9_/.]+
153
154 whitespace              [[:blank:]\r]+
155 newline                 \n
156
157 comment                 "//"[^\n]*\n
158
159 blk_cmnt_start  "/*"
160 cmnt_char               .
161 blk_cmnt_stop  "*/"
162  
163 %START OUTSIDE QUOTED INCLUDING COMMENT
164 %%
165
166 {newline}                                               current_frame->linenum++; 
167 {whitespace}                                    ;
168
169 <OUTSIDE>{include}                                      BEGIN INCLUDING;
170
171 <INCLUDING>{filename}                   {
172         if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
173                 g_error("dtd_preparse: include files nested to deeply");
174         
175         include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
176         yyin = eth_fopen( yytext, "r" );
177
178         if (!yyin) {
179                 yy_delete_buffer( YY_CURRENT_BUFFER );
180                 
181                 /* coverity[negative_sink] */
182                 yy_switch_to_buffer(include_stack[--include_stack_ptr] );
183                 
184                 if (errno)
185                         g_string_append_printf(mc->config_error, "Mate parser: Could not open file: '%s': %s", yytext, strerror(errno) );
186                 
187         } else {
188                 
189                 current_frame = g_malloc(sizeof(mate_config_frame));
190                 current_frame->filename = g_strdup(yytext);
191                 current_frame->linenum = 1;
192                 
193                 g_ptr_array_add(mc->config_stack,current_frame);
194
195                 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
196         }
197         
198         BEGIN OUTSIDE;
199 }
200
201 <<EOF>> {       
202         /* coverity[check_after_sink] */
203         if ( --include_stack_ptr < 0 ) {
204                 yyterminate();
205         } else {
206                 yy_delete_buffer( YY_CURRENT_BUFFER );
207                 yy_switch_to_buffer( include_stack[include_stack_ptr] );
208                 
209                 g_free(current_frame->filename);
210                 g_free(current_frame);
211                 current_frame = g_ptr_array_remove_index(mc->config_stack,mc->config_stack->len-1);
212         }
213 }                               
214
215 <OUTSIDE>{comment}                                      ;
216
217 <OUTSIDE>{blk_cmnt_start}                       BEGIN COMMENT;
218 <COMMENT>{cmnt_char}                    ;
219 <COMMENT>{blk_cmnt_stop}                BEGIN OUTSIDE;
220
221 <OUTSIDE>{pdu_kw}                                       MATE_PARSE(TOKEN_PDU_KW);
222 <OUTSIDE>{gop_kw}                                       MATE_PARSE(TOKEN_GOP_KW);
223 <OUTSIDE>{gog_kw}                                       MATE_PARSE(TOKEN_GOG_KW);
224 <OUTSIDE>{transform_kw}                         MATE_PARSE(TOKEN_TRANSFORM_KW);
225 <OUTSIDE>{match_kw}                                     MATE_PARSE(TOKEN_MATCH_KW);
226 <OUTSIDE>{strict_kw}                            MATE_PARSE(TOKEN_STRICT_KW);
227 <OUTSIDE>{every_kw}                                     MATE_PARSE(TOKEN_EVERY_KW);
228 <OUTSIDE>{loose_kw}                                     MATE_PARSE(TOKEN_LOOSE_KW);
229 <OUTSIDE>{replace_kw}                           MATE_PARSE(TOKEN_REPLACE_KW);
230 <OUTSIDE>{insert_kw}                            MATE_PARSE(TOKEN_INSERT_KW);
231 <OUTSIDE>{gop_tree_kw}                          MATE_PARSE(TOKEN_GOP_TREE_KW);
232 <OUTSIDE>{member_kw}                            MATE_PARSE(TOKEN_MEMBER_KW);
233 <OUTSIDE>{on_kw}                                        MATE_PARSE(TOKEN_ON_KW);
234 <OUTSIDE>{start_kw}                                     MATE_PARSE(TOKEN_START_KW);
235 <OUTSIDE>{stop_kw}                                      MATE_PARSE(TOKEN_STOP_KW);
236 <OUTSIDE>{extra_kw}                                     MATE_PARSE(TOKEN_EXTRA_KW);
237 <OUTSIDE>{show_tree_kw}                         MATE_PARSE(TOKEN_SHOW_TREE_KW);
238 <OUTSIDE>{show_times_kw}                        MATE_PARSE(TOKEN_SHOW_TIMES_KW);
239 <OUTSIDE>{expiration_kw}                        MATE_PARSE(TOKEN_EXPIRATION_KW);
240 <OUTSIDE>{idle_timeout_kw}                      MATE_PARSE(TOKEN_IDLE_TIMEOUT_KW);
241 <OUTSIDE>{lifetime_kw}                          MATE_PARSE(TOKEN_LIFETIME_KW);
242 <OUTSIDE>{no_tree_kw}                           MATE_PARSE(TOKEN_NO_TREE_KW);
243 <OUTSIDE>{pdu_tree_kw}                          MATE_PARSE(TOKEN_PDU_TREE_KW);
244 <OUTSIDE>{frame_tree_kw}                        MATE_PARSE(TOKEN_FRAME_TREE_KW);
245 <OUTSIDE>{basic_tree_kw}                        MATE_PARSE(TOKEN_BASIC_TREE_KW);
246 <OUTSIDE>{true_kw}                                      MATE_PARSE(TOKEN_TRUE_KW);
247 <OUTSIDE>{false_kw}                                     MATE_PARSE(TOKEN_FALSE_KW);
248 <OUTSIDE>{proto_kw}                                     MATE_PARSE(TOKEN_PROTO_KW);
249 <OUTSIDE>{payload_kw}                           MATE_PARSE(TOKEN_PAYLOAD_KW);
250 <OUTSIDE>{transport_kw}                         MATE_PARSE(TOKEN_TRANSPORT_KW);
251 <OUTSIDE>{criteria_kw}                          MATE_PARSE(TOKEN_CRITERIA_KW);
252 <OUTSIDE>{accept_kw}                            MATE_PARSE(TOKEN_ACCEPT_KW);
253 <OUTSIDE>{reject_kw}                            MATE_PARSE(TOKEN_REJECT_KW);
254 <OUTSIDE>{extract_kw}                           MATE_PARSE(TOKEN_EXTRACT_KW);
255 <OUTSIDE>{from_kw}                                      MATE_PARSE(TOKEN_FROM_KW);
256 <OUTSIDE>{drop_unassigned_kw}           MATE_PARSE(TOKEN_DROP_UNASSIGNED_KW);
257 <OUTSIDE>{discard_pdu_data_kw}          MATE_PARSE(TOKEN_DISCARD_PDU_DATA_KW);
258 <OUTSIDE>{last_pdu_kw}                          MATE_PARSE(TOKEN_LAST_PDU_KW);
259 <OUTSIDE>{done_kw}                                      MATE_PARSE(TOKEN_DONE_KW);
260 <OUTSIDE>{filename_kw}                          MATE_PARSE(TOKEN_FILENAME_KW);
261 <OUTSIDE>{debug_kw}                                     MATE_PARSE(TOKEN_DEBUG_KW);
262 <OUTSIDE>{level_kw}                                     MATE_PARSE(TOKEN_LEVEL_KW);
263 <OUTSIDE>{default_kw}                           MATE_PARSE(TOKEN_DEFAULT_KW);
264
265 <OUTSIDE>{open_parens}                          MATE_PARSE(TOKEN_OPEN_PARENS);
266 <OUTSIDE>{close_parens}                         MATE_PARSE(TOKEN_CLOSE_PARENS);
267 <OUTSIDE>{open_brace}                           MATE_PARSE(TOKEN_OPEN_BRACE);
268 <OUTSIDE>{close_brace}                          MATE_PARSE(TOKEN_CLOSE_BRACE);
269 <OUTSIDE>{comma}                                        MATE_PARSE(TOKEN_COMMA);
270 <OUTSIDE>{semicolon}                            MATE_PARSE(TOKEN_SEMICOLON);
271 <OUTSIDE>{slash}                                        MATE_PARSE(TOKEN_SLASH);
272 <OUTSIDE>{pipe}                                         MATE_PARSE(TOKEN_PIPE);
273
274 <OUTSIDE>{integer}                                      MATE_PARSE(TOKEN_INTEGER);
275 <OUTSIDE>{floating}                                     MATE_PARSE(TOKEN_FLOATING);
276 <OUTSIDE>{doted_ip}                                     MATE_PARSE(TOKEN_DOTED_IP);
277 <OUTSIDE>{colonized}                            MATE_PARSE(TOKEN_COLONIZED);
278 <OUTSIDE>{name}                                         MATE_PARSE(TOKEN_NAME);
279 <OUTSIDE>{avp_operator}                         MATE_PARSE(TOKEN_AVP_OPERATOR);
280
281
282 <OUTSIDE>{quote}                                        BEGIN QUOTED;
283 <QUOTED>{not_quoted}                    MATE_PARSE(TOKEN_QUOTED);
284 <QUOTED>{quote}                                 BEGIN OUTSIDE;
285
286 %%
287
288 extern gboolean mate_load_config(const gchar* filename, mate_config* matecfg) {
289         volatile gboolean state = TRUE;
290         mc = matecfg;
291
292         yyin = eth_fopen(filename,"r");
293         
294         if (!yyin) {
295                 g_string_append_printf(mc->config_error,"Mate parser: Could not open file: '%s', error: %s", filename, strerror(errno) );
296                 return FALSE;
297         }
298         
299         mc->config_stack = g_ptr_array_new();
300         
301         current_frame = g_malloc(sizeof(mate_config_frame));
302         current_frame->filename = g_strdup(filename);
303         current_frame->linenum = 1;
304         
305         g_ptr_array_add(mc->config_stack,current_frame);
306
307         pParser = MateParserAlloc(g_malloc);
308         
309         /* MateParserTrace(stdout,""); */
310         
311         TRY {
312                 BEGIN OUTSIDE;
313
314                 yylex();
315
316                 MateParser(pParser, 0, NULL,mc);
317
318                 yyrestart(NULL);
319         
320                 MateParserFree(pParser, g_free );
321         
322                 g_free(current_frame->filename);
323                 g_free(current_frame);
324         
325                 g_ptr_array_free(mc->config_stack,FALSE);
326         } CATCH(MateConfigError) {
327                 state = FALSE;
328         } CATCH_ALL {
329                 state = FALSE;          
330                 g_string_append_printf(mc->config_error,"An unexpected error occurred");
331         }
332         ENDTRY;
333         
334         return state;
335 }
336
337 /*
338  * We want to stop processing when we get to the end of the input.
339  * (%option noyywrap is not used because if used then 
340  * some flex versions (eg: 2.5.35) generate code which causes
341  * warnings by the Windows VC compiler).
342  */
343
344 int yywrap(void) {
345     return 1;
346 }