4 * XML dissector for wireshark
7 * Copyright 2005, Luis E. Garcia Ontanon <luis@ontanon.org>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
21 #include <ws_diag_control.h>
23 #include "dtd_parse.h"
25 static dtd_named_list_t* dtd_named_list_new(char* name, GPtrArray* list) {
26 dtd_named_list_t* nl = g_new(dtd_named_list_t,1);
34 static GPtrArray* g_ptr_array_join(GPtrArray* a, GPtrArray* b){
37 g_ptr_array_add(a,g_ptr_array_remove_index_fast(b,0));
40 g_ptr_array_free(b,true);
46 } /* end of %include */
54 %extra_argument { dtd_build_data_t *bd }
57 (void) bd; /* Mark unused, similar to Q_UNUSED */
67 g_string_append_printf(bd->error,"syntax error at end of file");
69 g_string_append_printf(bd->error,"syntax error in %s at or before '%s': \n", TOKEN->location,TOKEN->text);
73 g_string_append_printf(bd->error,"DTD parsing failure\n");
78 %token_type { dtd_token_data_t* }
83 doctype ::= TAG_START DOCTYPE_KW NAME(Name) OPEN_BRACKET dtd_parts CLOSE_BRACKET TAG_STOP. {
84 dtd_named_list_t* root;
85 GPtrArray* root_elems = g_ptr_array_new();
89 if(! bd->proto_name) {
90 bd->proto_name = g_strdup(Name->text);
93 g_free(bd->proto_root);
95 bd->proto_root = Name->text;
97 name = g_ascii_strdown(bd->proto_name, -1);
98 g_free(bd->proto_name);
99 bd->proto_name = name;
101 for( i = 0; i< bd->elements->len; i++) {
102 dtd_named_list_t* el = (dtd_named_list_t*)g_ptr_array_index(bd->elements,i);
104 g_ptr_array_add(root_elems,g_strdup(el->name));
107 root = dtd_named_list_new(g_strdup(Name->text),root_elems);
109 g_ptr_array_add(bd->elements,root);
111 g_free(Name->location);
116 dtd_parts ::= dtd_parts element(Element). { g_ptr_array_add(bd->elements,Element); }
117 dtd_parts ::= dtd_parts attlist(Attlist). { g_ptr_array_add(bd->attributes,Attlist); }
118 dtd_parts ::= element(Element). { g_ptr_array_add(bd->elements,Element); }
119 dtd_parts ::= attlist(Attlist). { g_ptr_array_add(bd->attributes,Attlist); }
121 %type attlist { dtd_named_list_t* }
122 attlist(A) ::= TAG_START ATTLIST_KW NAME(B) attrib_list(TheList) TAG_STOP. {
123 A = dtd_named_list_new(g_ascii_strdown(B->text, -1),TheList);
129 %type element { dtd_named_list_t* }
130 element(A) ::= TAG_START ELEMENT_KW NAME(B) sub_elements(C) TAG_STOP. {
131 A = dtd_named_list_new(g_ascii_strdown(B->text, -1),C);
137 %type attrib_list { GPtrArray* }
138 attrib_list(A) ::= attrib_list(B) attrib(C). { g_ptr_array_add(B,C); A = B; }
139 attrib_list(A) ::= attrib(B). { A = g_ptr_array_new(); g_ptr_array_add(A,B); }
141 %type attrib { char* }
142 attrib(A) ::= NAME(B) att_type att_default. {
143 A = g_ascii_strdown(B->text, -1);
149 att_type ::= ATT_TYPE.
150 att_type ::= enumeration.
152 att_default ::= ATT_DEF.
153 att_default ::= ATT_DEF_WITH_VALUE QUOTED.
154 att_default ::= QUOTED.
155 att_default ::= IMPLIED_KW.
156 att_default ::= REQUIRED_KW.
158 enumeration ::= OPEN_PARENS enum_list CLOSE_PARENS.
160 enum_list ::= enum_list PIPE enum_item.
161 enum_list ::= enum_item.
162 enum_list ::= enumeration.
163 enum_list ::= enum_list PIPE enumeration.
166 enum_item ::= QUOTED.
169 %type sub_elements { GPtrArray* }
170 sub_elements(A) ::= sub_elements(B) STAR. {A=B;}
171 sub_elements(A) ::= sub_elements(B) PLUS. {A=B;}
172 sub_elements(A) ::= sub_elements(B) QUESTION. {A=B;}
173 sub_elements(A) ::= OPEN_PARENS ELEM_DATA CLOSE_PARENS. { A = g_ptr_array_new(); }
174 sub_elements(A) ::= OPEN_PARENS element_list(B) COMMA ELEM_DATA CLOSE_PARENS. { A = B; }
175 sub_elements(A) ::= OPEN_PARENS element_list(B) PIPE ELEM_DATA CLOSE_PARENS. { A = B; }
176 sub_elements(A) ::= OPEN_PARENS element_list(B) CLOSE_PARENS. { A = B; }
177 sub_elements(A) ::= EMPTY_KW. { A = g_ptr_array_new(); }
179 %type element_list { GPtrArray* }
180 element_list(A) ::= element_list(B) COMMA element_child(C). { g_ptr_array_add(B,C); A = B; }
181 element_list(A) ::= element_list(B) PIPE element_child(C). { g_ptr_array_add(B,C); A = B; }
182 element_list(A) ::= element_child(B). { A = g_ptr_array_new(); g_ptr_array_add(A,B); }
183 element_list(A) ::= sub_elements(B). { A = B; }
184 element_list(A) ::= element_list(B) COMMA sub_elements(C). { A = g_ptr_array_join(B,C); }
185 element_list(A) ::= element_list(B) PIPE sub_elements(C). { A = g_ptr_array_join(B,C); }
187 %type element_child { char* }
188 element_child(A) ::= NAME(B). {
189 A = g_ascii_strdown(B->text, -1);
195 element_child(A) ::= NAME(B) STAR. {
196 A = g_ascii_strdown(B->text, -1);
202 element_child(A) ::= NAME(B) QUESTION. {
203 A = g_ascii_strdown(B->text, -1);
209 element_child(A) ::= NAME(B) PLUS. {
210 A = g_ascii_strdown(B->text, -1);