drsuapi_dissect_element_DsReplicaObjectIdentifier_dn parents append
[wireshark-sm.git] / plugins / epan / mate / mate_grammar.lemon
blobbef433e3d0e4b745d3fc2756a2726e7324135641
1 %include {
3 /* mate_grammar.lemon
4  * MATE's configuration language grammar
5  *
6  * Copyright 2005, Luis E. Garcia Ontanon <luis@ontanon.org>
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * SPDX-License-Identifier: GPL-2.0-or-later
13  */
16  * XXX - there's a Lemon bug where this grammar produces a parser that
17  * fails assertions; to work around it, we disable assert() failures.
18  */
19 #ifndef NDEBUG
20 #define NDEBUG
21 #endif
22 #include "config.h"
24 #include <errno.h>
26 #include "mate.h"
27 #include "mate_grammar.h"
29 #include "ws_attributes.h"
31 #include <wsutil/file_util.h>
32 #include <wsutil/str_util.h>
34 #define DUMMY void*
36 typedef struct _extraction {
37         char* as;
38         header_field_info* hfi;
39         struct _extraction* next;
40         struct _extraction* last;
41 } extraction_t;
43 typedef struct _pdu_criteria_t {
44         AVPL* criterium_avpl;
45         avpl_match_mode criterium_match_mode;
46         accept_mode_t criterium_accept_mode;
47 } pdu_criteria_t;
49 typedef struct _gop_options {
50         gop_tree_mode_t pdu_tree_mode;
51         bool drop_unassigned;
52         bool show_times;
53         double expiration;
54         double idle_timeout;
55         double lifetime;
56         AVPL* start;
57         AVPL* stop;
58         AVPL* extras;
59 } gop_options_t;
61 typedef struct _gog_statements {
62         double expiration;
63         gop_tree_mode_t gop_tree_mode;
64         GPtrArray* transform_list;
65         AVPL* extras;
66         LoAL* current_gogkeys;
67 } gog_statement_t;
69 typedef struct _transf_match_t {
70         avpl_match_mode match_mode;
71         AVPL* avpl;
72 } transf_match_t;
74 typedef struct _transf_action_t {
75         avpl_replace_mode replace_mode;
76         AVPL* avpl;
77 } transf_action_t;
79 WS_NORETURN
80 static void configuration_error(mate_config* mc, const char* fmt, ...) {
81         static char error_buffer[256];
82         const char* incl;
83         int i;
84         mate_config_frame* current_frame;
85         va_list list;
87         va_start( list, fmt );
88         vsnprintf(error_buffer,sizeof(error_buffer),fmt,list);
89         va_end( list );
91         i = (int) mc->config_stack->len;
93         while (i--) {
95                 if (i>0) {
96                         incl = "\n   included from: ";
97                 } else {
98                         incl = " ";
99                 }
101                 current_frame = (mate_config_frame *)g_ptr_array_index(mc->config_stack,(unsigned)i);
103                 g_string_append_printf(mc->config_error,"%s%s at line %u",incl, current_frame->filename, current_frame->linenum);
104         }
106         g_string_append_printf(mc->config_error,": %s\n",error_buffer);
108         THROW(MateConfigError);
112 static AVPL_Transf* new_transform_elem(AVPL* match, AVPL* replace, avpl_match_mode match_mode, avpl_replace_mode replace_mode) {
113          AVPL_Transf* t = (AVPL_Transf *)g_malloc(sizeof(AVPL_Transf));
115          t->name = NULL;
116          t->match = match;
117          t->replace = replace;
118          t->match_mode = match_mode;
119          t->replace_mode = replace_mode;
121          t->map = NULL;
122          t->next = NULL;
124          return t;
127 static char* recolonize(mate_config* mc, char* s) {
128         GString* str = g_string_new("");
129         char** vec;
130         unsigned i,v;
131         char c;
133         vec = g_strsplit(s,":",0);
135         for (i = 0; vec[i]; i++) {
136                 ascii_strdown_inplace(vec[i]);
138                 v = 0;
139                 switch ( strlen(vec[i]) ) {
140                  case 2:
141                         c = vec[i][1];
142                         vec[i][1] = vec[i][0];
143                         vec[i][0] = c;
144                         if (vec[i][0] >= '0' && vec[i][0] <= '9') {
145                                 v += (vec[i][1] - '0' )*16;
146                         } else {
147                                 v += (vec[i][1] - 'a' + 10)*16;
148                         }
149                 /* FALL THROUGH */
150                  case 1:
151                         if (vec[i][0] >= '0' && vec[i][0] <= '9') {
152                                 v += (vec[i][0] - '0' );
153                         } else {
154                                 v += (vec[i][0] - 'a' + 10);
155                         }
156                  case 0:
157                         break;
158                  default:
159                         configuration_error(mc,"bad token %s",s);
160                 }
162                 g_string_append_printf(str,":%.2X",v);
163         }
165         g_strfreev(vec);
167         g_string_erase(str,0,1);
169         return g_string_free(str,FALSE);
172 DIAG_OFF_LEMON()
173 } /* end of %include */
175 %code {
176 DIAG_ON_LEMON()
179 %name MateParser
181 %token_prefix TOKEN_
183 %token_type { char* }
184 %token_destructor {
185         (void) mc; /* Mark unused, similar to Q_UNUSED */
186         g_free($$);
189 %extra_argument { mate_config* mc }
191 %syntax_error {
192         if(yyminor == NULL) {
193                 configuration_error(mc,"Syntax error detected before end of file.");
194         } else {
195                 configuration_error(mc,"Syntax error at or before \"%s\"",yyminor);
196         }
199 %parse_failure {
200         configuration_error(mc,"Parse error");
203 %type   transform_decl  { AVPL_Transf* }
204 %type   transform_body { AVPL_Transf* }
205 %type   transform_statements { AVPL_Transf* }
206 %type   transform_statement { AVPL_Transf* }
207 %type   transform_match { transf_match_t* }
208 %type   transform_action { transf_action_t* }
209 %type   match_mode { avpl_match_mode }
210 %type   action_mode { avpl_replace_mode }
212 %type gop_name { char* }
213 %type time_value { double }
214 %type pdu_name { char* }
215 %type gop_tree_mode { gop_tree_mode_t }
216 %type true_false { bool }
218 %type criteria_statement { pdu_criteria_t* }
219 %type accept_mode { accept_mode_t }
220 %type pdu_drop_unassigned_statement { bool }
221 %type discard_pdu_data_statement { bool }
222 %type last_extracted_statement { bool }
224 %type extraction_statement {extraction_t*}
225 %type extraction_statements {extraction_t*}
227 %type gop_options { gop_options_t* }
229 %type gop_start_statement { AVPL* }
230 %type gop_stop_statement { AVPL* }
231 %type extra_statement { AVPL* }
232 %type gop_drop_unassigned_statement { bool }
233 %type show_goptree_statement { gop_tree_mode_t }
234 %type show_times_statement { bool }
235 %type gop_expiration_statement { double }
236 %type idle_timeout_statement { double }
237 %type lifetime_statement { double }
239 %type gog_statements { gog_statement_t* }
240 %type gog_expiration_statement { double }
241 %type gog_goptree_statement { gop_tree_mode_t }
242 %type gog_key_statements { LoAL* }
243 %type gog_key_statement { AVPL* }
244 %type transform_list_statement { GPtrArray* }
245 %type transform { AVPL_Transf* }
246 %type gop_tree_type { gop_tree_mode_t }
248 %type payload_statement { GPtrArray* }
249 %type proto_stack { GPtrArray*  }
250 %type field { header_field_info* }
251 %type transform_list { GPtrArray* }
252 %type avpl { AVPL* }
253 %type avps { AVPL* }
254 %type avp { AVP* }
255 %type value { char* }
256 %type avp_oneoff { char* }
259 mate_config ::= decls.
261 decls ::= decls decl.
262 decls ::= .
264 decl ::= pdu_decl.
265 decl ::= gop_decl.
266 decl ::= gog_decl.
267 decl ::= transform_decl.
268 decl ::= defaults_decl.
269 decl ::= debug_decl.
270 decl ::= DONE_KW SEMICOLON.
272 /************* DEBUG
275 debug_decl ::= DEBUG_KW OPEN_BRACE dbgfile_default dbglevel_default pdu_dbglevel_default gop_dbglevel_default gog_dbglevel_default CLOSE_BRACE SEMICOLON.
277 dbgfile_default ::= FILENAME_KW QUOTED(Filename) SEMICOLON. { mc->dbg_facility = ws_fopen(Filename,"w"); if (mc->dbg_facility == NULL) report_open_failure(Filename,errno,true); }
278 dbgfile_default ::= FILENAME_KW NAME(Filename) SEMICOLON. { mc->dbg_facility = ws_fopen(Filename,"w"); if (mc->dbg_facility == NULL) report_open_failure(Filename,errno,true);  }
279 dbgfile_default ::= .
281 dbglevel_default ::= LEVEL_KW INTEGER(LevelString) SEMICOLON. { mc->dbg_lvl = (int) strtol(LevelString,NULL,10); }
282 dbglevel_default ::= .
284 pdu_dbglevel_default ::= PDU_KW LEVEL_KW INTEGER(LevelString) SEMICOLON. { mc->dbg_pdu_lvl = (int) strtol(LevelString,NULL,10); }
285 pdu_dbglevel_default ::= .
287 gop_dbglevel_default ::= GOP_KW LEVEL_KW INTEGER(LevelString) SEMICOLON. { mc->dbg_gop_lvl = (int) strtol(LevelString,NULL,10); }
288 gop_dbglevel_default ::= .
290 gog_dbglevel_default ::= GOG_KW LEVEL_KW INTEGER(LevelString) SEMICOLON. { mc->dbg_gog_lvl = (int) strtol(LevelString,NULL,10); }
291 gog_dbglevel_default ::= .
294 /************* DEFAULTS
297 defaults_decl ::= DEFAULT_KW OPEN_BRACE pdu_defaults gop_defaults gog_defaults CLOSE_BRACE SEMICOLON.
299 pdu_defaults ::= PDU_KW OPEN_BRACE pdu_last_extracted_default pdu_drop_unassigned_default pdu_discard_default CLOSE_BRACE SEMICOLON.
300 pdu_defaults ::= .
302 pdu_last_extracted_default ::= LAST_EXTRACTED_KW true_false(Flag) SEMICOLON. { mc->defaults.pdu.last_extracted = Flag; }
303 pdu_last_extracted_default ::= .
305 pdu_drop_unassigned_default ::= DROP_UNASSIGNED_KW true_false(Flag) SEMICOLON. { mc->defaults.pdu.drop_unassigned = Flag; }
306 pdu_drop_unassigned_default ::= .
308 pdu_discard_default ::= DISCARD_PDU_DATA_KW true_false(Flag) SEMICOLON. { mc->defaults.pdu.discard = Flag; }
309 pdu_discard_default ::= .
311 gop_defaults ::= GOP_KW OPEN_BRACE gop_expiration_default gop_idle_timeout_default gop_lifetime_default gop_drop_unassigned_default gop_tree_mode_default gop_show_times_default  CLOSE_BRACE SEMICOLON.
312 gop_defaults ::= .
314 gop_expiration_default ::= EXPIRATION_KW time_value(B) SEMICOLON. { mc->defaults.gop.expiration = B; }
315 gop_expiration_default ::= .
317 gop_idle_timeout_default ::= IDLE_TIMEOUT_KW time_value(B) SEMICOLON. { mc->defaults.gop.idle_timeout = B; }
318 gop_idle_timeout_default ::= .
320 gop_lifetime_default ::= LIFETIME_KW time_value(B) SEMICOLON. { mc->defaults.gop.lifetime = B; }
321 gop_lifetime_default ::= .
323 gop_drop_unassigned_default ::= DROP_UNASSIGNED_KW true_false(B) SEMICOLON. { mc->defaults.gop.drop_unassigned = B; }
324 gop_drop_unassigned_default ::= .
326 gop_tree_mode_default ::= SHOW_TREE_KW gop_tree_mode(B) SEMICOLON. { mc->defaults.gop.pdu_tree_mode = (gop_pdu_tree_t)B; }
327 gop_tree_mode_default ::= .
329 gop_show_times_default ::= SHOW_TIMES_KW true_false(B) SEMICOLON. { mc->defaults.gop.show_times = B; }
330 gop_show_times_default ::= .
332 gog_defaults ::= GOG_KW OPEN_BRACE gog_expiration_default gop_tree_mode_default gog_goptree_default gog_show_times_default CLOSE_BRACE SEMICOLON.
333 gog_defaults ::= .
335 gog_expiration_default ::= EXPIRATION_KW time_value(B) SEMICOLON. { mc->defaults.gop.expiration = B; }
336 gog_expiration_default ::= .
338 gog_goptree_default ::= GOP_TREE_KW gop_tree_type(B) SEMICOLON. { mc->defaults.gog.gop_tree_mode = B; }
339 gog_goptree_default ::= .
341 gog_show_times_default ::= SHOW_TIMES_KW true_false(B) SEMICOLON. { mc->defaults.gog.show_times = B; }
342 gog_show_times_default ::= .
345 /******************************************* TRANSFORM
348 transform_decl(A) ::= TRANSFORM_KW NAME(B) transform_body(C) SEMICOLON. {
349         AVPL_Transf* c;
351         if ( g_hash_table_lookup(mc->transfs,B) ) {
352                 configuration_error(mc,"A transformation called '%s' exists already",B);
353         }
355         for ( c = C; c; c = c->next )
356                 c->name = g_strdup(B);
358         if (C) {
359                 g_hash_table_insert(mc->transfs,C->name,C);
360         }
362         A = NULL;
365 transform_body(A) ::= OPEN_BRACE transform_statements(B) CLOSE_BRACE. { A = B; }
367 transform_statements(A) ::= transform_statements(C) transform_statement(B). {
368         AVPL_Transf* c;
370         for ( c = C; c->next; c = c->next ) ;
371         c->next = B;
372         A = C;
375 transform_statements(A) ::= transform_statement(B). { A = B; }
377 transform_statement(A) ::= transform_match(Match) transform_action(Action) SEMICOLON. {
378         A = new_transform_elem(Match->avpl,Action->avpl,Match->match_mode,Action->replace_mode);
381 transform_match(A) ::= MATCH_KW  match_mode(Mode) avpl(Avpl). {
382         A = (transf_match_t *)g_malloc(sizeof(transf_match_t));
383         A->match_mode = Mode;
384         A->avpl = Avpl;
387 transform_match(A) ::= . {
388         A = (transf_match_t *)g_malloc(sizeof(transf_match_t));
389         A->match_mode = AVPL_STRICT;
390         A->avpl = new_avpl("");
394 transform_action(A) ::= . {
395         A = (transf_action_t *)g_malloc(sizeof(transf_action_t));
396         A->replace_mode = AVPL_INSERT;
397         A->avpl = new_avpl("");
399 transform_action(A) ::= action_mode(Mode) avpl(Avpl). {
400         A = (transf_action_t *)g_malloc(sizeof(transf_action_t));
401         A->replace_mode = Mode;
402         A->avpl = Avpl;
405 match_mode(A) ::=  . { A = AVPL_STRICT; }
406 match_mode(A) ::=  STRICT_KW. { A = AVPL_STRICT; }
407 match_mode(A) ::=  EVERY_KW. { A = AVPL_EVERY; }
408 match_mode(A) ::=  LOOSE_KW. { A = AVPL_LOOSE; }
410 action_mode(A) ::= REPLACE_KW. { A = AVPL_REPLACE; }
411 action_mode(A) ::= INSERT_KW. { A = AVPL_INSERT; }
412 action_mode(A) ::= . { A = AVPL_INSERT; }
414 /******************************************* PDU
417 pdu_decl ::=
418         PDU_KW NAME(Name) PROTO_KW field(Field) TRANSPORT_KW proto_stack(Stack)
419                 OPEN_BRACE
420                         payload_statement(Payload)
421                         extraction_statements(Extraction)
422                         transform_list_statement(Transform)
423                         criteria_statement(Criteria)
424                         pdu_drop_unassigned_statement(DropUnassigned)
425                         discard_pdu_data_statement(DistcardPduData)
426                         last_extracted_statement(LastExtracted)
427                 CLOSE_BRACE SEMICOLON.
430         mate_cfg_pdu* cfg  = new_pducfg(mc, Name);
431         extraction_t *extraction, *next_extraction;
432         GPtrArray* transport_stack = g_ptr_array_new();
433         int i;
435         if (! cfg ) configuration_error(mc,"could not create Pdu %s.",Name);
437         cfg->hfid_proto = Field->id;
439         cfg->last_extracted = LastExtracted;
440         cfg->discard = DistcardPduData;
441         cfg->drop_unassigned = DropUnassigned;
443         /*
444          * Add this protocol to our table of wanted hfids.
445          */
446         mc->wanted_hfids = g_array_append_val(mc->wanted_hfids, Field->id);
448         /* flip the transport_stack */
449         for (i = Stack->len - 1; Stack->len; i--) {
450                 g_ptr_array_add(transport_stack,g_ptr_array_remove_index(Stack,i));
451         }
453         g_ptr_array_free(Stack, true);
455         cfg->transport_ranges = transport_stack;
456         cfg->payload_ranges = Payload;
458         if (Criteria) {
459                 cfg->criterium = Criteria->criterium_avpl;
460                 cfg->criterium_match_mode = Criteria->criterium_match_mode;
461                 cfg->criterium_accept_mode = Criteria->criterium_accept_mode;
462         }
464         cfg->transforms = Transform;
466         for (extraction = Extraction; extraction; extraction = next_extraction) {
467                 next_extraction = extraction->next;
469                 if ( ! add_hfid(mc, extraction->hfi, extraction->as, cfg->hfids_attr) ) {
470                         configuration_error(mc,"MATE: failed to create extraction rule '%s'",extraction->as);
471                 }
473                 g_free(extraction);
474         }
477 payload_statement(A) ::= . { A = NULL; }
478 payload_statement(A) ::= PAYLOAD_KW proto_stack(B) SEMICOLON. { A = B; }
480 criteria_statement(A) ::= . { A = NULL; }
481 criteria_statement(A) ::= CRITERIA_KW accept_mode(B) match_mode(C) avpl(D) SEMICOLON. {
482         A = g_new(pdu_criteria_t, 1);
483         A->criterium_avpl = D;
484         A->criterium_match_mode = C;
485         A->criterium_accept_mode = B;
488 accept_mode(A) ::= . { A = ACCEPT_MODE; }
489 accept_mode(A) ::= ACCEPT_KW. { A = ACCEPT_MODE; }
490 accept_mode(A) ::= REJECT_KW. { A = REJECT_MODE; }
492 extraction_statements(A) ::= extraction_statements(B) extraction_statement(C). { A = B; A->last = A->last->next = C; }
493 extraction_statements(A) ::= extraction_statement(B). { A = B; A->last = A; }
495 extraction_statement(A) ::= EXTRACT_KW NAME(NAME) FROM_KW field(FIELD) SEMICOLON. {
496         A = g_new(extraction_t, 1);
497         A->as = NAME;
498         A->hfi = FIELD;
499         A->next = A->last = NULL;
503 pdu_drop_unassigned_statement(A) ::= DROP_UNASSIGNED_KW true_false(B) SEMICOLON. { A = B; }
504 pdu_drop_unassigned_statement(A) ::= . { A =  mc->defaults.pdu.drop_unassigned; }
506 discard_pdu_data_statement(A) ::=  DISCARD_PDU_DATA_KW true_false(B) SEMICOLON. { A = B; }
507 discard_pdu_data_statement(A) ::=  . { A =  mc->defaults.pdu.discard; }
509 last_extracted_statement(A) ::= LAST_PDU_KW true_false(B) SEMICOLON. { A = B; }
510 last_extracted_statement(A) ::= . { A = mc->defaults.pdu.last_extracted; }
512 proto_stack(A) ::= proto_stack(B) SLASH field(C). {
513         int* hfidp = g_new(int, 1);
515         *hfidp = C->id;
516         g_ptr_array_add(B,hfidp);
517         A = B;
520 proto_stack(A) ::= field(B). {
521         int* hfidp = g_new(int, 1);
522         *hfidp = B->id;
524         A = g_ptr_array_new();
525         g_ptr_array_add(A,hfidp);
528 field(A) ::= NAME(B). {
529         A = proto_registrar_get_byname(B);
530         if (A == NULL) {
531                 configuration_error(mc,"\nUnknown Proto/Transport/field: %s\n",B);
532         };
535 /******************************************* GOP
538 gop_decl(A) ::= GOP_KW NAME(Name) ON_KW pdu_name(PduName) MATCH_KW avpl(Key) OPEN_BRACE
539                 gop_start_statement(Start)
540                 gop_stop_statement(Stop)
541                 extra_statement(Extra)
542                 transform_list_statement(Transform)
543                 gop_expiration_statement(Expiration)
544                 idle_timeout_statement(IdleTimeout)
545                 lifetime_statement(Lifetime)
546                 gop_drop_unassigned_statement(DropUnassigned)
547                 show_goptree_statement(TreeMode)
548                 show_times_statement(ShowTimes)
549         CLOSE_BRACE SEMICOLON. {
550                 mate_cfg_gop* cfg;
552         if (g_hash_table_lookup(mc->gopcfgs,Name)) configuration_error(mc,"A Gop Named '%s' exists already.",Name);
553         if (g_hash_table_lookup(mc->gops_by_pduname,PduName) ) configuration_error(mc,"Gop for Pdu '%s' exists already",PduName);
555         cfg = new_gopcfg(mc, Name);
556         g_hash_table_insert(mc->gops_by_pduname,PduName,cfg);
557         g_hash_table_insert(mc->gopcfgs,cfg->name,cfg);
559         cfg->on_pdu = PduName;
560         cfg->key = Key;
561         cfg->drop_unassigned = DropUnassigned;
562         cfg->show_times = ShowTimes;
563         cfg->pdu_tree_mode = (gop_pdu_tree_t)TreeMode;
564         cfg->expiration = Expiration;
565         cfg->idle_timeout = IdleTimeout;
566         cfg->lifetime = Lifetime;
567         cfg->start = Start;
568         cfg->stop = Stop;
569         cfg->transforms = Transform;
571         merge_avpl(cfg->extra,Extra,true);
572         delete_avpl(Extra,true);
575 gop_drop_unassigned_statement(A) ::= DROP_UNASSIGNED_KW true_false(B) SEMICOLON. { A = B; }
576 gop_drop_unassigned_statement(A) ::= . { A =  mc->defaults.gop.drop_unassigned; }
578 gop_start_statement(A) ::= START_KW avpl(B) SEMICOLON. { A = B; }
579 gop_start_statement(A) ::= . { A = NULL; }
581 gop_stop_statement(A) ::= STOP_KW avpl(B) SEMICOLON. { A = B; }
582 gop_stop_statement(A) ::= . { A = NULL; }
584 show_goptree_statement(A) ::= SHOW_TREE_KW gop_tree_mode(B) SEMICOLON. { A = B; }
585 show_goptree_statement(A) ::= . { A = (gop_tree_mode_t)mc->defaults.gop.pdu_tree_mode; }
587 show_times_statement(A) ::= SHOW_TIMES_KW true_false(B) SEMICOLON. { A = B; }
588 show_times_statement(A) ::= . { A = mc->defaults.gop.show_times; }
590 gop_expiration_statement(A) ::= EXPIRATION_KW time_value(B) SEMICOLON. { A = B; }
591 gop_expiration_statement(A) ::= . { A = mc->defaults.gop.lifetime; }
593 idle_timeout_statement(A) ::= IDLE_TIMEOUT_KW time_value(B) SEMICOLON. { A = B; }
594 idle_timeout_statement(A) ::= . { A = mc->defaults.gop.lifetime; }
596 lifetime_statement(A) ::= LIFETIME_KW time_value(B) SEMICOLON. { A = B; }
597 lifetime_statement(A) ::= . { A = mc->defaults.gop.lifetime; }
599 gop_tree_mode(A) ::= NO_TREE_KW.        { A = (gop_tree_mode_t)GOP_NO_TREE; }
600 gop_tree_mode(A) ::= PDU_TREE_KW.       { A = (gop_tree_mode_t)GOP_PDU_TREE; }
601 gop_tree_mode(A) ::= FRAME_TREE_KW.     { A = (gop_tree_mode_t)GOP_FRAME_TREE; }
602 gop_tree_mode(A) ::= BASIC_TREE_KW.     { A = (gop_tree_mode_t)GOP_BASIC_PDU_TREE; }
604 true_false(A) ::= TRUE_KW. { A = true; }
605 true_false(A) ::= FALSE_KW. { A = false; }
607 pdu_name(A) ::= NAME(B). {
608         mate_cfg_pdu* c;
609         if (( c =  (mate_cfg_pdu *)g_hash_table_lookup(mc->pducfgs,B) )) {
610                 A = c->name;
611         } else {
612                 configuration_error(mc,"No such Pdu: '%s'",B);
613         }
617 time_value(A) ::= FLOATING(B). {
618         A = g_ascii_strtod(B,NULL);
621 time_value(A) ::= INTEGER(B). {
622         A = g_ascii_strtod(B,NULL);
625 /************* GOG
628 gog_decl ::= GOG_KW NAME(Name) OPEN_BRACE
629         gog_key_statements(Keys)
630         extra_statement(Extra)
631         transform_list_statement(Transforms)
632         gog_expiration_statement(Expiration)
633         gog_goptree_statement(Tree)
634         show_times_statement(ShowTimes)
635         CLOSE_BRACE SEMICOLON. {
636                 mate_cfg_gog* cfg = NULL;
638                 if ( g_hash_table_lookup(mc->gogcfgs,Name) ) {
639                         configuration_error(mc,"Gog '%s' exists already ",Name);
640                 }
642                 cfg = new_gogcfg(mc, Name);
644                 cfg->expiration = Expiration;
645                 cfg->gop_tree_mode = Tree;
646                 cfg->transforms = Transforms;
647                 cfg->keys = Keys;
648                 cfg->show_times = ShowTimes;
650                 merge_avpl(cfg->extra,Extra,true);
651                 delete_avpl(Extra,true);
654 gog_goptree_statement(A) ::= GOP_TREE_KW gop_tree_type(B) SEMICOLON. { A = B; }
655 gog_goptree_statement(A) ::= . { A = mc->defaults.gog.gop_tree_mode; }
657 gog_expiration_statement(A) ::= EXPIRATION_KW time_value(B) SEMICOLON. { A = B; }
658 gog_expiration_statement(A) ::= . { A = mc->defaults.gog.expiration; }
660 gop_tree_type(A) ::= NULL_TREE_KW. { A = GOP_NULL_TREE; }
661 gop_tree_type(A) ::= FULL_TREE_KW. { A = GOP_FULL_TREE; }
662 gop_tree_type(A) ::= BASIC_TREE_KW. { A = GOP_BASIC_TREE; }
664 gog_key_statements(A) ::= gog_key_statements(B) gog_key_statement(C). {
665         loal_append(B,C);
666         A = B;
669 gog_key_statements(A) ::= gog_key_statement(B). {
670         A = new_loal("");
671         loal_append(A,B);
675 gog_key_statement(A) ::= MEMBER_KW gop_name(B) avpl(C) SEMICOLON. {
676         rename_avpl(C,B);
677         A = C;
680 gop_name(A) ::= NAME(B). {
681         mate_cfg_gop* c;
682         if (( c = (mate_cfg_gop *)g_hash_table_lookup(mc->gopcfgs,B) )) {
683                 A = c->name;
684         } else {
685                 configuration_error(mc,"No Gop called '%s' has been already declared",B);
686         }
688 /******************************************** GENERAL
692 extra_statement(A) ::= EXTRA_KW avpl(B) SEMICOLON. { A = B; }
693 extra_statement(A) ::= . { A = new_avpl(""); }
695 transform_list_statement(A) ::= TRANSFORM_KW transform_list(B) SEMICOLON. { A = B; }
696 transform_list_statement(A) ::= . { A = g_ptr_array_new(); }
698 transform_list(A) ::= transform_list(B) COMMA transform(C). {
699         A = B;
700         g_ptr_array_add(B,C);
703 transform_list(A) ::= transform(B). {
704         A = g_ptr_array_new();
705         g_ptr_array_add(A,B);
708 transform(A) ::= NAME(B). {
709         AVPL_Transf* t;
711         if (( t = (AVPL_Transf *)g_hash_table_lookup(mc->transfs,B) )) {
712                 A = t;
713         } else {
714                 configuration_error(mc,"There's no such Transformation: %s",B);
715         }
718 avpl(A) ::= OPEN_PARENS avps(B) CLOSE_PARENS. { A = B; }
719 avpl(A) ::= OPEN_PARENS CLOSE_PARENS. { A = new_avpl(""); }
721 avps(A) ::= avps(B) COMMA avp(C). { A = B; if ( ! insert_avp(B,C) ) delete_avp(C); }
722 avps(A) ::= avp(B). { A = new_avpl(""); if ( ! insert_avp(A,B) ) delete_avp(B); }
724 avp(A) ::= NAME(B) AVP_OPERATOR(C) value(D). { A = new_avp(B,D,*C); }
725 avp(A) ::= NAME(B). { A = new_avp(B,"",'?'); }
726 avp(A) ::= NAME(B) OPEN_BRACE avp_oneoff(C) CLOSE_BRACE. { A = new_avp(B,C,'|'); }
728 avp_oneoff(A) ::= avp_oneoff(B) PIPE value(C). { A = ws_strdup_printf("%s|%s",B,C); }
729 avp_oneoff(A) ::= value(B). { A = g_strdup(B); }
731 value(A) ::= QUOTED(B). { A = g_strdup(B); }
732 value(A) ::= NAME(B). { A = g_strdup(B); }
733 value(A) ::= FLOATING(B). { A = g_strdup(B); }
734 value(A) ::= INTEGER(B). { A = g_strdup(B); }
735 value(A) ::= DOTED_IP(B). { A = g_strdup(B); }
736 value(A) ::= COLONIZED(B). { A = recolonize(mc,B); }