nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/usr/bin/env python |
2 | |||
3 | # |
||
4 | # asn2wrs.py |
||
5 | # ASN.1 to Wireshark dissector compiler |
||
6 | # Copyright 2004 Tomas Kukosa |
||
7 | # |
||
8 | # Permission is hereby granted, free of charge, to any person obtaining a |
||
9 | # copy of this software and associated documentation files (the |
||
10 | # "Software"), to deal in the Software without restriction, including |
||
11 | # without limitation the rights to use, copy, modify, merge, publish, |
||
12 | # distribute, and/or sell copies of the Software, and to permit persons |
||
13 | # to whom the Software is furnished to do so, provided that the above |
||
14 | # copyright notice(s) and this permission notice appear in all copies of |
||
15 | # the Software and that both the above copyright notice(s) and this |
||
16 | # permission notice appear in supporting documentation. |
||
17 | # |
||
18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
19 | # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
20 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT |
||
21 | # OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
||
22 | # HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL |
||
23 | # INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING |
||
24 | # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
||
25 | # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
||
26 | # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||
27 | # |
||
28 | # Except as contained in this notice, the name of a copyright holder |
||
29 | # shall not be used in advertising or otherwise to promote the sale, use |
||
30 | # or other dealings in this Software without prior written authorization |
||
31 | # of the copyright holder. |
||
32 | |||
33 | |||
34 | """ASN.1 to Wireshark dissector compiler""" |
||
35 | |||
36 | # |
||
37 | # Compiler from ASN.1 specification to the Wireshark dissector |
||
38 | # |
||
39 | # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license |
||
40 | # http://www.pobox.com/~asl2/software/PyZ3950/ |
||
41 | # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary) |
||
42 | # |
||
43 | # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3) |
||
44 | # http://www.dabeaz.com/ply/ |
||
45 | # |
||
46 | # |
||
47 | # ITU-T Recommendation X.680 (07/2002), |
||
48 | # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation |
||
49 | # |
||
50 | # ITU-T Recommendation X.681 (07/2002), |
||
51 | # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification |
||
52 | # |
||
53 | # ITU-T Recommendation X.682 (07/2002), |
||
54 | # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification |
||
55 | # |
||
56 | # ITU-T Recommendation X.683 (07/2002), |
||
57 | # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications |
||
58 | # |
||
59 | # ITU-T Recommendation X.880 (07/1994), |
||
60 | # Information technology - Remote Operations: Concepts, model and notation |
||
61 | # |
||
62 | |||
63 | import warnings |
||
64 | |||
65 | import re |
||
66 | import sys |
||
67 | import os |
||
68 | import os.path |
||
69 | import time |
||
70 | import getopt |
||
71 | import traceback |
||
72 | |||
73 | import lex |
||
74 | import yacc |
||
75 | |||
76 | if sys.version_info[0] < 3: |
||
77 | from string import maketrans |
||
78 | |||
79 | |||
80 | # OID name -> number conversion table |
||
81 | oid_names = { |
||
82 | '/itu-t' : 0, |
||
83 | '/itu' : 0, |
||
84 | '/ccitt' : 0, |
||
85 | '/itu-r' : 0, |
||
86 | '0/recommendation' : 0, |
||
87 | '0.0/a' : 1, |
||
88 | '0.0/b' : 2, |
||
89 | '0.0/c' : 3, |
||
90 | '0.0/d' : 4, |
||
91 | '0.0/e' : 5, |
||
92 | '0.0/f' : 6, |
||
93 | '0.0/g' : 7, |
||
94 | '0.0/h' : 8, |
||
95 | '0.0/i' : 9, |
||
96 | '0.0/j' : 10, |
||
97 | '0.0/k' : 11, |
||
98 | '0.0/l' : 12, |
||
99 | '0.0/m' : 13, |
||
100 | '0.0/n' : 14, |
||
101 | '0.0/o' : 15, |
||
102 | '0.0/p' : 16, |
||
103 | '0.0/q' : 17, |
||
104 | '0.0/r' : 18, |
||
105 | '0.0/s' : 19, |
||
106 | '0.0/t' : 20, |
||
107 | '0.0/tseries' : 20, |
||
108 | '0.0/u' : 21, |
||
109 | '0.0/v' : 22, |
||
110 | '0.0/w' : 23, |
||
111 | '0.0/x' : 24, |
||
112 | '0.0/y' : 25, |
||
113 | '0.0/z' : 26, |
||
114 | '0/question' : 1, |
||
115 | '0/administration' : 2, |
||
116 | '0/network-operator' : 3, |
||
117 | '0/identified-organization' : 4, |
||
118 | '0/r-recommendation' : 5, |
||
119 | '0/data' : 9, |
||
120 | '/iso' : 1, |
||
121 | '1/standard' : 0, |
||
122 | '1/registration-authority' : 1, |
||
123 | '1/member-body' : 2, |
||
124 | '1/identified-organization' : 3, |
||
125 | '/joint-iso-itu-t' : 2, |
||
126 | '/joint-iso-ccitt' : 2, |
||
127 | '2/presentation' : 0, |
||
128 | '2/asn1' : 1, |
||
129 | '2/association-control' : 2, |
||
130 | '2/reliable-transfer' : 3, |
||
131 | '2/remote-operations' : 4, |
||
132 | '2/ds' : 5, |
||
133 | '2/directory' : 5, |
||
134 | '2/mhs' : 6, |
||
135 | '2/mhs-motis' : 6, |
||
136 | '2/ccr' : 7, |
||
137 | '2/oda' : 8, |
||
138 | '2/ms' : 9, |
||
139 | '2/osi-management' : 9, |
||
140 | '2/transaction-processing' : 10, |
||
141 | '2/dor' : 11, |
||
142 | '2/distinguished-object-reference' : 11, |
||
143 | '2/reference-data-transfe' : 12, |
||
144 | '2/network-layer' : 13, |
||
145 | '2/network-layer-management' : 13, |
||
146 | '2/transport-layer' : 14, |
||
147 | '2/transport-layer-management' : 14, |
||
148 | '2/datalink-layer' : 15, |
||
149 | '2/datalink-layer-managemen' : 15, |
||
150 | '2/datalink-layer-management-information' : 15, |
||
151 | '2/country' : 16, |
||
152 | '2/registration-procedures' : 17, |
||
153 | '2/registration-procedure' : 17, |
||
154 | '2/physical-layer' : 18, |
||
155 | '2/physical-layer-management' : 18, |
||
156 | '2/mheg' : 19, |
||
157 | '2/genericULS' : 20, |
||
158 | '2/generic-upper-layers-security' : 20, |
||
159 | '2/guls' : 20, |
||
160 | '2/transport-layer-security-protocol' : 21, |
||
161 | '2/network-layer-security-protocol' : 22, |
||
162 | '2/international-organizations' : 23, |
||
163 | '2/internationalRA' : 23, |
||
164 | '2/sios' : 24, |
||
165 | '2/uuid' : 25, |
||
166 | '2/odp' : 26, |
||
167 | '2/upu' : 40, |
||
168 | } |
||
169 | |||
170 | ITEM_FIELD_NAME = '_item' |
||
171 | UNTAG_TYPE_NAME = '_untag' |
||
172 | |||
173 | def asn2c(id): |
||
174 | return id.replace('-', '_').replace('.', '_').replace('&', '_') |
||
175 | |||
176 | input_file = None |
||
177 | g_conform = None |
||
178 | lexer = None |
||
179 | in_oid = False |
||
180 | |||
181 | class LexError(Exception): |
||
182 | def __init__(self, tok, filename=None): |
||
183 | self.tok = tok |
||
184 | self.filename = filename |
||
185 | self.msg = "Unexpected character %r" % (self.tok.value[0]) |
||
186 | Exception.__init__(self, self.msg) |
||
187 | def __repr__(self): |
||
188 | return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg) |
||
189 | __str__ = __repr__ |
||
190 | |||
191 | |||
192 | class ParseError(Exception): |
||
193 | def __init__(self, tok, filename=None): |
||
194 | self.tok = tok |
||
195 | self.filename = filename |
||
196 | self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value) |
||
197 | Exception.__init__(self, self.msg) |
||
198 | def __repr__(self): |
||
199 | return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg) |
||
200 | __str__ = __repr__ |
||
201 | |||
202 | |||
203 | class DuplicateError(Exception): |
||
204 | def __init__(self, type, ident): |
||
205 | self.type = type |
||
206 | self.ident = ident |
||
207 | self.msg = "Duplicate %s for %s" % (self.type, self.ident) |
||
208 | Exception.__init__(self, self.msg) |
||
209 | def __repr__(self): |
||
210 | return self.msg |
||
211 | __str__ = __repr__ |
||
212 | |||
213 | class CompError(Exception): |
||
214 | def __init__(self, msg): |
||
215 | self.msg = msg |
||
216 | Exception.__init__(self, self.msg) |
||
217 | def __repr__(self): |
||
218 | return self.msg |
||
219 | __str__ = __repr__ |
||
220 | |||
221 | |||
222 | states = ( |
||
223 | ('braceignore','exclusive'), |
||
224 | ) |
||
225 | |||
226 | precedence = ( |
||
227 | ('left', 'UNION', 'BAR'), |
||
228 | ('left', 'INTERSECTION', 'CIRCUMFLEX'), |
||
229 | ) |
||
230 | # 11 ASN.1 lexical items |
||
231 | |||
232 | static_tokens = { |
||
233 | r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item |
||
234 | r'\.\.' : 'RANGE', # 11.17 Range separator |
||
235 | r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis |
||
236 | r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets |
||
237 | r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets |
||
238 | # 11.26 Single character lexical items |
||
239 | r'\{' : 'LBRACE', |
||
240 | r'\}' : 'RBRACE', |
||
241 | r'<' : 'LT', |
||
242 | #r'>' : 'GT', |
||
243 | r',' : 'COMMA', |
||
244 | r'\.' : 'DOT', |
||
245 | r'\(' : 'LPAREN', |
||
246 | r'\)' : 'RPAREN', |
||
247 | r'\[' : 'LBRACK', |
||
248 | r'\]' : 'RBRACK', |
||
249 | r'-' : 'MINUS', |
||
250 | r':' : 'COLON', |
||
251 | #r'=' : 'EQ', |
||
252 | #r'"' : 'QUOTATION', |
||
253 | #r"'" : 'APOSTROPHE', |
||
254 | r';' : 'SEMICOLON', |
||
255 | r'@' : 'AT', |
||
256 | r'\!' : 'EXCLAMATION', |
||
257 | r'\^' : 'CIRCUMFLEX', |
||
258 | r'\&' : 'AMPERSAND', |
||
259 | r'\|' : 'BAR' |
||
260 | } |
||
261 | |||
262 | # 11.27 Reserved words |
||
263 | |||
264 | # all keys in reserved_words must start w/ upper case |
||
265 | reserved_words = { |
||
266 | 'ABSENT' : 'ABSENT', |
||
267 | 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX', |
||
268 | 'ALL' : 'ALL', |
||
269 | 'APPLICATION' : 'APPLICATION', |
||
270 | 'AUTOMATIC' : 'AUTOMATIC', |
||
271 | 'BEGIN' : 'BEGIN', |
||
272 | 'BIT' : 'BIT', |
||
273 | 'BOOLEAN' : 'BOOLEAN', |
||
274 | 'BY' : 'BY', |
||
275 | 'CHARACTER' : 'CHARACTER', |
||
276 | 'CHOICE' : 'CHOICE', |
||
277 | 'CLASS' : 'CLASS', |
||
278 | 'COMPONENT' : 'COMPONENT', |
||
279 | 'COMPONENTS' : 'COMPONENTS', |
||
280 | 'CONSTRAINED' : 'CONSTRAINED', |
||
281 | 'CONTAINING' : 'CONTAINING', |
||
282 | 'DEFAULT' : 'DEFAULT', |
||
283 | 'DEFINITIONS' : 'DEFINITIONS', |
||
284 | 'EMBEDDED' : 'EMBEDDED', |
||
285 | # 'ENCODED' : 'ENCODED', |
||
286 | 'END' : 'END', |
||
287 | 'ENUMERATED' : 'ENUMERATED', |
||
288 | # 'EXCEPT' : 'EXCEPT', |
||
289 | 'EXPLICIT' : 'EXPLICIT', |
||
290 | 'EXPORTS' : 'EXPORTS', |
||
291 | # 'EXTENSIBILITY' : 'EXTENSIBILITY', |
||
292 | 'EXTERNAL' : 'EXTERNAL', |
||
293 | 'FALSE' : 'FALSE', |
||
294 | 'FROM' : 'FROM', |
||
295 | 'GeneralizedTime' : 'GeneralizedTime', |
||
296 | 'IDENTIFIER' : 'IDENTIFIER', |
||
297 | 'IMPLICIT' : 'IMPLICIT', |
||
298 | # 'IMPLIED' : 'IMPLIED', |
||
299 | 'IMPORTS' : 'IMPORTS', |
||
300 | 'INCLUDES' : 'INCLUDES', |
||
301 | 'INSTANCE' : 'INSTANCE', |
||
302 | 'INTEGER' : 'INTEGER', |
||
303 | 'INTERSECTION' : 'INTERSECTION', |
||
304 | 'MAX' : 'MAX', |
||
305 | 'MIN' : 'MIN', |
||
306 | 'MINUS-INFINITY' : 'MINUS_INFINITY', |
||
307 | 'NULL' : 'NULL', |
||
308 | 'OBJECT' : 'OBJECT', |
||
309 | 'ObjectDescriptor' : 'ObjectDescriptor', |
||
310 | 'OCTET' : 'OCTET', |
||
311 | 'OF' : 'OF', |
||
312 | 'OPTIONAL' : 'OPTIONAL', |
||
313 | 'PATTERN' : 'PATTERN', |
||
314 | 'PDV' : 'PDV', |
||
315 | 'PLUS-INFINITY' : 'PLUS_INFINITY', |
||
316 | 'PRESENT' : 'PRESENT', |
||
317 | 'PRIVATE' : 'PRIVATE', |
||
318 | 'REAL' : 'REAL', |
||
319 | 'RELATIVE-OID' : 'RELATIVE_OID', |
||
320 | 'SEQUENCE' : 'SEQUENCE', |
||
321 | 'SET' : 'SET', |
||
322 | 'SIZE' : 'SIZE', |
||
323 | 'STRING' : 'STRING', |
||
324 | 'SYNTAX' : 'SYNTAX', |
||
325 | 'TAGS' : 'TAGS', |
||
326 | 'TRUE' : 'TRUE', |
||
327 | 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER', |
||
328 | 'UNION' : 'UNION', |
||
329 | 'UNIQUE' : 'UNIQUE', |
||
330 | 'UNIVERSAL' : 'UNIVERSAL', |
||
331 | 'UTCTime' : 'UTCTime', |
||
332 | 'WITH' : 'WITH', |
||
333 | # X.208 obsolete but still used |
||
334 | 'ANY' : 'ANY', |
||
335 | 'DEFINED' : 'DEFINED', |
||
336 | } |
||
337 | |||
338 | for k in list(static_tokens.keys()): |
||
339 | if static_tokens [k] == None: |
||
340 | static_tokens [k] = k |
||
341 | |||
342 | StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8', |
||
343 | 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible', |
||
344 | 'General'] |
||
345 | |||
346 | for s in StringTypes: |
||
347 | reserved_words[s + 'String'] = s + 'String' |
||
348 | |||
349 | tokens = list(static_tokens.values()) \ |
||
350 | + list(reserved_words.values()) \ |
||
351 | + ['BSTRING', 'HSTRING', 'QSTRING', |
||
352 | 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT', |
||
353 | 'REAL_NUMBER', 'NUMBER', 'PYQUOTE'] |
||
354 | |||
355 | |||
356 | cur_mod = __import__ (__name__) # XXX blech! |
||
357 | |||
358 | for (k, v) in list(static_tokens.items ()): |
||
359 | cur_mod.__dict__['t_' + v] = k |
||
360 | |||
361 | # 11.10 Binary strings |
||
362 | def t_BSTRING (t): |
||
363 | r"'[01]*'B" |
||
364 | return t |
||
365 | |||
366 | # 11.12 Hexadecimal strings |
||
367 | def t_HSTRING (t): |
||
368 | r"'[0-9A-Fa-f]*'H" |
||
369 | return t |
||
370 | |||
371 | def t_QSTRING (t): |
||
372 | r'"([^"]|"")*"' |
||
373 | return t |
||
374 | |||
375 | def t_UCASE_IDENT (t): |
||
376 | r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-' |
||
377 | if (is_class_ident(t.value)): t.type = 'CLASS_IDENT' |
||
378 | if (is_class_syntax(t.value)): t.type = t.value |
||
379 | t.type = reserved_words.get(t.value, t.type) |
||
380 | return t |
||
381 | |||
382 | lcase_ident_assigned = {} |
||
383 | def t_LCASE_IDENT (t): |
||
384 | r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-' |
||
385 | if (not in_oid and (t.value in lcase_ident_assigned)): t.type = 'LCASE_IDENT_ASSIGNED' |
||
386 | return t |
||
387 | |||
388 | # 11.9 Real numbers |
||
389 | def t_REAL_NUMBER (t): |
||
390 | r"[0-9]+\.[0-9]*(?!\.)" |
||
391 | return t |
||
392 | |||
393 | # 11.8 Numbers |
||
394 | def t_NUMBER (t): |
||
395 | r"0|([1-9][0-9]*)" |
||
396 | return t |
||
397 | |||
398 | # 11.6 Comments |
||
399 | pyquote_str = 'PYQUOTE' |
||
400 | def t_COMMENT(t): |
||
401 | r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)" |
||
402 | if (t.value.find("\n") >= 0) : t.lexer.lineno += 1 |
||
403 | if t.value[2:2+len (pyquote_str)] == pyquote_str: |
||
404 | t.value = t.value[2+len(pyquote_str):] |
||
405 | t.value = t.value.lstrip () |
||
406 | t.type = pyquote_str |
||
407 | return t |
||
408 | return None |
||
409 | |||
410 | t_ignore = " \t\r" |
||
411 | |||
412 | def t_NEWLINE(t): |
||
413 | r'\n+' |
||
414 | t.lexer.lineno += t.value.count("\n") |
||
415 | |||
416 | def t_error(t): |
||
417 | global input_file |
||
418 | raise LexError(t, input_file) |
||
419 | |||
420 | # state 'braceignore' |
||
421 | |||
422 | def t_braceignore_lbrace(t): |
||
423 | r'\{' |
||
424 | t.lexer.level +=1 |
||
425 | |||
426 | def t_braceignore_rbrace(t): |
||
427 | r'\}' |
||
428 | t.lexer.level -=1 |
||
429 | # If closing brace, return token |
||
430 | if t.lexer.level == 0: |
||
431 | t.type = 'RBRACE' |
||
432 | return t |
||
433 | |||
434 | def t_braceignore_QSTRING (t): |
||
435 | r'"([^"]|"")*"' |
||
436 | t.lexer.lineno += t.value.count("\n") |
||
437 | |||
438 | def t_braceignore_COMMENT(t): |
||
439 | r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)" |
||
440 | if (t.value.find("\n") >= 0) : t.lexer.lineno += 1 |
||
441 | |||
442 | def t_braceignore_nonspace(t): |
||
443 | r'[^\s\{\}\"-]+|-(?!-)' |
||
444 | |||
445 | t_braceignore_ignore = " \t\r" |
||
446 | |||
447 | def t_braceignore_NEWLINE(t): |
||
448 | r'\n+' |
||
449 | t.lexer.lineno += t.value.count("\n") |
||
450 | |||
451 | def t_braceignore_error(t): |
||
452 | t.lexer.skip(1) |
||
453 | |||
454 | class Ctx: |
||
455 | def __init__ (self, defined_dict, indent = 0): |
||
456 | self.tags_def = 'EXPLICIT' # default = explicit |
||
457 | self.indent_lev = 0 |
||
458 | self.assignments = {} |
||
459 | self.dependencies = {} |
||
460 | self.pyquotes = [] |
||
461 | self.defined_dict = defined_dict |
||
462 | self.name_ctr = 0 |
||
463 | def spaces (self): |
||
464 | return " " * (4 * self.indent_lev) |
||
465 | def indent (self): |
||
466 | self.indent_lev += 1 |
||
467 | def outdent (self): |
||
468 | self.indent_lev -= 1 |
||
469 | assert (self.indent_lev >= 0) |
||
470 | def register_assignment (self, ident, val, dependencies): |
||
471 | if ident in self.assignments: |
||
472 | raise DuplicateError("assignment", ident) |
||
473 | if ident in self.defined_dict: |
||
474 | raise Exception("cross-module duplicates for %s" % ident) |
||
475 | self.defined_dict [ident] = 1 |
||
476 | self.assignments[ident] = val |
||
477 | self.dependencies [ident] = dependencies |
||
478 | return "" |
||
479 | # return "#%s depends on %s" % (ident, str (dependencies)) |
||
480 | def register_pyquote (self, val): |
||
481 | self.pyquotes.append (val) |
||
482 | return "" |
||
483 | def output_assignments (self): |
||
484 | already_output = {} |
||
485 | text_list = [] |
||
486 | assign_keys = list(self.assignments.keys()) |
||
487 | to_output_count = len (assign_keys) |
||
488 | while True: |
||
489 | any_output = 0 |
||
490 | for (ident, val) in list(self.assignments.items ()): |
||
491 | if ident in already_output: |
||
492 | continue |
||
493 | ok = 1 |
||
494 | for d in self.dependencies [ident]: |
||
495 | if ((d not in already_output) and |
||
496 | (d in assign_keys)): |
||
497 | ok = 0 |
||
498 | if ok: |
||
499 | text_list.append ("%s=%s" % (ident, |
||
500 | self.assignments [ident])) |
||
501 | already_output [ident] = 1 |
||
502 | any_output = 1 |
||
503 | to_output_count -= 1 |
||
504 | assert (to_output_count >= 0) |
||
505 | if not any_output: |
||
506 | if to_output_count == 0: |
||
507 | break |
||
508 | # OK, we detected a cycle |
||
509 | cycle_list = [] |
||
510 | for ident in list(self.assignments.keys ()): |
||
511 | if ident not in already_output: |
||
512 | depend_list = [d for d in self.dependencies[ident] if d in assign_keys] |
||
513 | cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list))) |
||
514 | |||
515 | text_list.append ("# Cycle XXX " + ",".join (cycle_list)) |
||
516 | for (ident, val) in list(self.assignments.items ()): |
||
517 | if ident not in already_output: |
||
518 | text_list.append ("%s=%s" % (ident, self.assignments [ident])) |
||
519 | break |
||
520 | |||
521 | return "\n".join (text_list) |
||
522 | def output_pyquotes (self): |
||
523 | return "\n".join (self.pyquotes) |
||
524 | def make_new_name (self): |
||
525 | self.name_ctr += 1 |
||
526 | return "_compiler_generated_name_%d" % (self.name_ctr,) |
||
527 | |||
528 | #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM ------------------------------- |
||
529 | EF_TYPE = 0x0001 |
||
530 | EF_VALS = 0x0002 |
||
531 | EF_ENUM = 0x0004 |
||
532 | EF_WS_DLL = 0x0010 # exported from shared library |
||
533 | EF_EXTERN = 0x0020 |
||
534 | EF_NO_PROT = 0x0040 |
||
535 | EF_NO_TYPE = 0x0080 |
||
536 | EF_UCASE = 0x0100 |
||
537 | EF_TABLE = 0x0400 |
||
538 | EF_DEFINE = 0x0800 |
||
539 | EF_MODULE = 0x1000 |
||
540 | |||
541 | #--- common dependency computation --- |
||
542 | # Input : list of items |
||
543 | # dictionary with lists of dependency |
||
544 | # |
||
545 | # |
||
546 | # Output : list of two outputs: |
||
547 | # [0] list of items in dependency |
||
548 | # [1] list of cycle dependency cycles |
||
549 | def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False): |
||
550 | item_ord = [] |
||
551 | item_cyc = [] |
||
552 | x = {} # already emitted |
||
553 | #print '# Dependency computation' |
||
554 | for t in items: |
||
555 | if map_fn(t) in x: |
||
556 | #print 'Continue: %s : %s' % (t, (map_fn(t)) |
||
557 | continue |
||
558 | stack = [t] |
||
559 | stackx = {t : dependency.get(t, [])[:]} |
||
560 | #print 'Push: %s : %s' % (t, str(stackx[t])) |
||
561 | while stack: |
||
562 | if stackx[stack[-1]]: # has dependencies |
||
563 | d = stackx[stack[-1]].pop(0) |
||
564 | if map_fn(d) in x or ignore_fn(d): |
||
565 | continue |
||
566 | if d in stackx: # cyclic dependency |
||
567 | c = stack[:] |
||
568 | c.reverse() |
||
569 | c = [d] + c[0:c.index(d)+1] |
||
570 | c.reverse() |
||
571 | item_cyc.append(c) |
||
572 | #print 'Cyclic: %s ' % (' -> '.join(c)) |
||
573 | continue |
||
574 | stack.append(d) |
||
575 | stackx[d] = dependency.get(d, [])[:] |
||
576 | #print 'Push: %s : %s' % (d, str(stackx[d])) |
||
577 | else: |
||
578 | #print 'Pop: %s' % (stack[-1]) |
||
579 | del stackx[stack[-1]] |
||
580 | e = map_fn(stack.pop()) |
||
581 | if e in x: |
||
582 | continue |
||
583 | #print 'Add: %s' % (e) |
||
584 | item_ord.append(e) |
||
585 | x[e] = True |
||
586 | return (item_ord, item_cyc) |
||
587 | |||
588 | # Given a filename, return a relative path from the current directory |
||
589 | def relpath(filename): |
||
590 | return os.path.relpath(filename) |
||
591 | |||
592 | # Given a filename, return a relative path from epan/dissectors |
||
593 | def rel_dissector_path(filename): |
||
594 | path_parts = os.path.abspath(filename).split(os.sep) |
||
595 | while (len(path_parts) > 3 and path_parts[0] != 'asn1'): |
||
596 | path_parts.pop(0) |
||
597 | path_parts.insert(0, '.') |
||
598 | return '/'.join(path_parts) |
||
599 | |||
600 | |||
601 | #--- EthCtx ------------------------------------------------------------------- |
||
602 | class EthCtx: |
||
603 | def __init__(self, conform, output, indent = 0): |
||
604 | self.conform = conform |
||
605 | self.output = output |
||
606 | self.conform.ectx = self |
||
607 | self.output.ectx = self |
||
608 | self.encoding = 'per' |
||
609 | self.aligned = False |
||
610 | self.default_oid_variant = '' |
||
611 | self.default_opentype_variant = '' |
||
612 | self.default_containing_variant = '_pdu_new' |
||
613 | self.default_embedded_pdv_cb = None |
||
614 | self.default_external_type_cb = None |
||
615 | self.remove_prefix = None |
||
616 | self.srcdir = None |
||
617 | self.emitted_pdu = {} |
||
618 | self.module = {} |
||
619 | self.module_ord = [] |
||
620 | self.all_type_attr = {} |
||
621 | self.all_tags = {} |
||
622 | self.all_vals = {} |
||
623 | |||
624 | def encp(self): # encoding protocol |
||
625 | encp = self.encoding |
||
626 | return encp |
||
627 | |||
628 | # Encoding |
||
629 | def Per(self): return self.encoding == 'per' |
||
630 | def Ber(self): return self.encoding == 'ber' |
||
631 | def Aligned(self): return self.aligned |
||
632 | def Unaligned(self): return not self.aligned |
||
633 | def NeedTags(self): return self.tag_opt or self.Ber() |
||
634 | def NAPI(self): return False # disable planned features |
||
635 | |||
636 | def Module(self): # current module name |
||
637 | return self.modules[-1][0] |
||
638 | |||
639 | def groups(self): |
||
640 | return self.group_by_prot or (self.conform.last_group > 0) |
||
641 | |||
642 | def dbg(self, d): |
||
643 | if (self.dbgopt.find(d) >= 0): |
||
644 | return True |
||
645 | else: |
||
646 | return False |
||
647 | |||
648 | def value_max(self, a, b): |
||
649 | if (a == 'MAX') or (b == 'MAX'): return 'MAX'; |
||
650 | if a == 'MIN': return b; |
||
651 | if b == 'MIN': return a; |
||
652 | try: |
||
653 | if (int(a) > int(b)): |
||
654 | return a |
||
655 | else: |
||
656 | return b |
||
657 | except (ValueError, TypeError): |
||
658 | pass |
||
659 | return "MAX((%s),(%s))" % (a, b) |
||
660 | |||
661 | def value_min(self, a, b): |
||
662 | if (a == 'MIN') or (b == 'MIN'): return 'MIN'; |
||
663 | if a == 'MAX': return b; |
||
664 | if b == 'MAX': return a; |
||
665 | try: |
||
666 | if (int(a) < int(b)): |
||
667 | return a |
||
668 | else: |
||
669 | return b |
||
670 | except (ValueError, TypeError): |
||
671 | pass |
||
672 | return "MIN((%s),(%s))" % (a, b) |
||
673 | |||
674 | def value_get_eth(self, val): |
||
675 | if isinstance(val, Value): |
||
676 | return val.to_str(self) |
||
677 | ethname = val |
||
678 | if val in self.value: |
||
679 | ethname = self.value[val]['ethname'] |
||
680 | return ethname |
||
681 | |||
682 | def value_get_val(self, nm): |
||
683 | val = asn2c(nm) |
||
684 | if nm in self.value: |
||
685 | if self.value[nm]['import']: |
||
686 | v = self.get_val_from_all(nm, self.value[nm]['import']) |
||
687 | if v is None: |
||
688 | msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto']) |
||
689 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
690 | else: |
||
691 | val = v |
||
692 | else: |
||
693 | val = self.value[nm]['value'] |
||
694 | if isinstance (val, Value): |
||
695 | val = val.to_str(self) |
||
696 | else: |
||
697 | msg = 'Need value of unknown value identifier %s' % (nm) |
||
698 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
699 | return val |
||
700 | |||
701 | def eth_get_type_attr(self, type): |
||
702 | #print "eth_get_type_attr(%s)" % (type) |
||
703 | types = [type] |
||
704 | while (not self.type[type]['import']): |
||
705 | val = self.type[type]['val'] |
||
706 | #print val |
||
707 | ttype = type |
||
708 | while (val.type == 'TaggedType'): |
||
709 | val = val.val |
||
710 | ttype += '/' + UNTAG_TYPE_NAME |
||
711 | if (val.type != 'Type_Ref'): |
||
712 | if (type != ttype): |
||
713 | types.append(ttype) |
||
714 | break |
||
715 | type = val.val |
||
716 | types.append(type) |
||
717 | attr = {} |
||
718 | #print " ", types |
||
719 | while len(types): |
||
720 | t = types.pop() |
||
721 | if (self.type[t]['import']): |
||
722 | attr.update(self.type[t]['attr']) |
||
723 | attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import'])) |
||
724 | elif (self.type[t]['val'].type == 'SelectionType'): |
||
725 | val = self.type[t]['val'] |
||
726 | (ftype, display) = val.eth_ftype(self) |
||
727 | attr.update({ 'TYPE' : ftype, 'DISPLAY' : display, |
||
728 | 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }); |
||
729 | else: |
||
730 | attr.update(self.type[t]['attr']) |
||
731 | attr.update(self.eth_type[self.type[t]['ethname']]['attr']) |
||
732 | #print " ", attr |
||
733 | return attr |
||
734 | |||
735 | def eth_get_type_attr_from_all(self, type, module): |
||
736 | attr = {} |
||
737 | if module in self.all_type_attr and type in self.all_type_attr[module]: |
||
738 | attr = self.all_type_attr[module][type] |
||
739 | return attr |
||
740 | |||
741 | def get_ttag_from_all(self, type, module): |
||
742 | ttag = None |
||
743 | if module in self.all_tags and type in self.all_tags[module]: |
||
744 | ttag = self.all_tags[module][type] |
||
745 | return ttag |
||
746 | |||
747 | def get_val_from_all(self, nm, module): |
||
748 | val = None |
||
749 | if module in self.all_vals and nm in self.all_vals[module]: |
||
750 | val = self.all_vals[module][nm] |
||
751 | return val |
||
752 | |||
753 | def get_obj_repr(self, ident, flds=[], not_flds=[]): |
||
754 | def set_type_fn(cls, field, fnfield): |
||
755 | obj[fnfield + '_fn'] = 'NULL' |
||
756 | obj[fnfield + '_pdu'] = 'NULL' |
||
757 | if field in val and isinstance(val[field], Type_Ref): |
||
758 | p = val[field].eth_type_default_pars(self, '') |
||
759 | obj[fnfield + '_fn'] = p['TYPE_REF_FN'] |
||
760 | obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration |
||
761 | if (self.conform.check_item('PDU', cls + '.' + field)): |
||
762 | obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname'] |
||
763 | return |
||
764 | # end of get_type_fn() |
||
765 | obj = { '_name' : ident, '_ident' : asn2c(ident)} |
||
766 | obj['_class'] = self.oassign[ident].cls |
||
767 | obj['_module'] = self.oassign[ident].module |
||
768 | val = self.oassign[ident].val |
||
769 | for f in flds: |
||
770 | if f not in val: |
||
771 | return None |
||
772 | for f in not_flds: |
||
773 | if f in val: |
||
774 | return None |
||
775 | for f in list(val.keys()): |
||
776 | if isinstance(val[f], Node): |
||
777 | obj[f] = val[f].fld_obj_repr(self) |
||
778 | else: |
||
779 | obj[f] = str(val[f]) |
||
780 | if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'): |
||
781 | set_type_fn(obj['_class'], '&Type', '_type') |
||
782 | if (obj['_class'] == 'OPERATION'): |
||
783 | set_type_fn(obj['_class'], '&ArgumentType', '_argument') |
||
784 | set_type_fn(obj['_class'], '&ResultType', '_result') |
||
785 | if (obj['_class'] == 'ERROR'): |
||
786 | set_type_fn(obj['_class'], '&ParameterType', '_parameter') |
||
787 | return obj |
||
788 | |||
789 | #--- eth_reg_module ----------------------------------------------------------- |
||
790 | def eth_reg_module(self, module): |
||
791 | #print "eth_reg_module(module='%s')" % (module) |
||
792 | name = module.get_name() |
||
793 | self.modules.append([name, module.get_proto(self)]) |
||
794 | if name in self.module: |
||
795 | raise DuplicateError("module", name) |
||
796 | self.module[name] = [] |
||
797 | self.module_ord.append(name) |
||
798 | |||
799 | #--- eth_module_dep_add ------------------------------------------------------------ |
||
800 | def eth_module_dep_add(self, module, dep): |
||
801 | self.module[module].append(dep) |
||
802 | |||
803 | #--- eth_exports ------------------------------------------------------------ |
||
804 | def eth_exports(self, exports): |
||
805 | self.exports_all = False |
||
806 | if ((len(exports) == 1) and (exports[0] == 'ALL')): |
||
807 | self.exports_all = True |
||
808 | return |
||
809 | for e in (exports): |
||
810 | if isinstance(e, Type_Ref): |
||
811 | self.exports.append(e.val) |
||
812 | elif isinstance(e, Class_Ref): |
||
813 | self.cexports.append(e.val) |
||
814 | else: |
||
815 | self.vexports.append(e) |
||
816 | |||
817 | #--- eth_reg_assign --------------------------------------------------------- |
||
818 | def eth_reg_assign(self, ident, val, virt=False): |
||
819 | #print "eth_reg_assign(ident='%s')" % (ident) |
||
820 | if ident in self.assign: |
||
821 | raise DuplicateError("assignment", ident) |
||
822 | self.assign[ident] = { 'val' : val , 'virt' : virt } |
||
823 | self.assign_ord.append(ident) |
||
824 | if (self.exports_all): |
||
825 | self.exports.append(ident) |
||
826 | |||
827 | #--- eth_reg_vassign -------------------------------------------------------- |
||
828 | def eth_reg_vassign(self, vassign): |
||
829 | ident = vassign.ident |
||
830 | #print "eth_reg_vassign(ident='%s')" % (ident) |
||
831 | if ident in self.vassign: |
||
832 | raise DuplicateError("value assignment", ident) |
||
833 | self.vassign[ident] = vassign |
||
834 | self.vassign_ord.append(ident) |
||
835 | if (self.exports_all): |
||
836 | self.vexports.append(ident) |
||
837 | |||
838 | #--- eth_reg_oassign -------------------------------------------------------- |
||
839 | def eth_reg_oassign(self, oassign): |
||
840 | ident = oassign.ident |
||
841 | #print "eth_reg_oassign(ident='%s')" % (ident) |
||
842 | if ident in self.oassign: |
||
843 | if self.oassign[ident] == oassign: |
||
844 | return # OK - already defined |
||
845 | else: |
||
846 | raise DuplicateError("information object assignment", ident) |
||
847 | self.oassign[ident] = oassign |
||
848 | self.oassign_ord.append(ident) |
||
849 | self.oassign_cls.setdefault(oassign.cls, []).append(ident) |
||
850 | |||
851 | #--- eth_import_type -------------------------------------------------------- |
||
852 | def eth_import_type(self, ident, mod, proto): |
||
853 | #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto) |
||
854 | if ident in self.type: |
||
855 | #print "already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-')) |
||
856 | if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) : |
||
857 | return # OK - already defined |
||
858 | elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) : |
||
859 | return # OK - already imported |
||
860 | else: |
||
861 | raise DuplicateError("type", ident) |
||
862 | self.type[ident] = {'import' : mod, 'proto' : proto, |
||
863 | 'ethname' : '' } |
||
864 | self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE', |
||
865 | 'STRINGS' : 'NULL', 'BITMASK' : '0' } |
||
866 | mident = "$%s$%s" % (mod, ident) |
||
867 | if (self.conform.check_item('TYPE_ATTR', mident)): |
||
868 | self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', mident)) |
||
869 | else: |
||
870 | self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident)) |
||
871 | if (self.conform.check_item('IMPORT_TAG', mident)): |
||
872 | self.conform.copy_item('IMPORT_TAG', ident, mident) |
||
873 | self.type_imp.append(ident) |
||
874 | |||
875 | #--- dummy_import_type -------------------------------------------------------- |
||
876 | def dummy_import_type(self, ident): |
||
877 | # dummy imported |
||
878 | if ident in self.type: |
||
879 | raise Exception("Try to dummy import for existing type :%s" % ident) |
||
880 | ethtype = asn2c(ident) |
||
881 | self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx', |
||
882 | 'ethname' : ethtype } |
||
883 | self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE', |
||
884 | 'STRINGS' : 'NULL', 'BITMASK' : '0' } |
||
885 | self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []} |
||
886 | print("Dummy imported: %s (%s)" % (ident, ethtype)) |
||
887 | return ethtype |
||
888 | |||
889 | #--- eth_import_class -------------------------------------------------------- |
||
890 | def eth_import_class(self, ident, mod, proto): |
||
891 | #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto) |
||
892 | if ident in self.objectclass: |
||
893 | #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module']) |
||
894 | if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) : |
||
895 | return # OK - already defined |
||
896 | elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) : |
||
897 | return # OK - already imported |
||
898 | else: |
||
899 | raise DuplicateError("object class", ident) |
||
900 | self.objectclass[ident] = {'import' : mod, 'proto' : proto, |
||
901 | 'ethname' : '' } |
||
902 | self.objectclass_imp.append(ident) |
||
903 | |||
904 | #--- eth_import_value ------------------------------------------------------- |
||
905 | def eth_import_value(self, ident, mod, proto): |
||
906 | #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot) |
||
907 | if ident in self.value: |
||
908 | #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module']) |
||
909 | if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) : |
||
910 | return # OK - already defined |
||
911 | elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) : |
||
912 | return # OK - already imported |
||
913 | else: |
||
914 | raise DuplicateError("value", ident) |
||
915 | self.value[ident] = {'import' : mod, 'proto' : proto, |
||
916 | 'ethname' : ''} |
||
917 | self.value_imp.append(ident) |
||
918 | |||
919 | #--- eth_sel_req ------------------------------------------------------------ |
||
920 | def eth_sel_req(self, typ, sel): |
||
921 | key = typ + '.' + sel |
||
922 | if key not in self.sel_req: |
||
923 | self.sel_req[key] = { 'typ' : typ , 'sel' : sel} |
||
924 | self.sel_req_ord.append(key) |
||
925 | return key |
||
926 | |||
927 | #--- eth_comp_req ------------------------------------------------------------ |
||
928 | def eth_comp_req(self, type): |
||
929 | self.comp_req_ord.append(type) |
||
930 | |||
931 | #--- eth_dep_add ------------------------------------------------------------ |
||
932 | def eth_dep_add(self, type, dep): |
||
933 | if type not in self.type_dep: |
||
934 | self.type_dep[type] = [] |
||
935 | self.type_dep[type].append(dep) |
||
936 | |||
937 | #--- eth_reg_type ----------------------------------------------------------- |
||
938 | def eth_reg_type(self, ident, val): |
||
939 | #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type) |
||
940 | if ident in self.type: |
||
941 | if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) : |
||
942 | # replace imported type |
||
943 | del self.type[ident] |
||
944 | self.type_imp.remove(ident) |
||
945 | else: |
||
946 | raise DuplicateError("type", ident) |
||
947 | val.ident = ident |
||
948 | self.type[ident] = { 'val' : val, 'import' : None } |
||
949 | self.type[ident]['module'] = self.Module() |
||
950 | self.type[ident]['proto'] = self.proto |
||
951 | if len(ident.split('/')) > 1: |
||
952 | self.type[ident]['tname'] = val.eth_tname() |
||
953 | else: |
||
954 | self.type[ident]['tname'] = asn2c(ident) |
||
955 | self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident) |
||
956 | self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident) |
||
957 | self.type[ident]['vals_ext'] = self.conform.use_item('USE_VALS_EXT', ident) |
||
958 | self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident) |
||
959 | self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident) |
||
960 | self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname']) |
||
961 | self.type[ident]['ethname'] = '' |
||
962 | if (val.type == 'Type_Ref') or (val.type == 'TaggedType') or (val.type == 'SelectionType') : |
||
963 | self.type[ident]['attr'] = {} |
||
964 | else: |
||
965 | (ftype, display) = val.eth_ftype(self) |
||
966 | self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display, |
||
967 | 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' } |
||
968 | self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident)) |
||
969 | self.type_ord.append(ident) |
||
970 | # PDU |
||
971 | if (self.conform.check_item('PDU', ident)): |
||
972 | self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident)) |
||
973 | |||
974 | #--- eth_reg_objectclass ---------------------------------------------------------- |
||
975 | def eth_reg_objectclass(self, ident, val): |
||
976 | #print "eth_reg_objectclass(ident='%s')" % (ident) |
||
977 | if ident in self.objectclass: |
||
978 | if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) : |
||
979 | # replace imported object class |
||
980 | del self.objectclass[ident] |
||
981 | self.objectclass_imp.remove(ident) |
||
982 | elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \ |
||
983 | isinstance(val, Class_Ref) and \ |
||
984 | (self.objectclass[ident]['val'].val == val.val): |
||
985 | pass # ignore duplicated CLASS1 ::= CLASS2 |
||
986 | else: |
||
987 | raise DuplicateError("object class", ident) |
||
988 | self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto } |
||
989 | self.objectclass[ident]['val'] = val |
||
990 | self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident) |
||
991 | self.objectclass_ord.append(ident) |
||
992 | |||
993 | #--- eth_reg_value ---------------------------------------------------------- |
||
994 | def eth_reg_value(self, ident, type, value, ethname=None): |
||
995 | #print "eth_reg_value(ident='%s')" % (ident) |
||
996 | if ident in self.value: |
||
997 | if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) : |
||
998 | # replace imported value |
||
999 | del self.value[ident] |
||
1000 | self.value_imp.remove(ident) |
||
1001 | elif ethname: |
||
1002 | self.value[ident]['ethname'] = ethname |
||
1003 | return |
||
1004 | else: |
||
1005 | raise DuplicateError("value", ident) |
||
1006 | self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto, |
||
1007 | 'type' : type, 'value' : value, |
||
1008 | 'no_emit' : False } |
||
1009 | self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident) |
||
1010 | self.value[ident]['ethname'] = '' |
||
1011 | if (ethname): self.value[ident]['ethname'] = ethname |
||
1012 | self.value_ord.append(ident) |
||
1013 | |||
1014 | #--- eth_reg_field ---------------------------------------------------------- |
||
1015 | def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None): |
||
1016 | #print "eth_reg_field(ident='%s', type='%s')" % (ident, type) |
||
1017 | if ident in self.field: |
||
1018 | if pdu and (type == self.field[ident]['type']): |
||
1019 | pass # OK already created PDU |
||
1020 | else: |
||
1021 | raise DuplicateError("field", ident) |
||
1022 | self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu, |
||
1023 | 'modified' : '', 'attr' : {} } |
||
1024 | name = ident.split('/')[-1] |
||
1025 | if self.remove_prefix and name.startswith(self.remove_prefix): |
||
1026 | name = name[len(self.remove_prefix):] |
||
1027 | |||
1028 | if len(ident.split('/')) > 1 and name == ITEM_FIELD_NAME: # Sequence/Set of type |
||
1029 | if len(self.field[ident]['type'].split('/')) > 1: |
||
1030 | self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2] |
||
1031 | self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name) |
||
1032 | else: |
||
1033 | self.field[ident]['attr']['NAME'] = '"%s"' % self.field[ident]['type'] |
||
1034 | self.field[ident]['attr']['ABBREV'] = asn2c(self.field[ident]['type']) |
||
1035 | else: |
||
1036 | self.field[ident]['attr']['NAME'] = '"%s"' % name |
||
1037 | self.field[ident]['attr']['ABBREV'] = asn2c(name) |
||
1038 | if self.conform.check_item('FIELD_ATTR', ident): |
||
1039 | self.field[ident]['modified'] = '#' + str(id(self)) |
||
1040 | self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident)) |
||
1041 | if (pdu): |
||
1042 | self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0) |
||
1043 | self.pdu_ord.append(ident) |
||
1044 | else: |
||
1045 | self.field_ord.append(ident) |
||
1046 | if parent: |
||
1047 | self.eth_dep_add(parent, type) |
||
1048 | |||
1049 | def eth_dummy_eag_field_required(self): |
||
1050 | if (not self.dummy_eag_field): |
||
1051 | self.dummy_eag_field = 'eag_field' |
||
1052 | |||
1053 | #--- eth_clean -------------------------------------------------------------- |
||
1054 | def eth_clean(self): |
||
1055 | self.proto = self.proto_opt; |
||
1056 | #--- ASN.1 tables ---------------- |
||
1057 | self.assign = {} |
||
1058 | self.assign_ord = [] |
||
1059 | self.field = {} |
||
1060 | self.pdu_ord = [] |
||
1061 | self.field_ord = [] |
||
1062 | self.type = {} |
||
1063 | self.type_ord = [] |
||
1064 | self.type_imp = [] |
||
1065 | self.type_dep = {} |
||
1066 | self.sel_req = {} |
||
1067 | self.sel_req_ord = [] |
||
1068 | self.comp_req_ord = [] |
||
1069 | self.vassign = {} |
||
1070 | self.vassign_ord = [] |
||
1071 | self.value = {} |
||
1072 | self.value_ord = [] |
||
1073 | self.value_imp = [] |
||
1074 | self.objectclass = {} |
||
1075 | self.objectclass_ord = [] |
||
1076 | self.objectclass_imp = [] |
||
1077 | self.oassign = {} |
||
1078 | self.oassign_ord = [] |
||
1079 | self.oassign_cls = {} |
||
1080 | #--- Modules ------------ |
||
1081 | self.modules = [] |
||
1082 | self.exports_all = False |
||
1083 | self.exports = [] |
||
1084 | self.cexports = [] |
||
1085 | self.vexports = [] |
||
1086 | #--- types ------------------- |
||
1087 | self.eth_type = {} |
||
1088 | self.eth_type_ord = [] |
||
1089 | self.eth_export_ord = [] |
||
1090 | self.eth_type_dupl = {} |
||
1091 | self.named_bit = [] |
||
1092 | #--- value dependencies ------------------- |
||
1093 | self.value_dep = {} |
||
1094 | #--- values ------------------- |
||
1095 | self.eth_value = {} |
||
1096 | self.eth_value_ord = [] |
||
1097 | #--- fields ------------------------- |
||
1098 | self.eth_hf = {} |
||
1099 | self.eth_hf_ord = [] |
||
1100 | self.eth_hfpdu_ord = [] |
||
1101 | self.eth_hf_dupl = {} |
||
1102 | self.dummy_eag_field = None |
||
1103 | #--- type dependencies ------------------- |
||
1104 | self.eth_type_ord1 = [] |
||
1105 | self.eth_dep_cycle = [] |
||
1106 | self.dep_cycle_eth_type = {} |
||
1107 | #--- value dependencies and export ------------------- |
||
1108 | self.eth_value_ord1 = [] |
||
1109 | self.eth_vexport_ord = [] |
||
1110 | |||
1111 | #--- eth_prepare ------------------------------------------------------------ |
||
1112 | def eth_prepare(self): |
||
1113 | self.eproto = asn2c(self.proto) |
||
1114 | |||
1115 | #--- dummy types/fields for PDU registration --- |
||
1116 | nm = 'NULL' |
||
1117 | if (self.conform.check_item('PDU', nm)): |
||
1118 | self.eth_reg_type('_dummy/'+nm, NullType()) |
||
1119 | self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm)) |
||
1120 | |||
1121 | #--- required PDUs ---------------------------- |
||
1122 | for t in self.type_ord: |
||
1123 | pdu = self.type[t]['val'].eth_need_pdu(self) |
||
1124 | if not pdu: continue |
||
1125 | f = pdu['type'] |
||
1126 | pdu['reg'] = None |
||
1127 | pdu['hidden'] = False |
||
1128 | pdu['need_decl'] = True |
||
1129 | if f not in self.field: |
||
1130 | self.eth_reg_field(f, f, pdu=pdu) |
||
1131 | |||
1132 | #--- values -> named values ------------------- |
||
1133 | t_for_update = {} |
||
1134 | for v in self.value_ord: |
||
1135 | if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v): |
||
1136 | if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v): |
||
1137 | tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v) |
||
1138 | else: |
||
1139 | tnm = self.value[v]['type'].val |
||
1140 | if tnm in self.type \ |
||
1141 | and not self.type[tnm]['import'] \ |
||
1142 | and (self.type[tnm]['val'].type == 'IntegerType'): |
||
1143 | self.type[tnm]['val'].add_named_value(v, self.value[v]['value']) |
||
1144 | self.value[v]['no_emit'] = True |
||
1145 | t_for_update[tnm] = True |
||
1146 | for t in list(t_for_update.keys()): |
||
1147 | self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings() |
||
1148 | self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t)) |
||
1149 | |||
1150 | #--- required components of --------------------------- |
||
1151 | #print "self.comp_req_ord = ", self.comp_req_ord |
||
1152 | for t in self.comp_req_ord: |
||
1153 | self.type[t]['val'].eth_reg_sub(t, self, components_available=True) |
||
1154 | |||
1155 | #--- required selection types --------------------------- |
||
1156 | #print "self.sel_req_ord = ", self.sel_req_ord |
||
1157 | for t in self.sel_req_ord: |
||
1158 | tt = self.sel_req[t]['typ'] |
||
1159 | if tt not in self.type: |
||
1160 | self.dummy_import_type(t) |
||
1161 | elif self.type[tt]['import']: |
||
1162 | self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto']) |
||
1163 | else: |
||
1164 | self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self) |
||
1165 | |||
1166 | #--- types ------------------- |
||
1167 | for t in self.type_imp: # imported types |
||
1168 | nm = asn2c(t) |
||
1169 | self.eth_type[nm] = { 'import' : self.type[t]['import'], |
||
1170 | 'proto' : asn2c(self.type[t]['proto']), |
||
1171 | 'attr' : {}, 'ref' : []} |
||
1172 | self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm)) |
||
1173 | self.type[t]['ethname'] = nm |
||
1174 | for t in self.type_ord: # dummy import for missing type reference |
||
1175 | tp = self.type[t]['val'] |
||
1176 | #print "X : %s %s " % (t, tp.type) |
||
1177 | if isinstance(tp, TaggedType): |
||
1178 | #print "%s : %s " % (tp.type, t) |
||
1179 | tp = tp.val |
||
1180 | if isinstance(tp, Type_Ref): |
||
1181 | #print "%s : %s ::= %s " % (tp.type, t, tp.val) |
||
1182 | if tp.val not in self.type: |
||
1183 | self.dummy_import_type(tp.val) |
||
1184 | for t in self.type_ord: |
||
1185 | nm = self.type[t]['tname'] |
||
1186 | if ((nm.find('#') >= 0) or |
||
1187 | ((len(t.split('/'))>1) and |
||
1188 | (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or |
||
1189 | self.conform.get_fn_presence('/'.join((t,ITEM_FIELD_NAME))) or self.conform.check_item('FN_PARS', '/'.join((t,ITEM_FIELD_NAME)))) and |
||
1190 | not self.conform.check_item('TYPE_RENAME', t))): |
||
1191 | if len(t.split('/')) == 2 and t.split('/')[1] == ITEM_FIELD_NAME: # Sequence of type at the 1st level |
||
1192 | nm = t.split('/')[0] + t.split('/')[1] |
||
1193 | elif t.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type at next levels |
||
1194 | nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1] |
||
1195 | elif t.split('/')[-1] == UNTAG_TYPE_NAME: # Untagged type |
||
1196 | nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U' |
||
1197 | else: |
||
1198 | nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1]) |
||
1199 | nm = asn2c(nm) |
||
1200 | if nm in self.eth_type: |
||
1201 | if nm in self.eth_type_dupl: |
||
1202 | self.eth_type_dupl[nm].append(t) |
||
1203 | else: |
||
1204 | self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t] |
||
1205 | nm += '_%02d' % (len(self.eth_type_dupl[nm])-1) |
||
1206 | if nm in self.eth_type: |
||
1207 | self.eth_type[nm]['ref'].append(t) |
||
1208 | else: |
||
1209 | self.eth_type_ord.append(nm) |
||
1210 | self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0, 'vals_ext' : 0, |
||
1211 | 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS, |
||
1212 | 'val' : self.type[t]['val'], |
||
1213 | 'attr' : {}, 'ref' : [t]} |
||
1214 | self.type[t]['ethname'] = nm |
||
1215 | if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export |
||
1216 | self.eth_export_ord.append(nm) |
||
1217 | self.eth_type[nm]['export'] |= self.type[t]['export'] |
||
1218 | self.eth_type[nm]['enum'] |= self.type[t]['enum'] |
||
1219 | self.eth_type[nm]['vals_ext'] |= self.type[t]['vals_ext'] |
||
1220 | self.eth_type[nm]['user_def'] &= self.type[t]['user_def'] |
||
1221 | self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit'] |
||
1222 | if self.type[t]['attr'].get('STRINGS') == '$$': |
||
1223 | use_ext = self.type[t]['vals_ext'] |
||
1224 | if (use_ext): |
||
1225 | self.eth_type[nm]['attr']['STRINGS'] = '&%s_ext' % (self.eth_vals_nm(nm)) |
||
1226 | else: |
||
1227 | self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm)) |
||
1228 | self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm)) |
||
1229 | for t in self.eth_type_ord: |
||
1230 | bits = self.eth_type[t]['val'].eth_named_bits() |
||
1231 | if (bits): |
||
1232 | for (val, id) in bits: |
||
1233 | self.named_bit.append({'name' : id, 'val' : val, |
||
1234 | 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)), |
||
1235 | 'ftype' : 'FT_BOOLEAN', 'display' : '8', |
||
1236 | 'strings' : 'NULL', |
||
1237 | 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]}) |
||
1238 | if self.eth_type[t]['val'].eth_need_tree(): |
||
1239 | self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t) |
||
1240 | else: |
||
1241 | self.eth_type[t]['tree'] = None |
||
1242 | |||
1243 | #--- register values from enums ------------ |
||
1244 | for t in self.eth_type_ord: |
||
1245 | if (self.eth_type[t]['val'].eth_has_enum(t, self)): |
||
1246 | self.eth_type[t]['val'].reg_enum_vals(t, self) |
||
1247 | |||
1248 | #--- value dependencies ------------------- |
||
1249 | for v in self.value_ord: |
||
1250 | if isinstance (self.value[v]['value'], Value): |
||
1251 | dep = self.value[v]['value'].get_dep() |
||
1252 | else: |
||
1253 | dep = self.value[v]['value'] |
||
1254 | if dep and dep in self.value: |
||
1255 | self.value_dep.setdefault(v, []).append(dep) |
||
1256 | |||
1257 | #--- exports all necessary values |
||
1258 | for v in self.value_ord: |
||
1259 | if not self.value[v]['export']: continue |
||
1260 | deparr = self.value_dep.get(v, []) |
||
1261 | while deparr: |
||
1262 | d = deparr.pop() |
||
1263 | if not self.value[d]['import']: |
||
1264 | if not self.value[d]['export']: |
||
1265 | self.value[d]['export'] = EF_TYPE |
||
1266 | deparr.extend(self.value_dep.get(d, [])) |
||
1267 | |||
1268 | #--- values ------------------- |
||
1269 | for v in self.value_imp: |
||
1270 | nm = asn2c(v) |
||
1271 | self.eth_value[nm] = { 'import' : self.value[v]['import'], |
||
1272 | 'proto' : asn2c(self.value[v]['proto']), |
||
1273 | 'ref' : []} |
||
1274 | self.value[v]['ethname'] = nm |
||
1275 | for v in self.value_ord: |
||
1276 | if (self.value[v]['ethname']): |
||
1277 | continue |
||
1278 | if (self.value[v]['no_emit']): |
||
1279 | continue |
||
1280 | nm = asn2c(v) |
||
1281 | self.eth_value[nm] = { 'import' : None, |
||
1282 | 'proto' : asn2c(self.value[v]['proto']), |
||
1283 | 'export' : self.value[v]['export'], 'ref' : [v] } |
||
1284 | self.eth_value[nm]['value'] = self.value[v]['value'] |
||
1285 | self.eth_value_ord.append(nm) |
||
1286 | self.value[v]['ethname'] = nm |
||
1287 | |||
1288 | #--- fields ------------------------- |
||
1289 | for f in (self.pdu_ord + self.field_ord): |
||
1290 | if len(f.split('/')) > 1 and f.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type |
||
1291 | nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1] |
||
1292 | else: |
||
1293 | nm = f.split('/')[-1] |
||
1294 | nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm) |
||
1295 | nm = asn2c(nm) |
||
1296 | if (self.field[f]['pdu']): |
||
1297 | nm += '_PDU' |
||
1298 | if (not self.merge_modules or self.field[f]['pdu']['export']): |
||
1299 | nm = self.eproto + '_' + nm |
||
1300 | t = self.field[f]['type'] |
||
1301 | if t in self.type: |
||
1302 | ethtype = self.type[t]['ethname'] |
||
1303 | else: # undefined type |
||
1304 | ethtype = self.dummy_import_type(t) |
||
1305 | ethtypemod = ethtype + self.field[f]['modified'] |
||
1306 | if nm in self.eth_hf: |
||
1307 | if nm in self.eth_hf_dupl: |
||
1308 | if ethtypemod in self.eth_hf_dupl[nm]: |
||
1309 | nm = self.eth_hf_dupl[nm][ethtypemod] |
||
1310 | self.eth_hf[nm]['ref'].append(f) |
||
1311 | self.field[f]['ethname'] = nm |
||
1312 | continue |
||
1313 | else: |
||
1314 | nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm]))) |
||
1315 | self.eth_hf_dupl[nm][ethtype] = nmx |
||
1316 | nm = nmx |
||
1317 | else: |
||
1318 | if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod: |
||
1319 | self.eth_hf[nm]['ref'].append(f) |
||
1320 | self.field[f]['ethname'] = nm |
||
1321 | continue |
||
1322 | else: |
||
1323 | nmx = nm + '_01' |
||
1324 | self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \ |
||
1325 | ethtypemod : nmx} |
||
1326 | nm = nmx |
||
1327 | if (self.field[f]['pdu']): |
||
1328 | self.eth_hfpdu_ord.append(nm) |
||
1329 | else: |
||
1330 | self.eth_hf_ord.append(nm) |
||
1331 | fullname = 'hf_%s_%s' % (self.eproto, nm) |
||
1332 | attr = self.eth_get_type_attr(self.field[f]['type']).copy() |
||
1333 | attr.update(self.field[f]['attr']) |
||
1334 | if (self.NAPI() and 'NAME' in attr): |
||
1335 | attr['NAME'] += self.field[f]['idx'] |
||
1336 | attr.update(self.conform.use_item('EFIELD_ATTR', nm)) |
||
1337 | use_vals_ext = self.eth_type[ethtype].get('vals_ext') |
||
1338 | if (use_vals_ext): |
||
1339 | attr['DISPLAY'] += '|BASE_EXT_STRING' |
||
1340 | self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'], |
||
1341 | 'ethtype' : ethtype, 'modified' : self.field[f]['modified'], |
||
1342 | 'attr' : attr.copy(), |
||
1343 | 'ref' : [f]} |
||
1344 | self.field[f]['ethname'] = nm |
||
1345 | if (self.dummy_eag_field): |
||
1346 | # Prepending "dummy_" avoids matching checkhf.pl. |
||
1347 | self.dummy_eag_field = 'dummy_hf_%s_%s' % (self.eproto, self.dummy_eag_field) |
||
1348 | #--- type dependencies ------------------- |
||
1349 | (self.eth_type_ord1, self.eth_dep_cycle) = dependency_compute(self.type_ord, self.type_dep, map_fn = lambda t: self.type[t]['ethname'], ignore_fn = lambda t: self.type[t]['import']) |
||
1350 | i = 0 |
||
1351 | while i < len(self.eth_dep_cycle): |
||
1352 | t = self.type[self.eth_dep_cycle[i][0]]['ethname'] |
||
1353 | self.dep_cycle_eth_type.setdefault(t, []).append(i) |
||
1354 | i += 1 |
||
1355 | |||
1356 | #--- value dependencies and export ------------------- |
||
1357 | for v in self.eth_value_ord: |
||
1358 | if self.eth_value[v]['export']: |
||
1359 | self.eth_vexport_ord.append(v) |
||
1360 | else: |
||
1361 | self.eth_value_ord1.append(v) |
||
1362 | |||
1363 | #--- export tags, values, ... --- |
||
1364 | for t in self.exports: |
||
1365 | if t not in self.type: |
||
1366 | continue |
||
1367 | if self.type[t]['import']: |
||
1368 | continue |
||
1369 | m = self.type[t]['module'] |
||
1370 | if not self.Per(): |
||
1371 | if m not in self.all_tags: |
||
1372 | self.all_tags[m] = {} |
||
1373 | self.all_tags[m][t] = self.type[t]['val'].GetTTag(self) |
||
1374 | if m not in self.all_type_attr: |
||
1375 | self.all_type_attr[m] = {} |
||
1376 | self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy() |
||
1377 | for v in self.vexports: |
||
1378 | if v not in self.value: |
||
1379 | continue |
||
1380 | if self.value[v]['import']: |
||
1381 | continue |
||
1382 | m = self.value[v]['module'] |
||
1383 | if m not in self.all_vals: |
||
1384 | self.all_vals[m] = {} |
||
1385 | vv = self.value[v]['value'] |
||
1386 | if isinstance (vv, Value): |
||
1387 | vv = vv.to_str(self) |
||
1388 | self.all_vals[m][v] = vv |
||
1389 | |||
1390 | #--- eth_vals_nm ------------------------------------------------------------ |
||
1391 | def eth_vals_nm(self, tname): |
||
1392 | out = "" |
||
1393 | if (not self.eth_type[tname]['export'] & EF_NO_PROT): |
||
1394 | out += "%s_" % (self.eproto) |
||
1395 | out += "%s_vals" % (tname) |
||
1396 | return out |
||
1397 | |||
1398 | #--- eth_vals --------------------------------------------------------------- |
||
1399 | def eth_vals(self, tname, vals): |
||
1400 | out = "" |
||
1401 | has_enum = self.eth_type[tname]['enum'] & EF_ENUM |
||
1402 | use_ext = self.eth_type[tname]['vals_ext'] |
||
1403 | if (use_ext): |
||
1404 | vals.sort(key=lambda vals_entry: int(vals_entry[0])) |
||
1405 | if (not self.eth_type[tname]['export'] & EF_VALS): |
||
1406 | out += 'static ' |
||
1407 | if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE): |
||
1408 | out += 'static ' |
||
1409 | out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname)) |
||
1410 | for (val, id) in vals: |
||
1411 | if (has_enum): |
||
1412 | vval = self.eth_enum_item(tname, id) |
||
1413 | else: |
||
1414 | vval = val |
||
1415 | out += ' { %3s, "%s" },\n' % (vval, id) |
||
1416 | out += " { 0, NULL }\n};\n" |
||
1417 | if (use_ext): |
||
1418 | out += "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self.eth_vals_nm(tname), self.eth_vals_nm(tname)) |
||
1419 | return out |
||
1420 | |||
1421 | #--- eth_enum_prefix ------------------------------------------------------------ |
||
1422 | def eth_enum_prefix(self, tname, type=False): |
||
1423 | out = "" |
||
1424 | if (self.eth_type[tname]['export'] & EF_ENUM): |
||
1425 | no_prot = self.eth_type[tname]['export'] & EF_NO_PROT |
||
1426 | else: |
||
1427 | no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT |
||
1428 | if (not no_prot): |
||
1429 | out += self.eproto |
||
1430 | if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type): |
||
1431 | if (out): out += '_' |
||
1432 | out += tname |
||
1433 | if (self.eth_type[tname]['enum'] & EF_UCASE): |
||
1434 | out = out.upper() |
||
1435 | if (out): out += '_' |
||
1436 | return out |
||
1437 | |||
1438 | #--- eth_enum_nm ------------------------------------------------------------ |
||
1439 | def eth_enum_nm(self, tname): |
||
1440 | out = self.eth_enum_prefix(tname, type=True) |
||
1441 | out += "enum" |
||
1442 | return out |
||
1443 | |||
1444 | #--- eth_enum_item --------------------------------------------------------------- |
||
1445 | def eth_enum_item(self, tname, ident): |
||
1446 | out = self.eth_enum_prefix(tname) |
||
1447 | out += asn2c(ident) |
||
1448 | if (self.eth_type[tname]['enum'] & EF_UCASE): |
||
1449 | out = out.upper() |
||
1450 | return out |
||
1451 | |||
1452 | #--- eth_enum --------------------------------------------------------------- |
||
1453 | def eth_enum(self, tname, vals): |
||
1454 | out = "" |
||
1455 | if (self.eth_type[tname]['enum'] & EF_DEFINE): |
||
1456 | out += "/* enumerated values for %s */\n" % (tname) |
||
1457 | for (val, id) in vals: |
||
1458 | out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val) |
||
1459 | else: |
||
1460 | out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname)) |
||
1461 | first_line = 1 |
||
1462 | for (val, id) in vals: |
||
1463 | if (first_line == 1): |
||
1464 | first_line = 0 |
||
1465 | else: |
||
1466 | out += ",\n" |
||
1467 | out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val) |
||
1468 | out += "\n} %s;\n" % (self.eth_enum_nm(tname)) |
||
1469 | return out |
||
1470 | |||
1471 | #--- eth_bits --------------------------------------------------------------- |
||
1472 | def eth_bits(self, tname, bits): |
||
1473 | out = "" |
||
1474 | out += "static const " |
||
1475 | out += "asn_namedbit %(TABLE)s[] = {\n" |
||
1476 | for (val, id) in bits: |
||
1477 | out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id) |
||
1478 | out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n" |
||
1479 | return out |
||
1480 | |||
1481 | #--- eth_type_fn_h ---------------------------------------------------------- |
||
1482 | def eth_type_fn_h(self, tname): |
||
1483 | out = "" |
||
1484 | if (not self.eth_type[tname]['export'] & EF_TYPE): |
||
1485 | out += 'static ' |
||
1486 | out += "int " |
||
1487 | if (self.Ber()): |
||
1488 | out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname) |
||
1489 | elif (self.Per()): |
||
1490 | out += "dissect_%s_%s(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname) |
||
1491 | out += ";\n" |
||
1492 | return out |
||
1493 | |||
1494 | #--- eth_fn_call ------------------------------------------------------------ |
||
1495 | def eth_fn_call(self, fname, ret=None, indent=2, par=None): |
||
1496 | out = indent * ' ' |
||
1497 | if (ret): |
||
1498 | if (ret == 'return'): |
||
1499 | out += 'return ' |
||
1500 | else: |
||
1501 | out += ret + ' = ' |
||
1502 | out += fname + '(' |
||
1503 | ind = len(out) |
||
1504 | for i in range(len(par)): |
||
1505 | if (i>0): out += ind * ' ' |
||
1506 | out += ', '.join(par[i]) |
||
1507 | if (i<(len(par)-1)): out += ',\n' |
||
1508 | out += ');\n' |
||
1509 | return out |
||
1510 | |||
1511 | #--- eth_type_fn_hdr -------------------------------------------------------- |
||
1512 | def eth_type_fn_hdr(self, tname): |
||
1513 | out = '\n' |
||
1514 | if (not self.eth_type[tname]['export'] & EF_TYPE): |
||
1515 | out += 'static ' |
||
1516 | out += "int\n" |
||
1517 | if (self.Ber()): |
||
1518 | out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname) |
||
1519 | elif (self.Per()): |
||
1520 | out += "dissect_%s_%s(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname) |
||
1521 | #if self.conform.get_fn_presence(tname): |
||
1522 | # out += self.conform.get_fn_text(tname, 'FN_HDR') |
||
1523 | #el |
||
1524 | if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]): |
||
1525 | out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR') |
||
1526 | return out |
||
1527 | |||
1528 | #--- eth_type_fn_ftr -------------------------------------------------------- |
||
1529 | def eth_type_fn_ftr(self, tname): |
||
1530 | out = '\n' |
||
1531 | #if self.conform.get_fn_presence(tname): |
||
1532 | # out += self.conform.get_fn_text(tname, 'FN_FTR') |
||
1533 | #el |
||
1534 | if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]): |
||
1535 | out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR') |
||
1536 | out += " return offset;\n" |
||
1537 | out += "}\n" |
||
1538 | return out |
||
1539 | |||
1540 | #--- eth_type_fn_body ------------------------------------------------------- |
||
1541 | def eth_type_fn_body(self, tname, body, pars=None): |
||
1542 | out = body |
||
1543 | #if self.conform.get_fn_body_presence(tname): |
||
1544 | # out = self.conform.get_fn_text(tname, 'FN_BODY') |
||
1545 | #el |
||
1546 | if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]): |
||
1547 | out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY') |
||
1548 | if pars: |
||
1549 | try: |
||
1550 | out = out % pars |
||
1551 | except (TypeError): |
||
1552 | pass |
||
1553 | return out |
||
1554 | |||
1555 | #--- eth_out_pdu_decl ---------------------------------------------------------- |
||
1556 | def eth_out_pdu_decl(self, f): |
||
1557 | t = self.eth_hf[f]['ethtype'] |
||
1558 | out = '' |
||
1559 | if (not self.eth_hf[f]['pdu']['export']): |
||
1560 | out += 'static ' |
||
1561 | out += 'int ' |
||
1562 | out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n' |
||
1563 | return out |
||
1564 | |||
1565 | #--- eth_output_hf ---------------------------------------------------------- |
||
1566 | def eth_output_hf (self): |
||
1567 | if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return |
||
1568 | fx = self.output.file_open('hf') |
||
1569 | for f in (self.eth_hfpdu_ord + self.eth_hf_ord): |
||
1570 | fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype'])) |
||
1571 | if (self.named_bit): |
||
1572 | fx.write('/* named bits */\n') |
||
1573 | for nb in self.named_bit: |
||
1574 | fx.write("static int %s = -1;\n" % (nb['ethname'])) |
||
1575 | if (self.dummy_eag_field): |
||
1576 | fx.write("static int %s = -1; /* never registered */\n" % (self.dummy_eag_field)) |
||
1577 | self.output.file_close(fx) |
||
1578 | |||
1579 | #--- eth_output_hf_arr ------------------------------------------------------ |
||
1580 | def eth_output_hf_arr (self): |
||
1581 | if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return |
||
1582 | fx = self.output.file_open('hfarr') |
||
1583 | for f in (self.eth_hfpdu_ord + self.eth_hf_ord): |
||
1584 | t = self.eth_hf[f]['ethtype'] |
||
1585 | if self.remove_prefix and t.startswith(self.remove_prefix): |
||
1586 | t = t[len(self.remove_prefix):] |
||
1587 | name=self.eth_hf[f]['attr']['NAME'] |
||
1588 | try: # Python < 3 |
||
1589 | trantab = maketrans("- ", "__") |
||
1590 | except: |
||
1591 | trantab = str.maketrans("- ", "__") |
||
1592 | name = name.translate(trantab) |
||
1593 | namelower = name.lower() |
||
1594 | tquoted_lower = '"' + t.lower() + '"' |
||
1595 | # Try to avoid giving blurbs that give no more info than the name |
||
1596 | if tquoted_lower == namelower or \ |
||
1597 | t == "NULL" or \ |
||
1598 | tquoted_lower.replace("t_", "") == namelower: |
||
1599 | blurb = 'NULL' |
||
1600 | else: |
||
1601 | blurb = '"%s"' % (t) |
||
1602 | attr = self.eth_hf[f]['attr'].copy() |
||
1603 | if attr['TYPE'] == 'FT_NONE': |
||
1604 | attr['ABBREV'] = '"%s.%s_element"' % (self.proto, attr['ABBREV']) |
||
1605 | else: |
||
1606 | attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV']) |
||
1607 | if 'BLURB' not in attr: |
||
1608 | attr['BLURB'] = blurb |
||
1609 | fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname'])) |
||
1610 | fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr) |
||
1611 | fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr) |
||
1612 | fx.write(' %(BLURB)s, HFILL }},\n' % attr) |
||
1613 | for nb in self.named_bit: |
||
1614 | fx.write(' { &%s,\n' % (nb['ethname'])) |
||
1615 | fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name'])) |
||
1616 | fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask'])) |
||
1617 | fx.write(' NULL, HFILL }},\n') |
||
1618 | self.output.file_close(fx) |
||
1619 | |||
1620 | #--- eth_output_ett --------------------------------------------------------- |
||
1621 | def eth_output_ett (self): |
||
1622 | fx = self.output.file_open('ett') |
||
1623 | fempty = True |
||
1624 | #fx.write("static gint ett_%s = -1;\n" % (self.eproto)) |
||
1625 | for t in self.eth_type_ord: |
||
1626 | if self.eth_type[t]['tree']: |
||
1627 | fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree'])) |
||
1628 | fempty = False |
||
1629 | self.output.file_close(fx, discard=fempty) |
||
1630 | |||
1631 | #--- eth_output_ett_arr ----------------------------------------------------- |
||
1632 | def eth_output_ett_arr(self): |
||
1633 | fx = self.output.file_open('ettarr') |
||
1634 | fempty = True |
||
1635 | #fx.write(" &ett_%s,\n" % (self.eproto)) |
||
1636 | for t in self.eth_type_ord: |
||
1637 | if self.eth_type[t]['tree']: |
||
1638 | fx.write(" &%s,\n" % (self.eth_type[t]['tree'])) |
||
1639 | fempty = False |
||
1640 | self.output.file_close(fx, discard=fempty) |
||
1641 | |||
1642 | #--- eth_output_export ------------------------------------------------------ |
||
1643 | def eth_output_export(self): |
||
1644 | fx = self.output.file_open('exp', ext='h') |
||
1645 | for t in self.eth_export_ord: # vals |
||
1646 | if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self): |
||
1647 | fx.write(self.eth_type[t]['val'].eth_type_enum(t, self)) |
||
1648 | if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals(): |
||
1649 | if not self.eth_type[t]['export'] & EF_TABLE: |
||
1650 | if self.eth_type[t]['export'] & EF_WS_DLL: |
||
1651 | fx.write("WS_DLL_PUBLIC ") |
||
1652 | else: |
||
1653 | fx.write("extern ") |
||
1654 | fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t))) |
||
1655 | else: |
||
1656 | fx.write(self.eth_type[t]['val'].eth_type_vals(t, self)) |
||
1657 | for t in self.eth_export_ord: # functions |
||
1658 | if (self.eth_type[t]['export'] & EF_TYPE): |
||
1659 | if self.eth_type[t]['export'] & EF_EXTERN: |
||
1660 | if self.eth_type[t]['export'] & EF_WS_DLL: |
||
1661 | fx.write("WS_DLL_PUBLIC ") |
||
1662 | else: |
||
1663 | fx.write("extern ") |
||
1664 | fx.write(self.eth_type_fn_h(t)) |
||
1665 | for f in self.eth_hfpdu_ord: # PDUs |
||
1666 | if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']): |
||
1667 | fx.write(self.eth_out_pdu_decl(f)) |
||
1668 | self.output.file_close(fx) |
||
1669 | |||
1670 | #--- eth_output_expcnf ------------------------------------------------------ |
||
1671 | def eth_output_expcnf(self): |
||
1672 | fx = self.output.file_open('exp', ext='cnf') |
||
1673 | fx.write('#.MODULE\n') |
||
1674 | maxw = 0 |
||
1675 | for (m, p) in self.modules: |
||
1676 | if (len(m) > maxw): maxw = len(m) |
||
1677 | for (m, p) in self.modules: |
||
1678 | fx.write("%-*s %s\n" % (maxw, m, p)) |
||
1679 | fx.write('#.END\n\n') |
||
1680 | for cls in self.objectclass_ord: |
||
1681 | if self.objectclass[cls]['export']: |
||
1682 | cnm = cls |
||
1683 | if self.objectclass[cls]['export'] & EF_MODULE: |
||
1684 | cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm) |
||
1685 | fx.write('#.CLASS %s\n' % (cnm)) |
||
1686 | maxw = 2 |
||
1687 | for fld in self.objectclass[cls]['val'].fields: |
||
1688 | w = len(fld.fld_repr()[0]) |
||
1689 | if (w > maxw): maxw = w |
||
1690 | for fld in self.objectclass[cls]['val'].fields: |
||
1691 | repr = fld.fld_repr() |
||
1692 | fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:]))) |
||
1693 | fx.write('#.END\n\n') |
||
1694 | if self.Ber(): |
||
1695 | fx.write('#.IMPORT_TAG\n') |
||
1696 | for t in self.eth_export_ord: # tags |
||
1697 | if (self.eth_type[t]['export'] & EF_TYPE): |
||
1698 | fx.write('%-24s ' % self.eth_type[t]['ref'][0]) |
||
1699 | fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self)) |
||
1700 | fx.write('#.END\n\n') |
||
1701 | fx.write('#.TYPE_ATTR\n') |
||
1702 | for t in self.eth_export_ord: # attributes |
||
1703 | if (self.eth_type[t]['export'] & EF_TYPE): |
||
1704 | tnm = self.eth_type[t]['ref'][0] |
||
1705 | if self.eth_type[t]['export'] & EF_MODULE: |
||
1706 | tnm = "$%s$%s" % (self.type[tnm]['module'], tnm) |
||
1707 | fx.write('%-24s ' % tnm) |
||
1708 | attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy() |
||
1709 | fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr) |
||
1710 | fx.write('#.END\n\n') |
||
1711 | self.output.file_close(fx, keep_anyway=True) |
||
1712 | |||
1713 | #--- eth_output_val ------------------------------------------------------ |
||
1714 | def eth_output_val(self): |
||
1715 | fx = self.output.file_open('val', ext='h') |
||
1716 | for v in self.eth_value_ord1: |
||
1717 | vv = self.eth_value[v]['value'] |
||
1718 | if isinstance (vv, Value): |
||
1719 | vv = vv.to_str(self) |
||
1720 | fx.write("#define %-30s %s\n" % (v, vv)) |
||
1721 | for t in self.eth_type_ord1: |
||
1722 | if self.eth_type[t]['import']: |
||
1723 | continue |
||
1724 | if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM): |
||
1725 | fx.write(self.eth_type[t]['val'].eth_type_enum(t, self)) |
||
1726 | self.output.file_close(fx) |
||
1727 | |||
1728 | #--- eth_output_valexp ------------------------------------------------------ |
||
1729 | def eth_output_valexp(self): |
||
1730 | if (not len(self.eth_vexport_ord)): return |
||
1731 | fx = self.output.file_open('valexp', ext='h') |
||
1732 | for v in self.eth_vexport_ord: |
||
1733 | vv = self.eth_value[v]['value'] |
||
1734 | if isinstance (vv, Value): |
||
1735 | vv = vv.to_str(self) |
||
1736 | fx.write("#define %-30s %s\n" % (v, vv)) |
||
1737 | self.output.file_close(fx) |
||
1738 | |||
1739 | #--- eth_output_types ------------------------------------------------------- |
||
1740 | def eth_output_types(self): |
||
1741 | def out_pdu(f): |
||
1742 | t = self.eth_hf[f]['ethtype'] |
||
1743 | impl = 'FALSE' |
||
1744 | out = '' |
||
1745 | if (not self.eth_hf[f]['pdu']['export']): |
||
1746 | out += 'static ' |
||
1747 | out += 'int ' |
||
1748 | out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n' |
||
1749 | out += ' int offset = 0;\n' |
||
1750 | off_par = 'offset' |
||
1751 | ret_par = 'offset' |
||
1752 | if (self.Per()): |
||
1753 | if (self.Aligned()): |
||
1754 | aligned = 'TRUE' |
||
1755 | else: |
||
1756 | aligned = 'FALSE' |
||
1757 | out += " asn1_ctx_t asn1_ctx;\n" |
||
1758 | out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),)) |
||
1759 | if (self.Ber()): |
||
1760 | out += " asn1_ctx_t asn1_ctx;\n" |
||
1761 | out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),)) |
||
1762 | par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),) |
||
1763 | elif (self.Per()): |
||
1764 | par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),) |
||
1765 | else: |
||
1766 | par=((),) |
||
1767 | out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par) |
||
1768 | if (self.Per()): |
||
1769 | out += ' offset += 7; offset >>= 3;\n' |
||
1770 | out += ' return offset;\n' |
||
1771 | out += '}\n' |
||
1772 | return out |
||
1773 | #end out_pdu() |
||
1774 | fx = self.output.file_open('fn') |
||
1775 | pos = fx.tell() |
||
1776 | if (len(self.eth_hfpdu_ord)): |
||
1777 | first_decl = True |
||
1778 | for f in self.eth_hfpdu_ord: |
||
1779 | if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']): |
||
1780 | if first_decl: |
||
1781 | fx.write('/*--- PDUs declarations ---*/\n') |
||
1782 | first_decl = False |
||
1783 | fx.write(self.eth_out_pdu_decl(f)) |
||
1784 | if not first_decl: |
||
1785 | fx.write('\n') |
||
1786 | if self.eth_dep_cycle: |
||
1787 | fx.write('/*--- Cyclic dependencies ---*/\n\n') |
||
1788 | i = 0 |
||
1789 | while i < len(self.eth_dep_cycle): |
||
1790 | t = self.type[self.eth_dep_cycle[i][0]]['ethname'] |
||
1791 | if self.dep_cycle_eth_type[t][0] != i: i += 1; continue |
||
1792 | fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]])) |
||
1793 | if not self.eth_type[t]['export'] & EF_TYPE: |
||
1794 | fx.write(self.eth_type_fn_h(t)) |
||
1795 | else: |
||
1796 | fx.write('/*' + self.eth_type_fn_h(t).strip() + '*/\n') |
||
1797 | fx.write('\n') |
||
1798 | i += 1 |
||
1799 | fx.write('\n') |
||
1800 | for t in self.eth_type_ord1: |
||
1801 | if self.eth_type[t]['import']: |
||
1802 | continue |
||
1803 | if self.eth_type[t]['val'].eth_has_vals(): |
||
1804 | if self.eth_type[t]['no_emit'] & EF_VALS: |
||
1805 | pass |
||
1806 | elif self.eth_type[t]['user_def'] & EF_VALS: |
||
1807 | fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t))) |
||
1808 | elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE): |
||
1809 | pass |
||
1810 | else: |
||
1811 | fx.write(self.eth_type[t]['val'].eth_type_vals(t, self)) |
||
1812 | if self.eth_type[t]['no_emit'] & EF_TYPE: |
||
1813 | pass |
||
1814 | elif self.eth_type[t]['user_def'] & EF_TYPE: |
||
1815 | fx.write(self.eth_type_fn_h(t)) |
||
1816 | else: |
||
1817 | fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self)) |
||
1818 | fx.write('\n') |
||
1819 | if (len(self.eth_hfpdu_ord)): |
||
1820 | fx.write('/*--- PDUs ---*/\n\n') |
||
1821 | for f in self.eth_hfpdu_ord: |
||
1822 | if (self.eth_hf[f]['pdu']): |
||
1823 | if (f in self.emitted_pdu): |
||
1824 | fx.write(" /* %s already emitted */\n" % (f)) |
||
1825 | else: |
||
1826 | fx.write(out_pdu(f)) |
||
1827 | self.emitted_pdu[f] = True |
||
1828 | fx.write('\n') |
||
1829 | fempty = pos == fx.tell() |
||
1830 | self.output.file_close(fx, discard=fempty) |
||
1831 | |||
1832 | #--- eth_output_dis_hnd ----------------------------------------------------- |
||
1833 | def eth_output_dis_hnd(self): |
||
1834 | fx = self.output.file_open('dis-hnd') |
||
1835 | fempty = True |
||
1836 | for f in self.eth_hfpdu_ord: |
||
1837 | pdu = self.eth_hf[f]['pdu'] |
||
1838 | if (pdu and pdu['reg'] and not pdu['hidden']): |
||
1839 | dis = self.proto |
||
1840 | if (pdu['reg'] != '.'): |
||
1841 | dis += '.' + pdu['reg'] |
||
1842 | fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis))) |
||
1843 | fempty = False |
||
1844 | fx.write('\n') |
||
1845 | self.output.file_close(fx, discard=fempty) |
||
1846 | |||
1847 | #--- eth_output_dis_reg ----------------------------------------------------- |
||
1848 | def eth_output_dis_reg(self): |
||
1849 | fx = self.output.file_open('dis-reg') |
||
1850 | fempty = True |
||
1851 | for f in self.eth_hfpdu_ord: |
||
1852 | pdu = self.eth_hf[f]['pdu'] |
||
1853 | if (pdu and pdu['reg']): |
||
1854 | new_prefix = '' |
||
1855 | if (pdu['new']): new_prefix = 'new_' |
||
1856 | dis = self.proto |
||
1857 | if (pdu['reg'] != '.'): dis += '.' + pdu['reg'] |
||
1858 | fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto)) |
||
1859 | if (not pdu['hidden']): |
||
1860 | fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis)) |
||
1861 | fempty = False |
||
1862 | fx.write('\n') |
||
1863 | self.output.file_close(fx, discard=fempty) |
||
1864 | |||
1865 | #--- eth_output_dis_tab ----------------------------------------------------- |
||
1866 | def eth_output_dis_tab(self): |
||
1867 | fx = self.output.file_open('dis-tab') |
||
1868 | fempty = True |
||
1869 | for k in self.conform.get_order('REGISTER'): |
||
1870 | reg = self.conform.use_item('REGISTER', k) |
||
1871 | if reg['pdu'] not in self.field: continue |
||
1872 | f = self.field[reg['pdu']]['ethname'] |
||
1873 | pdu = self.eth_hf[f]['pdu'] |
||
1874 | new_prefix = '' |
||
1875 | if (pdu['new']): new_prefix = 'new_' |
||
1876 | if (reg['rtype'] in ('NUM', 'STR')): |
||
1877 | rstr = '' |
||
1878 | if (reg['rtype'] == 'STR'): |
||
1879 | rstr = 'string' |
||
1880 | else: |
||
1881 | rstr = 'uint' |
||
1882 | if (pdu['reg']): |
||
1883 | dis = self.proto |
||
1884 | if (pdu['reg'] != '.'): dis += '.' + pdu['reg'] |
||
1885 | if (not pdu['hidden']): |
||
1886 | hnd = '%s_handle' % (asn2c(dis)) |
||
1887 | else: |
||
1888 | hnd = 'find_dissector("%s")' % (dis) |
||
1889 | else: |
||
1890 | hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto) |
||
1891 | rport = self.value_get_eth(reg['rport']) |
||
1892 | fx.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd)) |
||
1893 | elif (reg['rtype'] in ('BER', 'PER')): |
||
1894 | roid = self.value_get_eth(reg['roid']) |
||
1895 | fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname'])) |
||
1896 | fempty = False |
||
1897 | fx.write('\n') |
||
1898 | self.output.file_close(fx, discard=fempty) |
||
1899 | |||
1900 | #--- eth_output_syn_reg ----------------------------------------------------- |
||
1901 | def eth_output_syn_reg(self): |
||
1902 | fx = self.output.file_open('syn-reg') |
||
1903 | fempty = True |
||
1904 | first_decl = True |
||
1905 | for k in self.conform.get_order('SYNTAX'): |
||
1906 | reg = self.conform.use_item('SYNTAX', k) |
||
1907 | if reg['pdu'] not in self.field: continue |
||
1908 | f = self.field[reg['pdu']]['ethname'] |
||
1909 | pdu = self.eth_hf[f]['pdu'] |
||
1910 | new_prefix = '' |
||
1911 | if (pdu['new']): new_prefix = 'new_' |
||
1912 | if first_decl: |
||
1913 | fx.write(' /*--- Syntax registrations ---*/\n') |
||
1914 | first_decl = False |
||
1915 | fx.write(' %sregister_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (new_prefix, k, self.eproto, reg['pdu'])); |
||
1916 | fempty=False |
||
1917 | self.output.file_close(fx, discard=fempty) |
||
1918 | |||
1919 | #--- eth_output_tables ----------------------------------------------------- |
||
1920 | def eth_output_tables(self): |
||
1921 | for num in list(self.conform.report.keys()): |
||
1922 | fx = self.output.file_open('table' + num) |
||
1923 | for rep in self.conform.report[num]: |
||
1924 | self.eth_output_table(fx, rep) |
||
1925 | self.output.file_close(fx) |
||
1926 | |||
1927 | #--- eth_output_table ----------------------------------------------------- |
||
1928 | def eth_output_table(self, fx, rep): |
||
1929 | if rep['type'] == 'HDR': |
||
1930 | fx.write('\n') |
||
1931 | if rep['var']: |
||
1932 | var = rep['var'] |
||
1933 | var_list = var.split('.', 1) |
||
1934 | cls = var_list[0] |
||
1935 | del var_list[0] |
||
1936 | flds = [] |
||
1937 | not_flds = [] |
||
1938 | sort_flds = [] |
||
1939 | for f in var_list: |
||
1940 | if f[0] == '!': |
||
1941 | not_flds.append(f[1:]) |
||
1942 | continue |
||
1943 | if f[0] == '#': |
||
1944 | flds.append(f[1:]) |
||
1945 | sort_flds.append(f) |
||
1946 | continue |
||
1947 | if f[0] == '@': |
||
1948 | flds.append(f[1:]) |
||
1949 | sort_flds.append(f[1:]) |
||
1950 | continue |
||
1951 | flds.append(f) |
||
1952 | objs = {} |
||
1953 | objs_ord = [] |
||
1954 | if (cls in self.oassign_cls): |
||
1955 | for ident in self.oassign_cls[cls]: |
||
1956 | obj = self.get_obj_repr(ident, flds, not_flds) |
||
1957 | if not obj: |
||
1958 | continue |
||
1959 | obj['_LOOP'] = var |
||
1960 | obj['_DICT'] = str(obj) |
||
1961 | objs[ident] = obj |
||
1962 | objs_ord.append(ident) |
||
1963 | if (sort_flds): |
||
1964 | # Sort identifiers according to the matching object in objs. |
||
1965 | # The order is determined by sort_flds, keys prefixed by a |
||
1966 | # '#' are compared numerically. |
||
1967 | def obj_key_fn(name): |
||
1968 | obj = objs[name] |
||
1969 | return list( |
||
1970 | int(obj[f[1:]]) if f[0] == '#' else obj[f] |
||
1971 | for f in sort_flds |
||
1972 | ) |
||
1973 | objs_ord.sort(key=obj_key_fn) |
||
1974 | for ident in objs_ord: |
||
1975 | obj = objs[ident] |
||
1976 | try: |
||
1977 | text = rep['text'] % obj |
||
1978 | except (KeyError): |
||
1979 | raise sys.exc_info()[0]("%s:%s invalid key %s for information object %s of %s" % (rep['fn'], rep['lineno'], sys.exc_info()[1], ident, var)) |
||
1980 | fx.write(text) |
||
1981 | else: |
||
1982 | fx.write("/* Unknown or empty loop list %s */\n" % (var)) |
||
1983 | else: |
||
1984 | fx.write(rep['text']) |
||
1985 | if rep['type'] == 'FTR': |
||
1986 | fx.write('\n') |
||
1987 | |||
1988 | #--- dupl_report ----------------------------------------------------- |
||
1989 | def dupl_report(self): |
||
1990 | # types |
||
1991 | tmplist = sorted(self.eth_type_dupl.keys()) |
||
1992 | for t in tmplist: |
||
1993 | msg = "The same type names for different types. Explicit type renaming is recommended.\n" |
||
1994 | msg += t + "\n" |
||
1995 | for tt in self.eth_type_dupl[t]: |
||
1996 | msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt) |
||
1997 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
1998 | # fields |
||
1999 | tmplist = list(self.eth_hf_dupl.keys()) |
||
2000 | tmplist.sort() |
||
2001 | for f in tmplist: |
||
2002 | msg = "The same field names for different types. Explicit field renaming is recommended.\n" |
||
2003 | msg += f + "\n" |
||
2004 | for tt in list(self.eth_hf_dupl[f].keys()): |
||
2005 | msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt) |
||
2006 | msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref']) |
||
2007 | msg += "\n" |
||
2008 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
2009 | |||
2010 | #--- eth_do_output ------------------------------------------------------------ |
||
2011 | def eth_do_output(self): |
||
2012 | if self.dbg('a'): |
||
2013 | print("\n# Assignments") |
||
2014 | for a in self.assign_ord: |
||
2015 | v = ' ' |
||
2016 | if (self.assign[a]['virt']): v = '*' |
||
2017 | print(v, a) |
||
2018 | print("\n# Value assignments") |
||
2019 | for a in self.vassign_ord: |
||
2020 | print(' ', a) |
||
2021 | print("\n# Information object assignments") |
||
2022 | for a in self.oassign_ord: |
||
2023 | print(" %-12s (%s)" % (a, self.oassign[a].cls)) |
||
2024 | if self.dbg('t'): |
||
2025 | print("\n# Imported Types") |
||
2026 | print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) |
||
2027 | print("-" * 100) |
||
2028 | for t in self.type_imp: |
||
2029 | print("%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])) |
||
2030 | print("\n# Imported Values") |
||
2031 | print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) |
||
2032 | print("-" * 100) |
||
2033 | for t in self.value_imp: |
||
2034 | print("%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])) |
||
2035 | print("\n# Imported Object Classes") |
||
2036 | print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) |
||
2037 | print("-" * 100) |
||
2038 | for t in self.objectclass_imp: |
||
2039 | print("%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto'])) |
||
2040 | print("\n# Exported Types") |
||
2041 | print("%-31s %s" % ("Wireshark type", "Export Flag")) |
||
2042 | print("-" * 100) |
||
2043 | for t in self.eth_export_ord: |
||
2044 | print("%-31s 0x%02X" % (t, self.eth_type[t]['export'])) |
||
2045 | print("\n# Exported Values") |
||
2046 | print("%-40s %s" % ("Wireshark name", "Value")) |
||
2047 | print("-" * 100) |
||
2048 | for v in self.eth_vexport_ord: |
||
2049 | vv = self.eth_value[v]['value'] |
||
2050 | if isinstance (vv, Value): |
||
2051 | vv = vv.to_str(self) |
||
2052 | print("%-40s %s" % (v, vv)) |
||
2053 | print("\n# ASN.1 Object Classes") |
||
2054 | print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) |
||
2055 | print("-" * 100) |
||
2056 | for t in self.objectclass_ord: |
||
2057 | print("%-40s " % (t)) |
||
2058 | print("\n# ASN.1 Types") |
||
2059 | print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")) |
||
2060 | print("-" * 100) |
||
2061 | for t in self.type_ord: |
||
2062 | print("%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])) |
||
2063 | print("\n# Wireshark Types") |
||
2064 | print("Wireshark type References (ASN.1 types)") |
||
2065 | print("-" * 100) |
||
2066 | for t in self.eth_type_ord: |
||
2067 | sys.stdout.write("%-31s %d" % (t, len(self.eth_type[t]['ref']))) |
||
2068 | print(', '.join(self.eth_type[t]['ref'])) |
||
2069 | print("\n# ASN.1 Values") |
||
2070 | print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value")) |
||
2071 | print("-" * 100) |
||
2072 | for v in self.value_ord: |
||
2073 | vv = self.value[v]['value'] |
||
2074 | if isinstance (vv, Value): |
||
2075 | vv = vv.to_str(self) |
||
2076 | print("%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname'])) |
||
2077 | #print "\n# Wireshark Values" |
||
2078 | #print "%-40s %s" % ("Wireshark name", "Value") |
||
2079 | #print "-" * 100 |
||
2080 | #for v in self.eth_value_ord: |
||
2081 | # vv = self.eth_value[v]['value'] |
||
2082 | # if isinstance (vv, Value): |
||
2083 | # vv = vv.to_str(self) |
||
2084 | # print "%-40s %s" % (v, vv) |
||
2085 | print("\n# ASN.1 Fields") |
||
2086 | print("ASN.1 unique name Wireshark name ASN.1 type") |
||
2087 | print("-" * 100) |
||
2088 | for f in (self.pdu_ord + self.field_ord): |
||
2089 | print("%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])) |
||
2090 | print("\n# Wireshark Fields") |
||
2091 | print("Wireshark name Wireshark type References (ASN.1 fields)") |
||
2092 | print("-" * 100) |
||
2093 | for f in (self.eth_hfpdu_ord + self.eth_hf_ord): |
||
2094 | sys.stdout.write("%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref']))) |
||
2095 | print(', '.join(self.eth_hf[f]['ref'])) |
||
2096 | #print "\n# Order after dependencies" |
||
2097 | #print '\n'.join(self.eth_type_ord1) |
||
2098 | print("\n# Cyclic dependencies") |
||
2099 | for c in self.eth_dep_cycle: |
||
2100 | print(' -> '.join(c)) |
||
2101 | self.dupl_report() |
||
2102 | self.output.outnm = self.outnm_opt |
||
2103 | if (not self.output.outnm): |
||
2104 | self.output.outnm = self.proto |
||
2105 | self.output.outnm = self.output.outnm.replace('.', '-') |
||
2106 | if not self.justexpcnf: |
||
2107 | self.eth_output_hf() |
||
2108 | self.eth_output_ett() |
||
2109 | self.eth_output_types() |
||
2110 | self.eth_output_hf_arr() |
||
2111 | self.eth_output_ett_arr() |
||
2112 | self.eth_output_export() |
||
2113 | self.eth_output_val() |
||
2114 | self.eth_output_valexp() |
||
2115 | self.eth_output_dis_hnd() |
||
2116 | self.eth_output_dis_reg() |
||
2117 | self.eth_output_dis_tab() |
||
2118 | self.eth_output_syn_reg() |
||
2119 | self.eth_output_tables() |
||
2120 | if self.expcnf: |
||
2121 | self.eth_output_expcnf() |
||
2122 | |||
2123 | def dbg_modules(self): |
||
2124 | def print_mod(m): |
||
2125 | sys.stdout.write("%-30s " % (m)) |
||
2126 | dep = self.module[m][:] |
||
2127 | for i in range(len(dep)): |
||
2128 | if dep[i] not in self.module: |
||
2129 | dep[i] = '*' + dep[i] |
||
2130 | print(', '.join(dep)) |
||
2131 | # end of print_mod() |
||
2132 | (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module) |
||
2133 | print("\n# ASN.1 Moudules") |
||
2134 | print("Module name Dependency") |
||
2135 | print("-" * 100) |
||
2136 | new_ord = False |
||
2137 | for m in (self.module_ord): |
||
2138 | print_mod(m) |
||
2139 | new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m)) |
||
2140 | if new_ord: |
||
2141 | print("\n# ASN.1 Moudules - in dependency order") |
||
2142 | print("Module name Dependency") |
||
2143 | print("-" * 100) |
||
2144 | for m in (mod_ord): |
||
2145 | print_mod(m) |
||
2146 | if mod_cyc: |
||
2147 | print("\nCyclic dependencies:") |
||
2148 | for i in (list(range(len(mod_cyc)))): |
||
2149 | print("%02d: %s" % (i + 1, str(mod_cyc[i]))) |
||
2150 | |||
2151 | |||
2152 | #--- EthCnf ------------------------------------------------------------------- |
||
2153 | class EthCnf: |
||
2154 | def __init__(self): |
||
2155 | self.ectx = None |
||
2156 | self.tblcfg = {} |
||
2157 | self.table = {} |
||
2158 | self.order = {} |
||
2159 | self.fn = {} |
||
2160 | self.report = {} |
||
2161 | self.suppress_line = False |
||
2162 | self.include_path = [] |
||
2163 | # Value name Default value Duplicity check Usage check |
||
2164 | self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } |
||
2165 | self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } |
||
2166 | self.tblcfg['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } |
||
2167 | self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2168 | self.tblcfg['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2169 | self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2170 | self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } |
||
2171 | self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } |
||
2172 | self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False } |
||
2173 | self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True } |
||
2174 | self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True } |
||
2175 | self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2176 | self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2177 | self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2178 | self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2179 | self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False } |
||
2180 | self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True } |
||
2181 | self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False } |
||
2182 | self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False } |
||
2183 | self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True } |
||
2184 | self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True } |
||
2185 | self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False } |
||
2186 | self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } |
||
2187 | |||
2188 | for k in list(self.tblcfg.keys()) : |
||
2189 | self.table[k] = {} |
||
2190 | self.order[k] = [] |
||
2191 | |||
2192 | def add_item(self, table, key, fn, lineno, **kw): |
||
2193 | if self.tblcfg[table]['chk_dup'] and key in self.table[table]: |
||
2194 | warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" % |
||
2195 | (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']), |
||
2196 | UserWarning, fn, lineno) |
||
2197 | return |
||
2198 | self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False} |
||
2199 | self.table[table][key].update(kw) |
||
2200 | self.order[table].append(key) |
||
2201 | |||
2202 | def update_item(self, table, key, fn, lineno, **kw): |
||
2203 | if key not in self.table[table]: |
||
2204 | self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False} |
||
2205 | self.order[table].append(key) |
||
2206 | self.table[table][key][self.tblcfg[table]['val_nm']] = {} |
||
2207 | self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']]) |
||
2208 | |||
2209 | def get_order(self, table): |
||
2210 | return self.order[table] |
||
2211 | |||
2212 | def check_item(self, table, key): |
||
2213 | return key in self.table[table] |
||
2214 | |||
2215 | def copy_item(self, table, dst_key, src_key): |
||
2216 | if (src_key in self.table[table]): |
||
2217 | self.table[table][dst_key] = self.table[table][src_key] |
||
2218 | |||
2219 | def check_item_value(self, table, key, **kw): |
||
2220 | return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key] |
||
2221 | |||
2222 | def use_item(self, table, key, **kw): |
||
2223 | vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt']) |
||
2224 | if key not in self.table[table]: return vdflt |
||
2225 | vname = kw.get('val_nm', self.tblcfg[table]['val_nm']) |
||
2226 | #print "use_item() - set used for %s %s" % (table, key) |
||
2227 | self.table[table][key]['used'] = True |
||
2228 | return self.table[table][key].get(vname, vdflt) |
||
2229 | |||
2230 | def omit_assignment(self, type, ident, module): |
||
2231 | if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident): |
||
2232 | return True |
||
2233 | if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \ |
||
2234 | self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \ |
||
2235 | self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \ |
||
2236 | self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module): |
||
2237 | return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident) |
||
2238 | return False |
||
2239 | |||
2240 | def add_fn_line(self, name, ctx, line, fn, lineno): |
||
2241 | if name not in self.fn: |
||
2242 | self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None} |
||
2243 | if (self.fn[name][ctx]): |
||
2244 | self.fn[name][ctx]['text'] += line |
||
2245 | else: |
||
2246 | self.fn[name][ctx] = {'text' : line, 'used' : False, |
||
2247 | 'fn' : fn, 'lineno' : lineno} |
||
2248 | def get_fn_presence(self, name): |
||
2249 | #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name))) |
||
2250 | #if self.fn.has_key(name): print self.fn[name] |
||
2251 | return name in self.fn |
||
2252 | def get_fn_body_presence(self, name): |
||
2253 | return name in self.fn and self.fn[name]['FN_BODY'] |
||
2254 | def get_fn_text(self, name, ctx): |
||
2255 | if (name not in self.fn): |
||
2256 | return ''; |
||
2257 | if (not self.fn[name][ctx]): |
||
2258 | return ''; |
||
2259 | self.fn[name][ctx]['used'] = True |
||
2260 | out = self.fn[name][ctx]['text'] |
||
2261 | if (not self.suppress_line): |
||
2262 | out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], rel_dissector_path(self.fn[name][ctx]['fn']), out); |
||
2263 | return out |
||
2264 | |||
2265 | def add_pdu(self, par, fn, lineno): |
||
2266 | #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno) |
||
2267 | (reg, hidden) = (None, False) |
||
2268 | if (len(par) > 1): reg = par[1] |
||
2269 | if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True) |
||
2270 | attr = {'new' : False, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False} |
||
2271 | self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno) |
||
2272 | return |
||
2273 | |||
2274 | def add_syntax(self, par, fn, lineno): |
||
2275 | #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno) |
||
2276 | if( (len(par) >=2)): |
||
2277 | name = par[1] |
||
2278 | else: |
||
2279 | name = '"'+par[0]+'"' |
||
2280 | attr = { 'pdu' : par[0] } |
||
2281 | self.add_item('SYNTAX', name, attr=attr, fn=fn, lineno=lineno) |
||
2282 | return |
||
2283 | |||
2284 | def add_register(self, pdu, par, fn, lineno): |
||
2285 | #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno) |
||
2286 | if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2) |
||
2287 | elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2) |
||
2288 | elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2) |
||
2289 | elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2) |
||
2290 | else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return |
||
2291 | if ((len(par)-1) < pmin): |
||
2292 | warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno) |
||
2293 | return |
||
2294 | if ((len(par)-1) > pmax): |
||
2295 | warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno) |
||
2296 | attr = {'pdu' : pdu, 'rtype' : rtype} |
||
2297 | if (rtype in ('NUM', 'STR')): |
||
2298 | attr['rtable'] = par[1] |
||
2299 | attr['rport'] = par[2] |
||
2300 | rkey = '/'.join([rtype, attr['rtable'], attr['rport']]) |
||
2301 | elif (rtype in ('BER', 'PER')): |
||
2302 | attr['roid'] = par[1] |
||
2303 | attr['roidname'] = '""' |
||
2304 | if (len(par)>=3): |
||
2305 | attr['roidname'] = par[2] |
||
2306 | elif attr['roid'][0] != '"': |
||
2307 | attr['roidname'] = '"' + attr['roid'] + '"' |
||
2308 | rkey = '/'.join([rtype, attr['roid']]) |
||
2309 | self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno) |
||
2310 | |||
2311 | def check_par(self, par, pmin, pmax, fn, lineno): |
||
2312 | for i in range(len(par)): |
||
2313 | if par[i] == '-': |
||
2314 | par[i] = None |
||
2315 | continue |
||
2316 | if par[i][0] == '#': |
||
2317 | par[i:] = [] |
||
2318 | break |
||
2319 | if len(par) < pmin: |
||
2320 | warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno) |
||
2321 | return None |
||
2322 | if (pmax >= 0) and (len(par) > pmax): |
||
2323 | warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno) |
||
2324 | return par[0:pmax] |
||
2325 | return par |
||
2326 | |||
2327 | def read(self, fn): |
||
2328 | def get_par(line, pmin, pmax, fn, lineno): |
||
2329 | par = line.split(None, pmax) |
||
2330 | par = self.check_par(par, pmin, pmax, fn, lineno) |
||
2331 | return par |
||
2332 | |||
2333 | def get_par_nm(line, pmin, pmax, fn, lineno): |
||
2334 | if pmax: |
||
2335 | par = line.split(None, pmax) |
||
2336 | else: |
||
2337 | par = [line,] |
||
2338 | for i in range(len(par)): |
||
2339 | if par[i][0] == '#': |
||
2340 | par[i:] = [] |
||
2341 | break |
||
2342 | if len(par) < pmin: |
||
2343 | warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno) |
||
2344 | return None |
||
2345 | if len(par) > pmax: |
||
2346 | nmpar = par[pmax] |
||
2347 | else: |
||
2348 | nmpar = '' |
||
2349 | nmpars = {} |
||
2350 | nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*') |
||
2351 | nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*') |
||
2352 | nmpar_end = re.compile(r'\s*$') |
||
2353 | result = nmpar_first.search(nmpar) |
||
2354 | pos = 0 |
||
2355 | while result: |
||
2356 | k = result.group('attr') |
||
2357 | pos = result.end() |
||
2358 | result = nmpar_next.search(nmpar, pos) |
||
2359 | p1 = pos |
||
2360 | if result: |
||
2361 | p2 = result.start() |
||
2362 | else: |
||
2363 | p2 = nmpar_end.search(nmpar, pos).start() |
||
2364 | v = nmpar[p1:p2] |
||
2365 | nmpars[k] = v |
||
2366 | if len(par) > pmax: |
||
2367 | par[pmax] = nmpars |
||
2368 | return par |
||
2369 | |||
2370 | f = open(fn, "r") |
||
2371 | lineno = 0 |
||
2372 | is_import = False |
||
2373 | directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)') |
||
2374 | cdirective = re.compile(r'^\s*##') |
||
2375 | report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$') |
||
2376 | comment = re.compile(r'^\s*#[^.#]') |
||
2377 | empty = re.compile(r'^\s*$') |
||
2378 | ctx = None |
||
2379 | name = '' |
||
2380 | default_flags = 0x00 |
||
2381 | stack = [] |
||
2382 | while True: |
||
2383 | if not f.closed: |
||
2384 | line = f.readline() |
||
2385 | lineno += 1 |
||
2386 | else: |
||
2387 | line = None |
||
2388 | if not line: |
||
2389 | if not f.closed: |
||
2390 | f.close() |
||
2391 | if stack: |
||
2392 | frec = stack.pop() |
||
2393 | fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import'] |
||
2394 | continue |
||
2395 | else: |
||
2396 | break |
||
2397 | if comment.search(line): continue |
||
2398 | result = directive.search(line) |
||
2399 | if result: # directive |
||
2400 | rep_result = report.search(result.group('name')) |
||
2401 | if result.group('name') == 'END_OF_CNF': |
||
2402 | f.close() |
||
2403 | elif result.group('name') == 'OPT': |
||
2404 | ctx = result.group('name') |
||
2405 | par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno) |
||
2406 | if not par: continue |
||
2407 | self.set_opt(par[0], par[1:], fn, lineno) |
||
2408 | ctx = None |
||
2409 | elif result.group('name') in ('PDU', 'REGISTER', |
||
2410 | 'MODULE', 'MODULE_IMPORT', |
||
2411 | 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN', |
||
2412 | 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE', |
||
2413 | 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG', |
||
2414 | 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR', |
||
2415 | 'SYNTAX'): |
||
2416 | ctx = result.group('name') |
||
2417 | elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT', |
||
2418 | 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', |
||
2419 | 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'): |
||
2420 | ctx = result.group('name') |
||
2421 | key = '*' |
||
2422 | if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'): |
||
2423 | key += 'T' |
||
2424 | if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'): |
||
2425 | key += 'V' |
||
2426 | par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno) |
||
2427 | if par: |
||
2428 | key += '/' + par[0] |
||
2429 | self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno) |
||
2430 | if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'): |
||
2431 | ctx = 'NO_OMIT_ASSGN' |
||
2432 | else: |
||
2433 | ctx = None |
||
2434 | elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'): |
||
2435 | ctx = result.group('name') |
||
2436 | default_flags = EF_TYPE|EF_VALS |
||
2437 | if ctx == 'MODULE_EXPORTS': |
||
2438 | ctx = 'EXPORTS' |
||
2439 | default_flags |= EF_MODULE |
||
2440 | if ctx == 'EXPORTS': |
||
2441 | par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno) |
||
2442 | else: |
||
2443 | par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno) |
||
2444 | if not par: continue |
||
2445 | p = 1 |
||
2446 | if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS |
||
2447 | elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE |
||
2448 | elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS |
||
2449 | elif (ctx == 'EXPORTS'): p = 0 |
||
2450 | else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno) |
||
2451 | for i in range(p, len(par)): |
||
2452 | if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM |
||
2453 | elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM |
||
2454 | elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE |
||
2455 | elif (par[i] == 'WS_DLL'): default_flags |= EF_WS_DLL |
||
2456 | elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN |
||
2457 | elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT |
||
2458 | else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) |
||
2459 | elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'): |
||
2460 | ctx = result.group('name') |
||
2461 | default_flags = EF_ENUM |
||
2462 | if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE |
||
2463 | if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE |
||
2464 | par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno) |
||
2465 | for i in range(0, len(par)): |
||
2466 | if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT |
||
2467 | elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT |
||
2468 | elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE |
||
2469 | elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE |
||
2470 | elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE |
||
2471 | elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE |
||
2472 | else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) |
||
2473 | elif result.group('name') == 'USE_VALS_EXT': |
||
2474 | ctx = result.group('name') |
||
2475 | default_flags = 0xFF |
||
2476 | elif result.group('name') == 'FN_HDR': |
||
2477 | minp = 1 |
||
2478 | if (ctx in ('FN_PARS',)) and name: minp = 0 |
||
2479 | par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno) |
||
2480 | if (not par) and (minp > 0): continue |
||
2481 | ctx = result.group('name') |
||
2482 | if par: name = par[0] |
||
2483 | elif result.group('name') == 'FN_FTR': |
||
2484 | minp = 1 |
||
2485 | if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0 |
||
2486 | par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno) |
||
2487 | if (not par) and (minp > 0): continue |
||
2488 | ctx = result.group('name') |
||
2489 | if par: name = par[0] |
||
2490 | elif result.group('name') == 'FN_BODY': |
||
2491 | par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno) |
||
2492 | if not par: continue |
||
2493 | ctx = result.group('name') |
||
2494 | name = par[0] |
||
2495 | if len(par) > 1: |
||
2496 | self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno) |
||
2497 | elif result.group('name') == 'FN_PARS': |
||
2498 | par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno) |
||
2499 | ctx = result.group('name') |
||
2500 | if not par: |
||
2501 | name = None |
||
2502 | elif len(par) == 1: |
||
2503 | name = par[0] |
||
2504 | self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno) |
||
2505 | elif len(par) > 1: |
||
2506 | self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno) |
||
2507 | ctx = None |
||
2508 | elif result.group('name') == 'CLASS': |
||
2509 | par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) |
||
2510 | if not par: continue |
||
2511 | ctx = result.group('name') |
||
2512 | name = par[0] |
||
2513 | add_class_ident(name) |
||
2514 | if not name.split('$')[-1].isupper(): |
||
2515 | warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name), |
||
2516 | UserWarning, fn, lineno) |
||
2517 | elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER': |
||
2518 | par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) |
||
2519 | if not par: continue |
||
2520 | self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno) |
||
2521 | elif rep_result: # Reports |
||
2522 | num = rep_result.group('num') |
||
2523 | type = rep_result.group('type') |
||
2524 | if type == 'BODY': |
||
2525 | par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) |
||
2526 | if not par: continue |
||
2527 | else: |
||
2528 | par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno) |
||
2529 | rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno } |
||
2530 | if len(par) > 0: |
||
2531 | rep['var'] = par[0] |
||
2532 | self.report.setdefault(num, []).append(rep) |
||
2533 | ctx = 'TABLE' |
||
2534 | name = num |
||
2535 | elif result.group('name') in ('INCLUDE', 'IMPORT') : |
||
2536 | is_imp = result.group('name') == 'IMPORT' |
||
2537 | par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) |
||
2538 | if not par: |
||
2539 | warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno) |
||
2540 | continue |
||
2541 | fname = par[0] |
||
2542 | #print "Try include: %s" % (fname) |
||
2543 | if (not os.path.exists(fname)): |
||
2544 | fname = os.path.join(os.path.split(fn)[0], par[0]) |
||
2545 | #print "Try include: %s" % (fname) |
||
2546 | i = 0 |
||
2547 | while not os.path.exists(fname) and (i < len(self.include_path)): |
||
2548 | fname = os.path.join(self.include_path[i], par[0]) |
||
2549 | #print "Try include: %s" % (fname) |
||
2550 | i += 1 |
||
2551 | if (not os.path.exists(fname)): |
||
2552 | if is_imp: |
||
2553 | continue # just ignore |
||
2554 | else: |
||
2555 | fname = par[0] # report error |
||
2556 | fnew = open(fname, "r") |
||
2557 | stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import}) |
||
2558 | fn, f, lineno, is_import = par[0], fnew, 0, is_imp |
||
2559 | elif result.group('name') == 'END': |
||
2560 | ctx = None |
||
2561 | else: |
||
2562 | warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno) |
||
2563 | continue |
||
2564 | if not ctx: |
||
2565 | if not empty.match(line): |
||
2566 | warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno) |
||
2567 | elif ctx == 'OPT': |
||
2568 | if empty.match(line): continue |
||
2569 | par = get_par(line, 1, -1, fn=fn, lineno=lineno) |
||
2570 | if not par: continue |
||
2571 | self.set_opt(par[0], par[1:], fn, lineno) |
||
2572 | elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'): |
||
2573 | if empty.match(line): continue |
||
2574 | if ctx == 'EXPORTS': |
||
2575 | par = get_par(line, 1, 6, fn=fn, lineno=lineno) |
||
2576 | else: |
||
2577 | par = get_par(line, 1, 2, fn=fn, lineno=lineno) |
||
2578 | if not par: continue |
||
2579 | flags = default_flags |
||
2580 | p = 2 |
||
2581 | if (len(par)>=2): |
||
2582 | if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS |
||
2583 | elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE |
||
2584 | elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS |
||
2585 | elif (ctx == 'EXPORTS'): p = 1 |
||
2586 | else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno) |
||
2587 | for i in range(p, len(par)): |
||
2588 | if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM |
||
2589 | elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM |
||
2590 | elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE |
||
2591 | elif (par[i] == 'WS_DLL'): flags |= EF_WS_DLL |
||
2592 | elif (par[i] == 'EXTERN'): flags |= EF_EXTERN |
||
2593 | elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT |
||
2594 | else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) |
||
2595 | self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno) |
||
2596 | elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'): |
||
2597 | if empty.match(line): continue |
||
2598 | par = get_par(line, 1, 4, fn=fn, lineno=lineno) |
||
2599 | if not par: continue |
||
2600 | flags = default_flags |
||
2601 | for i in range(1, len(par)): |
||
2602 | if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT |
||
2603 | elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT |
||
2604 | elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE |
||
2605 | elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE |
||
2606 | elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE |
||
2607 | elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE |
||
2608 | else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) |
||
2609 | self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno) |
||
2610 | elif ctx == 'USE_VALS_EXT': |
||
2611 | if empty.match(line): continue |
||
2612 | par = get_par(line, 1, 1, fn=fn, lineno=lineno) |
||
2613 | if not par: continue |
||
2614 | flags = default_flags |
||
2615 | self.add_item('USE_VALS_EXT', par[0], flag=flags, fn=fn, lineno=lineno) |
||
2616 | elif ctx == 'PDU': |
||
2617 | if empty.match(line): continue |
||
2618 | par = get_par(line, 1, 5, fn=fn, lineno=lineno) |
||
2619 | if not par: continue |
||
2620 | self.add_pdu(par[0:2], fn, lineno) |
||
2621 | if (len(par)>=3): |
||
2622 | self.add_register(par[0], par[2:5], fn, lineno) |
||
2623 | elif ctx == 'SYNTAX': |
||
2624 | if empty.match(line): continue |
||
2625 | par = get_par(line, 1, 2, fn=fn, lineno=lineno) |
||
2626 | if not par: continue |
||
2627 | if not self.check_item('PDU', par[0]): |
||
2628 | self.add_pdu(par[0:1], fn, lineno) |
||
2629 | self.add_syntax(par, fn, lineno) |
||
2630 | elif ctx == 'REGISTER': |
||
2631 | if empty.match(line): continue |
||
2632 | par = get_par(line, 3, 4, fn=fn, lineno=lineno) |
||
2633 | if not par: continue |
||
2634 | if not self.check_item('PDU', par[0]): |
||
2635 | self.add_pdu(par[0:1], fn, lineno) |
||
2636 | self.add_register(par[0], par[1:4], fn, lineno) |
||
2637 | elif ctx in ('MODULE', 'MODULE_IMPORT'): |
||
2638 | if empty.match(line): continue |
||
2639 | par = get_par(line, 2, 2, fn=fn, lineno=lineno) |
||
2640 | if not par: continue |
||
2641 | self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno) |
||
2642 | elif ctx == 'IMPORT_TAG': |
||
2643 | if empty.match(line): continue |
||
2644 | par = get_par(line, 3, 3, fn=fn, lineno=lineno) |
||
2645 | if not par: continue |
||
2646 | self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno) |
||
2647 | elif ctx == 'OMIT_ASSIGNMENT': |
||
2648 | if empty.match(line): continue |
||
2649 | par = get_par(line, 1, 1, fn=fn, lineno=lineno) |
||
2650 | if not par: continue |
||
2651 | self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno) |
||
2652 | elif ctx == 'NO_OMIT_ASSGN': |
||
2653 | if empty.match(line): continue |
||
2654 | par = get_par(line, 1, 1, fn=fn, lineno=lineno) |
||
2655 | if not par: continue |
||
2656 | self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno) |
||
2657 | elif ctx == 'VIRTUAL_ASSGN': |
||
2658 | if empty.match(line): continue |
||
2659 | par = get_par(line, 2, -1, fn=fn, lineno=lineno) |
||
2660 | if not par: continue |
||
2661 | if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]): |
||
2662 | self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno) |
||
2663 | self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno) |
||
2664 | for nm in par[2:]: |
||
2665 | self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno) |
||
2666 | if not par[0][0].isupper(): |
||
2667 | warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]), |
||
2668 | UserWarning, fn, lineno) |
||
2669 | elif ctx == 'SET_TYPE': |
||
2670 | if empty.match(line): continue |
||
2671 | par = get_par(line, 2, 2, fn=fn, lineno=lineno) |
||
2672 | if not par: continue |
||
2673 | if not self.check_item('VIRTUAL_ASSGN', par[0]): |
||
2674 | self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno) |
||
2675 | if not par[1][0].isupper(): |
||
2676 | warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]), |
||
2677 | UserWarning, fn, lineno) |
||
2678 | elif ctx == 'ASSIGN_VALUE_TO_TYPE': |
||
2679 | if empty.match(line): continue |
||
2680 | par = get_par(line, 2, 2, fn=fn, lineno=lineno) |
||
2681 | if not par: continue |
||
2682 | self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno) |
||
2683 | elif ctx == 'TYPE_RENAME': |
||
2684 | if empty.match(line): continue |
||
2685 | par = get_par(line, 2, 2, fn=fn, lineno=lineno) |
||
2686 | if not par: continue |
||
2687 | self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno) |
||
2688 | if not par[1][0].isupper(): |
||
2689 | warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]), |
||
2690 | UserWarning, fn, lineno) |
||
2691 | elif ctx == 'FIELD_RENAME': |
||
2692 | if empty.match(line): continue |
||
2693 | par = get_par(line, 2, 2, fn=fn, lineno=lineno) |
||
2694 | if not par: continue |
||
2695 | self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno) |
||
2696 | if not par[1][0].islower(): |
||
2697 | warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]), |
||
2698 | UserWarning, fn, lineno) |
||
2699 | elif ctx == 'TF_RENAME': |
||
2700 | if empty.match(line): continue |
||
2701 | par = get_par(line, 2, 2, fn=fn, lineno=lineno) |
||
2702 | if not par: continue |
||
2703 | tmpu = par[1][0].upper() + par[1][1:] |
||
2704 | tmpl = par[1][0].lower() + par[1][1:] |
||
2705 | self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno) |
||
2706 | if not tmpu[0].isupper(): |
||
2707 | warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]), |
||
2708 | UserWarning, fn, lineno) |
||
2709 | self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno) |
||
2710 | if not tmpl[0].islower(): |
||
2711 | warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]), |
||
2712 | UserWarning, fn, lineno) |
||
2713 | elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'): |
||
2714 | if empty.match(line): continue |
||
2715 | par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno) |
||
2716 | if not par: continue |
||
2717 | self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno) |
||
2718 | elif ctx == 'FN_PARS': |
||
2719 | if empty.match(line): continue |
||
2720 | if name: |
||
2721 | par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno) |
||
2722 | else: |
||
2723 | par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno) |
||
2724 | if not par: continue |
||
2725 | if name: |
||
2726 | self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno) |
||
2727 | else: |
||
2728 | self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno) |
||
2729 | elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'): |
||
2730 | result = cdirective.search(line) |
||
2731 | if result: # directive |
||
2732 | line = '#' + line[result.end():] |
||
2733 | self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno) |
||
2734 | elif ctx == 'CLASS': |
||
2735 | if empty.match(line): continue |
||
2736 | par = get_par(line, 1, 3, fn=fn, lineno=lineno) |
||
2737 | if not par: continue |
||
2738 | if not set_type_to_class(name, par[0], par[1:]): |
||
2739 | warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]), |
||
2740 | UserWarning, fn, lineno) |
||
2741 | elif ctx == 'TABLE': |
||
2742 | self.report[name][-1]['text'] += line |
||
2743 | |||
2744 | def set_opt(self, opt, par, fn, lineno): |
||
2745 | #print "set_opt: %s, %s" % (opt, par) |
||
2746 | if opt in ("-I",): |
||
2747 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2748 | if not par: return |
||
2749 | self.include_path.append(relpath(par[0])) |
||
2750 | elif opt in ("-b", "BER", "CER", "DER"): |
||
2751 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2752 | self.ectx.encoding = 'ber' |
||
2753 | elif opt in ("PER",): |
||
2754 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2755 | self.ectx.encoding = 'per' |
||
2756 | elif opt in ("-p", "PROTO"): |
||
2757 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2758 | if not par: return |
||
2759 | self.ectx.proto_opt = par[0] |
||
2760 | self.ectx.merge_modules = True |
||
2761 | elif opt in ("ALIGNED",): |
||
2762 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2763 | self.ectx.aligned = True |
||
2764 | elif opt in ("-u", "UNALIGNED"): |
||
2765 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2766 | self.ectx.aligned = False |
||
2767 | elif opt in ("-d",): |
||
2768 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2769 | if not par: return |
||
2770 | self.ectx.dbgopt = par[0] |
||
2771 | elif opt in ("-e",): |
||
2772 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2773 | self.ectx.expcnf = True |
||
2774 | elif opt in ("-S",): |
||
2775 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2776 | self.ectx.merge_modules = True |
||
2777 | elif opt in ("GROUP_BY_PROT",): |
||
2778 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2779 | self.ectx.group_by_prot = True |
||
2780 | elif opt in ("-o",): |
||
2781 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2782 | if not par: return |
||
2783 | self.ectx.outnm_opt = par[0] |
||
2784 | elif opt in ("-O",): |
||
2785 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2786 | if not par: return |
||
2787 | self.ectx.output.outdir = relpath(par[0]) |
||
2788 | elif opt in ("-s",): |
||
2789 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2790 | if not par: return |
||
2791 | self.ectx.output.single_file = relpath(par[0]) |
||
2792 | elif opt in ("-k",): |
||
2793 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2794 | self.ectx.output.keep = True |
||
2795 | elif opt in ("-L",): |
||
2796 | par = self.check_par(par, 0, 0, fn, lineno) |
||
2797 | self.suppress_line = True |
||
2798 | elif opt in ("EMBEDDED_PDV_CB",): |
||
2799 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2800 | if not par: return |
||
2801 | self.ectx.default_embedded_pdv_cb = par[0] |
||
2802 | elif opt in ("EXTERNAL_TYPE_CB",): |
||
2803 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2804 | if not par: return |
||
2805 | self.ectx.default_external_type_cb = par[0] |
||
2806 | elif opt in ("-r",): |
||
2807 | par = self.check_par(par, 1, 1, fn, lineno) |
||
2808 | if not par: return |
||
2809 | self.ectx.remove_prefix = par[0] |
||
2810 | else: |
||
2811 | warnings.warn_explicit("Unknown option %s" % (opt), |
||
2812 | UserWarning, fn, lineno) |
||
2813 | |||
2814 | def dbg_print(self): |
||
2815 | print("\n# Conformance values") |
||
2816 | print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")) |
||
2817 | print("-" * 100) |
||
2818 | tbls = sorted(self.table.keys()) |
||
2819 | for t in tbls: |
||
2820 | keys = sorted(self.table[t].keys()) |
||
2821 | for k in keys: |
||
2822 | print("%-15s %4s %-15s %-20s %s" % ( |
||
2823 | self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))) |
||
2824 | |||
2825 | def unused_report(self): |
||
2826 | tbls = sorted(self.table.keys()) |
||
2827 | for t in tbls: |
||
2828 | if not self.tblcfg[t]['chk_use']: continue |
||
2829 | keys = sorted(self.table[t].keys()) |
||
2830 | for k in keys: |
||
2831 | if not self.table[t][k]['used']: |
||
2832 | warnings.warn_explicit("Unused %s for %s" % (t, k), |
||
2833 | UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno']) |
||
2834 | fnms = list(self.fn.keys()) |
||
2835 | fnms.sort() |
||
2836 | for f in fnms: |
||
2837 | keys = sorted(self.fn[f].keys()) |
||
2838 | for k in keys: |
||
2839 | if not self.fn[f][k]: continue |
||
2840 | if not self.fn[f][k]['used']: |
||
2841 | warnings.warn_explicit("Unused %s for %s" % (k, f), |
||
2842 | UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno']) |
||
2843 | |||
2844 | #--- EthOut ------------------------------------------------------------------- |
||
2845 | class EthOut: |
||
2846 | def __init__(self): |
||
2847 | self.ectx = None |
||
2848 | self.outnm = None |
||
2849 | self.outdir = '.' |
||
2850 | self.single_file = None |
||
2851 | self.created_files = {} |
||
2852 | self.created_files_ord = [] |
||
2853 | self.keep = False |
||
2854 | |||
2855 | def outcomment(self, ln, comment=None): |
||
2856 | if comment: |
||
2857 | return '%s %s\n' % (comment, ln) |
||
2858 | else: |
||
2859 | return '/* %-74s */\n' % (ln) |
||
2860 | |||
2861 | def created_file_add(self, name, keep_anyway): |
||
2862 | name = os.path.normcase(os.path.abspath(name)) |
||
2863 | if name not in self.created_files: |
||
2864 | self.created_files_ord.append(name) |
||
2865 | self.created_files[name] = keep_anyway |
||
2866 | else: |
||
2867 | self.created_files[name] = self.created_files[name] or keep_anyway |
||
2868 | |||
2869 | def created_file_exists(self, name): |
||
2870 | name = os.path.normcase(os.path.abspath(name)) |
||
2871 | return name in self.created_files |
||
2872 | |||
2873 | #--- output_fname ------------------------------------------------------- |
||
2874 | def output_fname(self, ftype, ext='c'): |
||
2875 | fn = '' |
||
2876 | if not ext in ('cnf',): |
||
2877 | fn += 'packet-' |
||
2878 | fn += self.outnm |
||
2879 | if (ftype): |
||
2880 | fn += '-' + ftype |
||
2881 | fn += '.' + ext |
||
2882 | return fn |
||
2883 | #--- file_open ------------------------------------------------------- |
||
2884 | def file_open(self, ftype, ext='c'): |
||
2885 | fn = self.output_fname(ftype, ext=ext) |
||
2886 | if self.created_file_exists(fn): |
||
2887 | fx = open(fn, 'a') |
||
2888 | else: |
||
2889 | fx = open(fn, 'w') |
||
2890 | comment = None |
||
2891 | if ext in ('cnf',): |
||
2892 | comment = '#' |
||
2893 | fx.write(self.fhdr(fn, comment = comment)) |
||
2894 | else: |
||
2895 | if (not self.single_file and not self.created_file_exists(fn)): |
||
2896 | fx.write(self.fhdr(fn)) |
||
2897 | if not self.ectx.merge_modules: |
||
2898 | fx.write('\n') |
||
2899 | mstr = "--- " |
||
2900 | if self.ectx.groups(): |
||
2901 | mstr += "Module" |
||
2902 | if (len(self.ectx.modules) > 1): |
||
2903 | mstr += "s" |
||
2904 | for (m, p) in self.ectx.modules: |
||
2905 | mstr += " %s" % (m) |
||
2906 | else: |
||
2907 | mstr += "Module %s" % (self.ectx.Module()) |
||
2908 | mstr += " --- --- ---" |
||
2909 | fx.write(self.outcomment(mstr, comment)) |
||
2910 | fx.write('\n') |
||
2911 | return fx |
||
2912 | #--- file_close ------------------------------------------------------- |
||
2913 | def file_close(self, fx, discard=False, keep_anyway=False): |
||
2914 | fx.close() |
||
2915 | if discard and not self.created_file_exists(fx.name): |
||
2916 | os.unlink(fx.name) |
||
2917 | else: |
||
2918 | self.created_file_add(fx.name, keep_anyway) |
||
2919 | #--- fhdr ------------------------------------------------------- |
||
2920 | def fhdr(self, fn, comment=None): |
||
2921 | out = '' |
||
2922 | out += self.outcomment('Do not modify this file. Changes will be overwritten.', comment) |
||
2923 | out += self.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment) |
||
2924 | out += self.outcomment(os.path.basename(fn), comment) |
||
2925 | out += self.outcomment(' '.join(['asn2wrs.py'] + sys.argv[1:]), comment) |
||
2926 | out += '\n' |
||
2927 | # Make Windows path separator look like Unix path separator |
||
2928 | out = out.replace('\\', '/') |
||
2929 | # Change absolute paths and relative paths generated outside |
||
2930 | # source directory to paths relative to asn1/<proto> subdir. |
||
2931 | out = re.sub(r'(\s)[./A-Z]\S*/dissectors\b', r'\1../..', out) |
||
2932 | out = re.sub(r'(\s)[./A-Z]\S*/asn1/\S*?([\s/])', r'\1.\2', out) |
||
2933 | return out |
||
2934 | |||
2935 | #--- dbg_print ------------------------------------------------------- |
||
2936 | def dbg_print(self): |
||
2937 | print("\n# Output files") |
||
2938 | print("\n".join(self.created_files_ord)) |
||
2939 | print("\n") |
||
2940 | |||
2941 | #--- make_single_file ------------------------------------------------------- |
||
2942 | def make_single_file(self): |
||
2943 | if (not self.single_file): return |
||
2944 | in_nm = self.single_file + '.c' |
||
2945 | out_nm = os.path.join(self.outdir, self.output_fname('')) |
||
2946 | self.do_include(out_nm, in_nm) |
||
2947 | in_nm = self.single_file + '.h' |
||
2948 | if (os.path.exists(in_nm)): |
||
2949 | out_nm = os.path.join(self.outdir, self.output_fname('', ext='h')) |
||
2950 | self.do_include(out_nm, in_nm) |
||
2951 | if (not self.keep): |
||
2952 | for fn in self.created_files_ord: |
||
2953 | if not self.created_files[fn]: |
||
2954 | os.unlink(fn) |
||
2955 | |||
2956 | #--- do_include ------------------------------------------------------- |
||
2957 | def do_include(self, out_nm, in_nm): |
||
2958 | def check_file(fn, fnlist): |
||
2959 | fnfull = os.path.normcase(os.path.abspath(fn)) |
||
2960 | if (fnfull in fnlist and os.path.exists(fnfull)): |
||
2961 | return os.path.normpath(fn) |
||
2962 | return None |
||
2963 | fin = open(in_nm, "r") |
||
2964 | fout = open(out_nm, "w") |
||
2965 | fout.write(self.fhdr(out_nm)) |
||
2966 | fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n') |
||
2967 | fout.write('\n') |
||
2968 | fout.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm))) |
||
2969 | |||
2970 | include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE) |
||
2971 | |||
2972 | cont_linenum = 0; |
||
2973 | |||
2974 | while (True): |
||
2975 | cont_linenum = cont_linenum + 1; |
||
2976 | line = fin.readline() |
||
2977 | if (line == ''): break |
||
2978 | ifile = None |
||
2979 | result = include.search(line) |
||
2980 | #if (result): print os.path.normcase(os.path.abspath(result.group('fname'))) |
||
2981 | if (result): |
||
2982 | ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files) |
||
2983 | if (not ifile): |
||
2984 | ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files) |
||
2985 | if (not ifile): |
||
2986 | ifile = check_file(result.group('fname'), self.created_files) |
||
2987 | if (ifile): |
||
2988 | fout.write('\n') |
||
2989 | fout.write('/*--- Included file: ' + ifile + ' ---*/\n') |
||
2990 | fout.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile))) |
||
2991 | finc = open(ifile, "r") |
||
2992 | fout.write(finc.read()) |
||
2993 | fout.write('\n') |
||
2994 | fout.write('/*--- End of included file: ' + ifile + ' ---*/\n') |
||
2995 | fout.write('#line %u "%s"\n' % (cont_linenum+1, rel_dissector_path(in_nm)) ) |
||
2996 | finc.close() |
||
2997 | else: |
||
2998 | fout.write(line) |
||
2999 | |||
3000 | fout.close() |
||
3001 | fin.close() |
||
3002 | |||
3003 | |||
3004 | #--- Node --------------------------------------------------------------------- |
||
3005 | class Node: |
||
3006 | def __init__(self,*args, **kw): |
||
3007 | if len (args) == 0: |
||
3008 | self.type = self.__class__.__name__ |
||
3009 | else: |
||
3010 | assert (len(args) == 1) |
||
3011 | self.type = args[0] |
||
3012 | self.__dict__.update (kw) |
||
3013 | def str_child (self, key, child, depth): |
||
3014 | indent = " " * (2 * depth) |
||
3015 | keystr = indent + key + ": " |
||
3016 | if key == 'type': # already processed in str_depth |
||
3017 | return "" |
||
3018 | if isinstance (child, Node): # ugh |
||
3019 | return keystr + "\n" + child.str_depth (depth+1) |
||
3020 | if isinstance(child, type ([])): |
||
3021 | l = [] |
||
3022 | for x in child: |
||
3023 | if isinstance (x, Node): |
||
3024 | l.append (x.str_depth (depth+1)) |
||
3025 | else: |
||
3026 | l.append (indent + " " + str(x) + "\n") |
||
3027 | return keystr + "[\n" + ''.join(l) + indent + "]\n" |
||
3028 | else: |
||
3029 | return keystr + str (child) + "\n" |
||
3030 | def str_depth (self, depth): # ugh |
||
3031 | indent = " " * (2 * depth) |
||
3032 | l = ["%s%s" % (indent, self.type)] |
||
3033 | l.append ("".join ([self.str_child (k_v[0], k_v[1], depth + 1) for k_v in list(self.__dict__.items ())])) |
||
3034 | return "\n".join (l) |
||
3035 | def __repr__(self): |
||
3036 | return "\n" + self.str_depth (0) |
||
3037 | def to_python (self, ctx): |
||
3038 | return self.str_depth (ctx.indent_lev) |
||
3039 | |||
3040 | def eth_reg(self, ident, ectx): |
||
3041 | pass |
||
3042 | |||
3043 | def fld_obj_repr(self, ectx): |
||
3044 | return "/* TO DO %s */" % (str(self)) |
||
3045 | |||
3046 | |||
3047 | #--- ValueAssignment ------------------------------------------------------------- |
||
3048 | class ValueAssignment (Node): |
||
3049 | def __init__(self,*args, **kw) : |
||
3050 | Node.__init__ (self,*args, **kw) |
||
3051 | |||
3052 | def eth_reg(self, ident, ectx): |
||
3053 | if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit |
||
3054 | ectx.eth_reg_vassign(self) |
||
3055 | ectx.eth_reg_value(self.ident, self.typ, self.val) |
||
3056 | |||
3057 | #--- ObjectAssignment ------------------------------------------------------------- |
||
3058 | class ObjectAssignment (Node): |
||
3059 | def __init__(self,*args, **kw) : |
||
3060 | Node.__init__ (self,*args, **kw) |
||
3061 | |||
3062 | def __eq__(self, other): |
||
3063 | if self.cls != other.cls: |
||
3064 | return False |
||
3065 | if len(self.val) != len(other.val): |
||
3066 | return False |
||
3067 | for f in (list(self.val.keys())): |
||
3068 | if f not in other.val: |
||
3069 | return False |
||
3070 | if isinstance(self.val[f], Node) and isinstance(other.val[f], Node): |
||
3071 | if not self.val[f].fld_obj_eq(other.val[f]): |
||
3072 | return False |
||
3073 | else: |
||
3074 | if str(self.val[f]) != str(other.val[f]): |
||
3075 | return False |
||
3076 | return True |
||
3077 | |||
3078 | def eth_reg(self, ident, ectx): |
||
3079 | def make_virtual_type(cls, field, prefix): |
||
3080 | if isinstance(self.val, str): return |
||
3081 | if field in self.val and not isinstance(self.val[field], Type_Ref): |
||
3082 | vnm = prefix + '-' + self.ident |
||
3083 | virtual_tr = Type_Ref(val = vnm) |
||
3084 | t = self.val[field] |
||
3085 | self.val[field] = virtual_tr |
||
3086 | ectx.eth_reg_assign(vnm, t, virt=True) |
||
3087 | ectx.eth_reg_type(vnm, t) |
||
3088 | t.eth_reg_sub(vnm, ectx) |
||
3089 | if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field): |
||
3090 | ectx.eth_reg_field(self.val[field].val, self.val[field].val, impl=self.val[field].HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', cls + '.' + field)) |
||
3091 | return |
||
3092 | # end of make_virtual_type() |
||
3093 | if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit |
||
3094 | self.module = ectx.Module() |
||
3095 | ectx.eth_reg_oassign(self) |
||
3096 | if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'): |
||
3097 | make_virtual_type(self.cls, '&Type', 'TYPE') |
||
3098 | if (self.cls == 'OPERATION'): |
||
3099 | make_virtual_type(self.cls, '&ArgumentType', 'ARG') |
||
3100 | make_virtual_type(self.cls, '&ResultType', 'RES') |
||
3101 | if (self.cls == 'ERROR'): |
||
3102 | make_virtual_type(self.cls, '&ParameterType', 'PAR') |
||
3103 | |||
3104 | |||
3105 | #--- Type --------------------------------------------------------------------- |
||
3106 | class Type (Node): |
||
3107 | def __init__(self,*args, **kw) : |
||
3108 | self.name = None |
||
3109 | self.constr = None |
||
3110 | self.tags = [] |
||
3111 | self.named_list = None |
||
3112 | Node.__init__ (self,*args, **kw) |
||
3113 | |||
3114 | def IsNamed(self): |
||
3115 | if self.name is None : |
||
3116 | return False |
||
3117 | else: |
||
3118 | return True |
||
3119 | |||
3120 | def HasConstraint(self): |
||
3121 | if self.constr is None : |
||
3122 | return False |
||
3123 | else : |
||
3124 | return True |
||
3125 | |||
3126 | def HasSizeConstraint(self): |
||
3127 | return self.HasConstraint() and self.constr.IsSize() |
||
3128 | |||
3129 | def HasValueConstraint(self): |
||
3130 | return self.HasConstraint() and self.constr.IsValue() |
||
3131 | |||
3132 | def HasPermAlph(self): |
||
3133 | return self.HasConstraint() and self.constr.IsPermAlph() |
||
3134 | |||
3135 | def HasContentsConstraint(self): |
||
3136 | return self.HasConstraint() and self.constr.IsContents() |
||
3137 | |||
3138 | def HasOwnTag(self): |
||
3139 | return len(self.tags) > 0 |
||
3140 | |||
3141 | def HasImplicitTag(self, ectx): |
||
3142 | return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx)) |
||
3143 | |||
3144 | def IndetermTag(self, ectx): |
||
3145 | return False |
||
3146 | |||
3147 | def AddTag(self, tag): |
||
3148 | self.tags[0:0] = [tag] |
||
3149 | |||
3150 | def GetTag(self, ectx): |
||
3151 | #print "GetTag(%s)\n" % self.name; |
||
3152 | if (self.HasOwnTag()): |
||
3153 | return self.tags[0].GetTag(ectx) |
||
3154 | else: |
||
3155 | return self.GetTTag(ectx) |
||
3156 | |||
3157 | def GetTTag(self, ectx): |
||
3158 | print("#Unhandled GetTTag() in %s" % (self.type)) |
||
3159 | print(self.str_depth(1)) |
||
3160 | return ('BER_CLASS_unknown', 'TAG_unknown') |
||
3161 | |||
3162 | def SetName(self, name): |
||
3163 | self.name = name |
||
3164 | |||
3165 | def AddConstraint(self, constr): |
||
3166 | if not self.HasConstraint(): |
||
3167 | self.constr = constr |
||
3168 | else: |
||
3169 | self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr]) |
||
3170 | |||
3171 | def eth_tname(self): |
||
3172 | return '#' + self.type + '_' + str(id(self)) |
||
3173 | |||
3174 | def eth_ftype(self, ectx): |
||
3175 | return ('FT_NONE', 'BASE_NONE') |
||
3176 | |||
3177 | def eth_strings(self): |
||
3178 | return 'NULL' |
||
3179 | |||
3180 | def eth_omit_field(self): |
||
3181 | return False |
||
3182 | |||
3183 | def eth_need_tree(self): |
||
3184 | return False |
||
3185 | |||
3186 | def eth_has_vals(self): |
||
3187 | return False |
||
3188 | |||
3189 | def eth_has_enum(self, tname, ectx): |
||
3190 | return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM) |
||
3191 | |||
3192 | def eth_need_pdu(self, ectx): |
||
3193 | return None |
||
3194 | |||
3195 | def eth_named_bits(self): |
||
3196 | return None |
||
3197 | |||
3198 | def eth_reg_sub(self, ident, ectx): |
||
3199 | pass |
||
3200 | |||
3201 | def get_components(self, ectx): |
||
3202 | print("#Unhandled get_components() in %s" % (self.type)) |
||
3203 | print(self.str_depth(1)) |
||
3204 | return [] |
||
3205 | |||
3206 | def sel_req(self, sel, ectx): |
||
3207 | print("#Selection '%s' required for non-CHOICE type %s" % (sel, self.type)) |
||
3208 | print(self.str_depth(1)) |
||
3209 | |||
3210 | def fld_obj_eq(self, other): |
||
3211 | return isinstance(other, Type) and (self.eth_tname() == other.eth_tname()) |
||
3212 | |||
3213 | def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None): |
||
3214 | #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent)) |
||
3215 | #print " ", self |
||
3216 | if (ectx.NeedTags() and (len(self.tags) > tstrip)): |
||
3217 | tagged_type = self |
||
3218 | for i in range(len(self.tags)-1, tstrip-1, -1): |
||
3219 | tagged_type = TaggedType(val=tagged_type, tstrip=i) |
||
3220 | tagged_type.AddTag(self.tags[i]) |
||
3221 | if not tagflag: # 1st tagged level |
||
3222 | if self.IsNamed() and not selflag: |
||
3223 | tagged_type.SetName(self.name) |
||
3224 | tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent) |
||
3225 | return |
||
3226 | nm = '' |
||
3227 | if ident and self.IsNamed() and not tagflag and not selflag: |
||
3228 | nm = ident + '/' + self.name |
||
3229 | elif ident: |
||
3230 | nm = ident |
||
3231 | elif self.IsNamed(): |
||
3232 | nm = self.name |
||
3233 | if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit |
||
3234 | if not ident: # Assignment |
||
3235 | ectx.eth_reg_assign(nm, self) |
||
3236 | if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx): |
||
3237 | ectx.eth_reg_type(nm, self) |
||
3238 | virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm)) |
||
3239 | if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm): |
||
3240 | if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag): |
||
3241 | if ectx.conform.check_item('SET_TYPE', nm): |
||
3242 | ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference |
||
3243 | else: |
||
3244 | ectx.eth_reg_type(nm, self) # new type |
||
3245 | trnm = nm |
||
3246 | elif ectx.conform.check_item('SET_TYPE', nm): |
||
3247 | trnm = ectx.conform.use_item('SET_TYPE', nm) |
||
3248 | elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx): |
||
3249 | ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints |
||
3250 | trnm = nm |
||
3251 | else: |
||
3252 | trnm = self.val |
||
3253 | else: |
||
3254 | ectx.eth_reg_type(nm, self) |
||
3255 | trnm = nm |
||
3256 | if ectx.conform.check_item('VIRTUAL_ASSGN', nm): |
||
3257 | vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm) |
||
3258 | ectx.eth_reg_assign(vnm, self, virt=True) |
||
3259 | ectx.eth_reg_type(vnm, self) |
||
3260 | self.eth_reg_sub(vnm, ectx) |
||
3261 | if parent and (ectx.type[parent]['val'].type == 'TaggedType'): |
||
3262 | ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx) |
||
3263 | if ident and not tagflag and not self.eth_omit_field(): |
||
3264 | ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx)) |
||
3265 | if ectx.conform.check_item('SET_TYPE', nm): |
||
3266 | virtual_tr.eth_reg_sub(nm, ectx) |
||
3267 | else: |
||
3268 | self.eth_reg_sub(nm, ectx) |
||
3269 | |||
3270 | def eth_get_size_constr(self, ectx): |
||
3271 | (minv, maxv, ext) = ('MIN', 'MAX', False) |
||
3272 | if self.HasSizeConstraint(): |
||
3273 | if self.constr.IsSize(): |
||
3274 | (minv, maxv, ext) = self.constr.GetSize(ectx) |
||
3275 | if (self.constr.type == 'Intersection'): |
||
3276 | if self.constr.subtype[0].IsSize(): |
||
3277 | (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx) |
||
3278 | elif self.constr.subtype[1].IsSize(): |
||
3279 | (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx) |
||
3280 | if minv == 'MIN': minv = 'NO_BOUND' |
||
3281 | if maxv == 'MAX': maxv = 'NO_BOUND' |
||
3282 | if (ext): ext = 'TRUE' |
||
3283 | else: ext = 'FALSE' |
||
3284 | return (minv, maxv, ext) |
||
3285 | |||
3286 | def eth_get_value_constr(self, ectx): |
||
3287 | (minv, maxv, ext) = ('MIN', 'MAX', False) |
||
3288 | if self.HasValueConstraint(): |
||
3289 | (minv, maxv, ext) = self.constr.GetValue(ectx) |
||
3290 | if minv == 'MIN': minv = 'NO_BOUND' |
||
3291 | if maxv == 'MAX': maxv = 'NO_BOUND' |
||
3292 | if str(minv).isdigit(): |
||
3293 | minv += 'U' |
||
3294 | elif (str(minv)[0] == "-") and str(minv)[1:].isdigit(): |
||
3295 | if (int(minv) == -(2**31)): |
||
3296 | minv = "G_MININT32" |
||
3297 | elif (int(minv) < -(2**31)): |
||
3298 | minv = "G_GINT64_CONSTANT(%s)" % (str(minv)) |
||
3299 | if str(maxv).isdigit(): |
||
3300 | if (int(maxv) >= 2**32): |
||
3301 | maxv = "G_GUINT64_CONSTANT(%s)" % (str(maxv)) |
||
3302 | else: |
||
3303 | maxv += 'U' |
||
3304 | if (ext): ext = 'TRUE' |
||
3305 | else: ext = 'FALSE' |
||
3306 | return (minv, maxv, ext) |
||
3307 | |||
3308 | def eth_get_alphabet_constr(self, ectx): |
||
3309 | (alph, alphlen) = ('NULL', '0') |
||
3310 | if self.HasPermAlph(): |
||
3311 | alph = self.constr.GetPermAlph(ectx) |
||
3312 | if not alph: |
||
3313 | alph = 'NULL' |
||
3314 | if (alph != 'NULL'): |
||
3315 | if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))): |
||
3316 | alphlen = str(len(alph) - 2) |
||
3317 | else: |
||
3318 | alphlen = 'strlen(%s)' % (alph) |
||
3319 | return (alph, alphlen) |
||
3320 | |||
3321 | def eth_type_vals(self, tname, ectx): |
||
3322 | if self.eth_has_vals(): |
||
3323 | print("#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)) |
||
3324 | print(self.str_depth(1)) |
||
3325 | return '' |
||
3326 | |||
3327 | def eth_type_enum(self, tname, ectx): |
||
3328 | if self.eth_has_enum(tname, ectx): |
||
3329 | print("#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)) |
||
3330 | print(self.str_depth(1)) |
||
3331 | return '' |
||
3332 | |||
3333 | def eth_type_default_table(self, ectx, tname): |
||
3334 | return '' |
||
3335 | |||
3336 | def eth_type_default_body(self, ectx): |
||
3337 | print("#Unhandled eth_type_default_body() in %s" % (self.type)) |
||
3338 | print(self.str_depth(1)) |
||
3339 | return '' |
||
3340 | |||
3341 | def eth_type_default_pars(self, ectx, tname): |
||
3342 | pars = { |
||
3343 | 'TNAME' : tname, |
||
3344 | 'ER' : ectx.encp(), |
||
3345 | 'FN_VARIANT' : '', |
||
3346 | 'TREE' : 'tree', |
||
3347 | 'TVB' : 'tvb', |
||
3348 | 'OFFSET' : 'offset', |
||
3349 | 'ACTX' : 'actx', |
||
3350 | 'HF_INDEX' : 'hf_index', |
||
3351 | 'VAL_PTR' : 'NULL', |
||
3352 | 'IMPLICIT_TAG' : 'implicit_tag', |
||
3353 | } |
||
3354 | if (ectx.eth_type[tname]['tree']): |
||
3355 | pars['ETT_INDEX'] = ectx.eth_type[tname]['tree'] |
||
3356 | if (ectx.merge_modules): |
||
3357 | pars['PROTOP'] = '' |
||
3358 | else: |
||
3359 | pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_' |
||
3360 | return pars |
||
3361 | |||
3362 | def eth_type_fn(self, proto, tname, ectx): |
||
3363 | body = self.eth_type_default_body(ectx, tname) |
||
3364 | pars = self.eth_type_default_pars(ectx, tname) |
||
3365 | if ectx.conform.check_item('FN_PARS', tname): |
||
3366 | pars.update(ectx.conform.use_item('FN_PARS', tname)) |
||
3367 | elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]): |
||
3368 | pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0])) |
||
3369 | pars['DEFAULT_BODY'] = body |
||
3370 | for i in range(4): |
||
3371 | for k in list(pars.keys()): |
||
3372 | try: |
||
3373 | pars[k] = pars[k] % pars |
||
3374 | except (ValueError,TypeError): |
||
3375 | raise sys.exc_info()[0]("%s\n%s" % (str(pars), sys.exc_info()[1])) |
||
3376 | out = '\n' |
||
3377 | out += self.eth_type_default_table(ectx, tname) % pars |
||
3378 | out += ectx.eth_type_fn_hdr(tname) |
||
3379 | out += ectx.eth_type_fn_body(tname, body, pars=pars) |
||
3380 | out += ectx.eth_type_fn_ftr(tname) |
||
3381 | return out |
||
3382 | |||
3383 | #--- Value -------------------------------------------------------------------- |
||
3384 | class Value (Node): |
||
3385 | def __init__(self,*args, **kw) : |
||
3386 | self.name = None |
||
3387 | Node.__init__ (self,*args, **kw) |
||
3388 | |||
3389 | def SetName(self, name) : |
||
3390 | self.name = name |
||
3391 | |||
3392 | def to_str(self, ectx): |
||
3393 | return str(self.val) |
||
3394 | |||
3395 | def get_dep(self): |
||
3396 | return None |
||
3397 | |||
3398 | def fld_obj_repr(self, ectx): |
||
3399 | return self.to_str(ectx) |
||
3400 | |||
3401 | #--- Value_Ref ----------------------------------------------------------------- |
||
3402 | class Value_Ref (Value): |
||
3403 | def to_str(self, ectx): |
||
3404 | return asn2c(self.val) |
||
3405 | |||
3406 | #--- ObjectClass --------------------------------------------------------------------- |
||
3407 | class ObjectClass (Node): |
||
3408 | def __init__(self,*args, **kw) : |
||
3409 | self.name = None |
||
3410 | Node.__init__ (self,*args, **kw) |
||
3411 | |||
3412 | def SetName(self, name): |
||
3413 | self.name = name |
||
3414 | add_class_ident(self.name) |
||
3415 | |||
3416 | def eth_reg(self, ident, ectx): |
||
3417 | if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit |
||
3418 | ectx.eth_reg_objectclass(self.name, self) |
||
3419 | |||
3420 | #--- Class_Ref ----------------------------------------------------------------- |
||
3421 | class Class_Ref (ObjectClass): |
||
3422 | pass |
||
3423 | |||
3424 | #--- ObjectClassDefn --------------------------------------------------------------------- |
||
3425 | class ObjectClassDefn (ObjectClass): |
||
3426 | def reg_types(self): |
||
3427 | for fld in self.fields: |
||
3428 | repr = fld.fld_repr() |
||
3429 | set_type_to_class(self.name, repr[0], repr[1:]) |
||
3430 | |||
3431 | |||
3432 | #--- Tag --------------------------------------------------------------- |
||
3433 | class Tag (Node): |
||
3434 | def to_python (self, ctx): |
||
3435 | return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls, |
||
3436 | self.tag_typ, |
||
3437 | self.tag.num), |
||
3438 | self.typ.to_python (ctx)) |
||
3439 | def IsImplicit(self, ectx): |
||
3440 | return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def != 'EXPLICIT'))) |
||
3441 | |||
3442 | def GetTag(self, ectx): |
||
3443 | tc = '' |
||
3444 | if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI' |
||
3445 | elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP' |
||
3446 | elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON' |
||
3447 | elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI' |
||
3448 | return (tc, self.num) |
||
3449 | |||
3450 | def eth_tname(self): |
||
3451 | n = '' |
||
3452 | if (self.cls == 'UNIVERSAL'): n = 'U' |
||
3453 | elif (self.cls == 'APPLICATION'): n = 'A' |
||
3454 | elif (self.cls == 'CONTEXT'): n = 'C' |
||
3455 | elif (self.cls == 'PRIVATE'): n = 'P' |
||
3456 | return n + str(self.num) |
||
3457 | |||
3458 | #--- Constraint --------------------------------------------------------------- |
||
3459 | constr_cnt = 0 |
||
3460 | class Constraint (Node): |
||
3461 | def to_python (self, ctx): |
||
3462 | print("Ignoring constraint:", self.type) |
||
3463 | return self.subtype.typ.to_python (ctx) |
||
3464 | def __str__ (self): |
||
3465 | return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype) |
||
3466 | |||
3467 | def eth_tname(self): |
||
3468 | return '#' + self.type + '_' + str(id(self)) |
||
3469 | |||
3470 | def IsSize(self): |
||
3471 | return (self.type == 'Size' and self.subtype.IsValue()) \ |
||
3472 | or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \ |
||
3473 | |||
3474 | def GetSize(self, ectx): |
||
3475 | (minv, maxv, ext) = ('MIN', 'MAX', False) |
||
3476 | if self.IsSize(): |
||
3477 | if self.type == 'Size': |
||
3478 | (minv, maxv, ext) = self.subtype.GetValue(ectx) |
||
3479 | elif self.type == 'Intersection': |
||
3480 | if self.subtype[0].IsSize() and not self.subtype[1].IsSize(): |
||
3481 | (minv, maxv, ext) = self.subtype[0].GetSize(ectx) |
||
3482 | elif not self.subtype[0].IsSize() and self.subtype[1].IsSize(): |
||
3483 | (minv, maxv, ext) = self.subtype[1].GetSize(ectx) |
||
3484 | return (minv, maxv, ext) |
||
3485 | |||
3486 | def IsValue(self): |
||
3487 | return self.type == 'SingleValue' \ |
||
3488 | or self.type == 'ValueRange' \ |
||
3489 | or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \ |
||
3490 | or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue())) |
||
3491 | |||
3492 | def GetValue(self, ectx): |
||
3493 | (minv, maxv, ext) = ('MIN', 'MAX', False) |
||
3494 | if self.IsValue(): |
||
3495 | if self.type == 'SingleValue': |
||
3496 | minv = ectx.value_get_eth(self.subtype) |
||
3497 | maxv = ectx.value_get_eth(self.subtype) |
||
3498 | ext = hasattr(self, 'ext') and self.ext |
||
3499 | elif self.type == 'ValueRange': |
||
3500 | minv = ectx.value_get_eth(self.subtype[0]) |
||
3501 | maxv = ectx.value_get_eth(self.subtype[1]) |
||
3502 | ext = hasattr(self, 'ext') and self.ext |
||
3503 | elif self.type == 'Intersection': |
||
3504 | if self.subtype[0].IsValue() and not self.subtype[1].IsValue(): |
||
3505 | (minv, maxv, ext) = self.subtype[0].GetValue(ectx) |
||
3506 | elif not self.subtype[0].IsValue() and self.subtype[1].IsValue(): |
||
3507 | (minv, maxv, ext) = self.subtype[1].GetValue(ectx) |
||
3508 | elif self.subtype[0].IsValue() and self.subtype[1].IsValue(): |
||
3509 | v0 = self.subtype[0].GetValue(ectx) |
||
3510 | v1 = self.subtype[1].GetValue(ectx) |
||
3511 | (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2]) |
||
3512 | elif self.type == 'Union': |
||
3513 | if self.subtype[0].IsValue() and self.subtype[1].IsValue(): |
||
3514 | v0 = self.subtype[0].GetValue(ectx) |
||
3515 | v1 = self.subtype[1].GetValue(ectx) |
||
3516 | (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2]) |
||
3517 | return (minv, maxv, ext) |
||
3518 | |||
3519 | def IsAlphabet(self): |
||
3520 | return self.type == 'SingleValue' \ |
||
3521 | or self.type == 'ValueRange' \ |
||
3522 | or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \ |
||
3523 | or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet())) |
||
3524 | |||
3525 | def GetAlphabet(self, ectx): |
||
3526 | alph = None |
||
3527 | if self.IsAlphabet(): |
||
3528 | if self.type == 'SingleValue': |
||
3529 | alph = ectx.value_get_eth(self.subtype) |
||
3530 | elif self.type == 'ValueRange': |
||
3531 | if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \ |
||
3532 | and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')): |
||
3533 | alph = '"' |
||
3534 | for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1): |
||
3535 | alph += chr(c) |
||
3536 | alph += '"' |
||
3537 | elif self.type == 'Union': |
||
3538 | if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet(): |
||
3539 | a0 = self.subtype[0].GetAlphabet(ectx) |
||
3540 | a1 = self.subtype[1].GetAlphabet(ectx) |
||
3541 | if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \ |
||
3542 | and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)): |
||
3543 | alph = '"' + a0[1:-1] + a1[1:-1] + '"' |
||
3544 | else: |
||
3545 | alph = a0 + ' ' + a1 |
||
3546 | return alph |
||
3547 | |||
3548 | def IsPermAlph(self): |
||
3549 | return self.type == 'From' and self.subtype.IsAlphabet() \ |
||
3550 | or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \ |
||
3551 | |||
3552 | def GetPermAlph(self, ectx): |
||
3553 | alph = None |
||
3554 | if self.IsPermAlph(): |
||
3555 | if self.type == 'From': |
||
3556 | alph = self.subtype.GetAlphabet(ectx) |
||
3557 | elif self.type == 'Intersection': |
||
3558 | if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph(): |
||
3559 | alph = self.subtype[0].GetPermAlph(ectx) |
||
3560 | elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph(): |
||
3561 | alph = self.subtype[1].GetPermAlph(ectx) |
||
3562 | return alph |
||
3563 | |||
3564 | def IsContents(self): |
||
3565 | return self.type == 'Contents' \ |
||
3566 | or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \ |
||
3567 | |||
3568 | def GetContents(self, ectx): |
||
3569 | contents = None |
||
3570 | if self.IsContents(): |
||
3571 | if self.type == 'Contents': |
||
3572 | if self.subtype.type == 'Type_Ref': |
||
3573 | contents = self.subtype.val |
||
3574 | elif self.type == 'Intersection': |
||
3575 | if self.subtype[0].IsContents() and not self.subtype[1].IsContents(): |
||
3576 | contents = self.subtype[0].GetContents(ectx) |
||
3577 | elif not self.subtype[0].IsContents() and self.subtype[1].IsContents(): |
||
3578 | contents = self.subtype[1].GetContents(ectx) |
||
3579 | return contents |
||
3580 | |||
3581 | def IsNegativ(self): |
||
3582 | def is_neg(sval): |
||
3583 | return isinstance(sval, str) and (sval[0] == '-') |
||
3584 | if self.type == 'SingleValue': |
||
3585 | return is_neg(self.subtype) |
||
3586 | elif self.type == 'ValueRange': |
||
3587 | if self.subtype[0] == 'MIN': return True |
||
3588 | return is_neg(self.subtype[0]) |
||
3589 | return False |
||
3590 | |||
3591 | def eth_constrname(self): |
||
3592 | def int2str(val): |
||
3593 | if isinstance(val, Value_Ref): |
||
3594 | return asn2c(val.val) |
||
3595 | try: |
||
3596 | if (int(val) < 0): |
||
3597 | return 'M' + str(-int(val)) |
||
3598 | else: |
||
3599 | return str(int(val)) |
||
3600 | except (ValueError, TypeError): |
||
3601 | return asn2c(str(val)) |
||
3602 | |||
3603 | ext = '' |
||
3604 | if hasattr(self, 'ext') and self.ext: |
||
3605 | ext = '_' |
||
3606 | if self.type == 'SingleValue': |
||
3607 | return int2str(self.subtype) + ext |
||
3608 | elif self.type == 'ValueRange': |
||
3609 | return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext |
||
3610 | elif self.type == 'Size': |
||
3611 | return 'SIZE_' + self.subtype.eth_constrname() + ext |
||
3612 | else: |
||
3613 | if (not hasattr(self, 'constr_num')): |
||
3614 | global constr_cnt |
||
3615 | constr_cnt += 1 |
||
3616 | self.constr_num = constr_cnt |
||
3617 | return 'CONSTR%03d%s' % (self.constr_num, ext) |
||
3618 | |||
3619 | def Needs64b(self, ectx): |
||
3620 | (minv, maxv, ext) = self.GetValue(ectx) |
||
3621 | if (str(minv).isdigit() or ((str(minv)[0] == "-") and str(minv)[1:].isdigit())) \ |
||
3622 | and str(maxv).isdigit() and (abs(int(maxv) - int(minv)) >= 2**32): |
||
3623 | return True |
||
3624 | return False |
||
3625 | |||
3626 | class Module (Node): |
||
3627 | def to_python (self, ctx): |
||
3628 | ctx.tag_def = self.tag_def.dfl_tag |
||
3629 | return """#%s |
||
3630 | %s""" % (self.ident, self.body.to_python (ctx)) |
||
3631 | |||
3632 | def get_name(self): |
||
3633 | return self.ident.val |
||
3634 | |||
3635 | def get_proto(self, ectx): |
||
3636 | if (ectx.proto): |
||
3637 | prot = ectx.proto |
||
3638 | else: |
||
3639 | prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name()) |
||
3640 | return prot |
||
3641 | |||
3642 | def to_eth(self, ectx): |
||
3643 | ectx.tags_def = 'EXPLICIT' # default = explicit |
||
3644 | ectx.proto = self.get_proto(ectx) |
||
3645 | ectx.tag_def = self.tag_def.dfl_tag |
||
3646 | ectx.eth_reg_module(self) |
||
3647 | self.body.to_eth(ectx) |
||
3648 | |||
3649 | class Module_Body (Node): |
||
3650 | def to_python (self, ctx): |
||
3651 | # XXX handle exports, imports. |
||
3652 | l = [x.to_python (ctx) for x in self.assign_list] |
||
3653 | l = [a for a in l if a != ''] |
||
3654 | return "\n".join (l) |
||
3655 | |||
3656 | def to_eth(self, ectx): |
||
3657 | # Exports |
||
3658 | ectx.eth_exports(self.exports) |
||
3659 | # Imports |
||
3660 | for i in self.imports: |
||
3661 | mod = i.module.val |
||
3662 | proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod) |
||
3663 | ectx.eth_module_dep_add(ectx.Module(), mod) |
||
3664 | for s in i.symbol_list: |
||
3665 | if isinstance(s, Type_Ref): |
||
3666 | ectx.eth_import_type(s.val, mod, proto) |
||
3667 | elif isinstance(s, Value_Ref): |
||
3668 | ectx.eth_import_value(s.val, mod, proto) |
||
3669 | elif isinstance(s, Class_Ref): |
||
3670 | ectx.eth_import_class(s.val, mod, proto) |
||
3671 | else: |
||
3672 | msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod) |
||
3673 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
3674 | # AssignmentList |
||
3675 | for a in self.assign_list: |
||
3676 | a.eth_reg('', ectx) |
||
3677 | |||
3678 | class Default_Tags (Node): |
||
3679 | def to_python (self, ctx): # not to be used directly |
||
3680 | assert (0) |
||
3681 | |||
3682 | # XXX should just calculate dependencies as we go along. |
||
3683 | def calc_dependencies (node, dict, trace = 0): |
||
3684 | if not hasattr (node, '__dict__'): |
||
3685 | if trace: print("#returning, node=", node) |
||
3686 | return |
||
3687 | if isinstance (node, Type_Ref): |
||
3688 | dict [node.val] = 1 |
||
3689 | if trace: print("#Setting", node.val) |
||
3690 | return |
||
3691 | for (a, val) in list(node.__dict__.items ()): |
||
3692 | if trace: print("# Testing node ", node, "attr", a, " val", val) |
||
3693 | if a[0] == '_': |
||
3694 | continue |
||
3695 | elif isinstance (val, Node): |
||
3696 | calc_dependencies (val, dict, trace) |
||
3697 | elif isinstance (val, type ([])): |
||
3698 | for v in val: |
||
3699 | calc_dependencies (v, dict, trace) |
||
3700 | |||
3701 | |||
3702 | class Type_Assign (Node): |
||
3703 | def __init__ (self, *args, **kw): |
||
3704 | Node.__init__ (self, *args, **kw) |
||
3705 | if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag) |
||
3706 | to_test = self.val.typ |
||
3707 | else: |
||
3708 | to_test = self.val |
||
3709 | if isinstance (to_test, SequenceType): |
||
3710 | to_test.sequence_name = self.name.name |
||
3711 | |||
3712 | def to_python (self, ctx): |
||
3713 | dep_dict = {} |
||
3714 | calc_dependencies (self.val, dep_dict, 0) |
||
3715 | depend_list = list(dep_dict.keys ()) |
||
3716 | return ctx.register_assignment (self.name.name, |
||
3717 | self.val.to_python (ctx), |
||
3718 | depend_list) |
||
3719 | |||
3720 | class PyQuote (Node): |
||
3721 | def to_python (self, ctx): |
||
3722 | return ctx.register_pyquote (self.val) |
||
3723 | |||
3724 | #--- Type_Ref ----------------------------------------------------------------- |
||
3725 | class Type_Ref (Type): |
||
3726 | def to_python (self, ctx): |
||
3727 | return self.val |
||
3728 | |||
3729 | def eth_reg_sub(self, ident, ectx): |
||
3730 | ectx.eth_dep_add(ident, self.val) |
||
3731 | |||
3732 | def eth_tname(self): |
||
3733 | if self.HasSizeConstraint(): |
||
3734 | return asn2c(self.val) + '_' + self.constr.eth_constrname() |
||
3735 | else: |
||
3736 | return asn2c(self.val) |
||
3737 | |||
3738 | def tr_need_own_fn(self, ectx): |
||
3739 | return ectx.Per() and self.HasSizeConstraint() |
||
3740 | |||
3741 | def fld_obj_repr(self, ectx): |
||
3742 | return self.val |
||
3743 | |||
3744 | def get_components(self, ectx): |
||
3745 | if self.val not in ectx.type or ectx.type[self.val]['import']: |
||
3746 | msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val) |
||
3747 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
3748 | return [] |
||
3749 | else: |
||
3750 | return ectx.type[self.val]['val'].get_components(ectx) |
||
3751 | |||
3752 | def GetTTag(self, ectx): |
||
3753 | #print "GetTTag(%s)\n" % self.val; |
||
3754 | if (ectx.type[self.val]['import']): |
||
3755 | if 'ttag' not in ectx.type[self.val]: |
||
3756 | ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import']) |
||
3757 | if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val): |
||
3758 | msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto']) |
||
3759 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
3760 | ttag = ('-1/*imported*/', '-1/*imported*/') |
||
3761 | ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag) |
||
3762 | return ectx.type[self.val]['ttag'] |
||
3763 | else: |
||
3764 | return ectx.type[self.val]['val'].GetTag(ectx) |
||
3765 | |||
3766 | def IndetermTag(self, ectx): |
||
3767 | if (ectx.type[self.val]['import']): |
||
3768 | return False |
||
3769 | else: |
||
3770 | return ectx.type[self.val]['val'].IndetermTag(ectx) |
||
3771 | |||
3772 | def eth_type_default_pars(self, ectx, tname): |
||
3773 | if tname: |
||
3774 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
3775 | else: |
||
3776 | pars = {} |
||
3777 | t = ectx.type[self.val]['ethname'] |
||
3778 | pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] |
||
3779 | pars['TYPE_REF_TNAME'] = t |
||
3780 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' |
||
3781 | if self.HasSizeConstraint(): |
||
3782 | (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) |
||
3783 | return pars |
||
3784 | |||
3785 | def eth_type_default_body(self, ectx, tname): |
||
3786 | if (ectx.Ber()): |
||
3787 | body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', |
||
3788 | par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) |
||
3789 | elif (ectx.Per()): |
||
3790 | if self.HasSizeConstraint(): |
||
3791 | body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset', |
||
3792 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',), |
||
3793 | ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) |
||
3794 | else: |
||
3795 | body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', |
||
3796 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) |
||
3797 | else: |
||
3798 | body = '#error Can not decode %s' % (tname) |
||
3799 | return body |
||
3800 | |||
3801 | #--- SelectionType ------------------------------------------------------------ |
||
3802 | class SelectionType (Type): |
||
3803 | def to_python (self, ctx): |
||
3804 | return self.val |
||
3805 | |||
3806 | def sel_of_typeref(self): |
||
3807 | return self.typ.type == 'Type_Ref' |
||
3808 | |||
3809 | def eth_reg_sub(self, ident, ectx): |
||
3810 | if not self.sel_of_typeref(): |
||
3811 | self.seltype = '' |
||
3812 | return |
||
3813 | self.seltype = ectx.eth_sel_req(self.typ.val, self.sel) |
||
3814 | ectx.eth_dep_add(ident, self.seltype) |
||
3815 | |||
3816 | def eth_ftype(self, ectx): |
||
3817 | (ftype, display) = ('FT_NONE', 'BASE_NONE') |
||
3818 | if self.sel_of_typeref() and not ectx.type[self.seltype]['import']: |
||
3819 | (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx) |
||
3820 | return (ftype, display) |
||
3821 | |||
3822 | def GetTTag(self, ectx): |
||
3823 | #print "GetTTag(%s)\n" % self.seltype; |
||
3824 | if (ectx.type[self.seltype]['import']): |
||
3825 | if 'ttag' not in ectx.type[self.seltype]: |
||
3826 | if not ectx.conform.check_item('IMPORT_TAG', self.seltype): |
||
3827 | msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto']) |
||
3828 | warnings.warn_explicit(msg, UserWarning, '', 0) |
||
3829 | ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/')) |
||
3830 | return ectx.type[self.seltype]['ttag'] |
||
3831 | else: |
||
3832 | return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx) |
||
3833 | |||
3834 | def eth_type_default_pars(self, ectx, tname): |
||
3835 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
3836 | if self.sel_of_typeref(): |
||
3837 | t = ectx.type[self.seltype]['ethname'] |
||
3838 | pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] |
||
3839 | pars['TYPE_REF_TNAME'] = t |
||
3840 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' |
||
3841 | return pars |
||
3842 | |||
3843 | def eth_type_default_body(self, ectx, tname): |
||
3844 | if not self.sel_of_typeref(): |
||
3845 | body = '#error Can not decode %s' % (tname) |
||
3846 | elif (ectx.Ber()): |
||
3847 | body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', |
||
3848 | par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) |
||
3849 | elif (ectx.Per()): |
||
3850 | body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', |
||
3851 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) |
||
3852 | else: |
||
3853 | body = '#error Can not decode %s' % (tname) |
||
3854 | return body |
||
3855 | |||
3856 | #--- TaggedType ----------------------------------------------------------------- |
||
3857 | class TaggedType (Type): |
||
3858 | def eth_tname(self): |
||
3859 | tn = '' |
||
3860 | for i in range(self.tstrip, len(self.val.tags)): |
||
3861 | tn += self.val.tags[i].eth_tname() |
||
3862 | tn += '_' |
||
3863 | tn += self.val.eth_tname() |
||
3864 | return tn |
||
3865 | |||
3866 | def eth_set_val_name(self, ident, val_name, ectx): |
||
3867 | #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name) |
||
3868 | self.val_name = val_name |
||
3869 | ectx.eth_dep_add(ident, self.val_name) |
||
3870 | |||
3871 | def eth_reg_sub(self, ident, ectx): |
||
3872 | self.val_name = ident + '/' + UNTAG_TYPE_NAME |
||
3873 | self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident) |
||
3874 | |||
3875 | def GetTTag(self, ectx): |
||
3876 | #print "GetTTag(%s)\n" % self.seltype; |
||
3877 | return self.GetTag(ectx) |
||
3878 | |||
3879 | def eth_ftype(self, ectx): |
||
3880 | return self.val.eth_ftype(ectx) |
||
3881 | |||
3882 | def eth_type_default_pars(self, ectx, tname): |
||
3883 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
3884 | t = ectx.type[self.val_name]['ethname'] |
||
3885 | pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] |
||
3886 | pars['TYPE_REF_TNAME'] = t |
||
3887 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' |
||
3888 | (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx) |
||
3889 | if self.HasImplicitTag(ectx): |
||
3890 | pars['TAG_IMPL'] = 'TRUE' |
||
3891 | else: |
||
3892 | pars['TAG_IMPL'] = 'FALSE' |
||
3893 | return pars |
||
3894 | |||
3895 | def eth_type_default_body(self, ectx, tname): |
||
3896 | if (ectx.Ber()): |
||
3897 | body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset', |
||
3898 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
3899 | ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),)) |
||
3900 | else: |
||
3901 | body = '#error Can not decode %s' % (tname) |
||
3902 | return body |
||
3903 | |||
3904 | #--- SqType ----------------------------------------------------------- |
||
3905 | class SqType (Type): |
||
3906 | def out_item(self, f, val, optional, ext, ectx): |
||
3907 | if (val.eth_omit_field()): |
||
3908 | t = ectx.type[val.ident]['ethname'] |
||
3909 | fullname = ectx.dummy_eag_field |
||
3910 | else: |
||
3911 | ef = ectx.field[f]['ethname'] |
||
3912 | t = ectx.eth_hf[ef]['ethtype'] |
||
3913 | fullname = ectx.eth_hf[ef]['fullname'] |
||
3914 | if (ectx.Ber()): |
||
3915 | #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx))) |
||
3916 | #print val.str_depth(1) |
||
3917 | opt = '' |
||
3918 | if (optional): |
||
3919 | opt = 'BER_FLAGS_OPTIONAL' |
||
3920 | if (not val.HasOwnTag()): |
||
3921 | if (opt): opt += '|' |
||
3922 | opt += 'BER_FLAGS_NOOWNTAG' |
||
3923 | elif (val.HasImplicitTag(ectx)): |
||
3924 | if (opt): opt += '|' |
||
3925 | opt += 'BER_FLAGS_IMPLTAG' |
||
3926 | if (val.IndetermTag(ectx)): |
||
3927 | if (opt): opt += '|' |
||
3928 | opt += 'BER_FLAGS_NOTCHKTAG' |
||
3929 | if (not opt): opt = '0' |
||
3930 | else: |
||
3931 | if optional: |
||
3932 | opt = 'ASN1_OPTIONAL' |
||
3933 | else: |
||
3934 | opt = 'ASN1_NOT_OPTIONAL' |
||
3935 | if (ectx.Ber()): |
||
3936 | (tc, tn) = val.GetTag(ectx) |
||
3937 | out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \ |
||
3938 | % ('&'+fullname, tc, tn, opt, ectx.eth_type[t]['proto'], t) |
||
3939 | elif (ectx.Per()): |
||
3940 | out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \ |
||
3941 | % ('&'+fullname, ext, opt, ectx.eth_type[t]['proto'], t) |
||
3942 | else: |
||
3943 | out = '' |
||
3944 | return out |
||
3945 | |||
3946 | #--- SeqType ----------------------------------------------------------- |
||
3947 | class SeqType (SqType): |
||
3948 | |||
3949 | def all_components(self): |
||
3950 | lst = self.elt_list[:] |
||
3951 | if hasattr(self, 'ext_list'): |
||
3952 | lst.extend(self.ext_list) |
||
3953 | if hasattr(self, 'elt_list2'): |
||
3954 | lst.extend(self.elt_list2) |
||
3955 | return lst |
||
3956 | |||
3957 | def need_components(self): |
||
3958 | lst = self.all_components() |
||
3959 | for e in (lst): |
||
3960 | if e.type == 'components_of': |
||
3961 | return True |
||
3962 | return False |
||
3963 | |||
3964 | def expand_components(self, ectx): |
||
3965 | while self.need_components(): |
||
3966 | for i in range(len(self.elt_list)): |
||
3967 | if self.elt_list[i].type == 'components_of': |
||
3968 | comp = self.elt_list[i].typ.get_components(ectx) |
||
3969 | self.elt_list[i:i+1] = comp |
||
3970 | break |
||
3971 | if hasattr(self, 'ext_list'): |
||
3972 | for i in range(len(self.ext_list)): |
||
3973 | if self.ext_list[i].type == 'components_of': |
||
3974 | comp = self.ext_list[i].typ.get_components(ectx) |
||
3975 | self.ext_list[i:i+1] = comp |
||
3976 | break |
||
3977 | if hasattr(self, 'elt_list2'): |
||
3978 | for i in range(len(self.elt_list2)): |
||
3979 | if self.elt_list2[i].type == 'components_of': |
||
3980 | comp = self.elt_list2[i].typ.get_components(ectx) |
||
3981 | self.elt_list2[i:i+1] = comp |
||
3982 | break |
||
3983 | |||
3984 | def get_components(self, ectx): |
||
3985 | lst = self.elt_list[:] |
||
3986 | if hasattr(self, 'elt_list2'): |
||
3987 | lst.extend(self.elt_list2) |
||
3988 | return lst |
||
3989 | |||
3990 | def eth_reg_sub(self, ident, ectx, components_available=False): |
||
3991 | # check if autotag is required |
||
3992 | autotag = False |
||
3993 | if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')): |
||
3994 | autotag = True |
||
3995 | lst = self.all_components() |
||
3996 | for e in (self.elt_list): |
||
3997 | if e.val.HasOwnTag(): autotag = False; break; |
||
3998 | # expand COMPONENTS OF |
||
3999 | if self.need_components(): |
||
4000 | if components_available: |
||
4001 | self.expand_components(ectx) |
||
4002 | else: |
||
4003 | ectx.eth_comp_req(ident) |
||
4004 | return |
||
4005 | # extension addition groups |
||
4006 | if hasattr(self, 'ext_list'): |
||
4007 | if (ectx.Per()): # add names |
||
4008 | eag_num = 1 |
||
4009 | for e in (self.ext_list): |
||
4010 | if isinstance(e.val, ExtensionAdditionGroup): |
||
4011 | e.val.parent_ident = ident |
||
4012 | e.val.parent_tname = ectx.type[ident]['tname'] |
||
4013 | if (e.val.ver): |
||
4014 | e.val.SetName("eag_v%s" % (e.val.ver)) |
||
4015 | else: |
||
4016 | e.val.SetName("eag_%d" % (eag_num)) |
||
4017 | eag_num += 1; |
||
4018 | else: # expand |
||
4019 | new_ext_list = [] |
||
4020 | for e in (self.ext_list): |
||
4021 | if isinstance(e.val, ExtensionAdditionGroup): |
||
4022 | new_ext_list.extend(e.val.elt_list) |
||
4023 | else: |
||
4024 | new_ext_list.append(e) |
||
4025 | self.ext_list = new_ext_list |
||
4026 | # do autotag |
||
4027 | if autotag: |
||
4028 | atag = 0 |
||
4029 | for e in (self.elt_list): |
||
4030 | e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) |
||
4031 | atag += 1 |
||
4032 | if autotag and hasattr(self, 'elt_list2'): |
||
4033 | for e in (self.elt_list2): |
||
4034 | e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) |
||
4035 | atag += 1 |
||
4036 | if autotag and hasattr(self, 'ext_list'): |
||
4037 | for e in (self.ext_list): |
||
4038 | e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) |
||
4039 | atag += 1 |
||
4040 | # register components |
||
4041 | for e in (self.elt_list): |
||
4042 | e.val.eth_reg(ident, ectx, tstrip=1, parent=ident) |
||
4043 | if hasattr(self, 'ext_list'): |
||
4044 | for e in (self.ext_list): |
||
4045 | e.val.eth_reg(ident, ectx, tstrip=1, parent=ident) |
||
4046 | if hasattr(self, 'elt_list2'): |
||
4047 | for e in (self.elt_list2): |
||
4048 | e.val.eth_reg(ident, ectx, tstrip=1, parent=ident) |
||
4049 | |||
4050 | def eth_type_default_table(self, ectx, tname): |
||
4051 | #print "eth_type_default_table(tname='%s')" % (tname) |
||
4052 | fname = ectx.eth_type[tname]['ref'][0] |
||
4053 | table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n" |
||
4054 | if hasattr(self, 'ext_list'): |
||
4055 | ext = 'ASN1_EXTENSION_ROOT' |
||
4056 | else: |
||
4057 | ext = 'ASN1_NO_EXTENSIONS' |
||
4058 | empty_ext_flag = '0' |
||
4059 | if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0) and (not hasattr(self, 'elt_list2') or (len(self.elt_list2)==0)): |
||
4060 | empty_ext_flag = ext |
||
4061 | for e in (self.elt_list): |
||
4062 | f = fname + '/' + e.val.name |
||
4063 | table += self.out_item(f, e.val, e.optional, ext, ectx) |
||
4064 | if hasattr(self, 'ext_list'): |
||
4065 | for e in (self.ext_list): |
||
4066 | f = fname + '/' + e.val.name |
||
4067 | table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx) |
||
4068 | if hasattr(self, 'elt_list2'): |
||
4069 | for e in (self.elt_list2): |
||
4070 | f = fname + '/' + e.val.name |
||
4071 | table += self.out_item(f, e.val, e.optional, ext, ectx) |
||
4072 | if (ectx.Ber()): |
||
4073 | table += " { NULL, 0, 0, 0, NULL }\n};\n" |
||
4074 | else: |
||
4075 | table += " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag) |
||
4076 | return table |
||
4077 | |||
4078 | #--- SeqOfType ----------------------------------------------------------- |
||
4079 | class SeqOfType (SqType): |
||
4080 | def eth_type_default_table(self, ectx, tname): |
||
4081 | #print "eth_type_default_table(tname='%s')" % (tname) |
||
4082 | fname = ectx.eth_type[tname]['ref'][0] |
||
4083 | if self.val.IsNamed (): |
||
4084 | f = fname + '/' + self.val.name |
||
4085 | else: |
||
4086 | f = fname + '/' + ITEM_FIELD_NAME |
||
4087 | table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n" |
||
4088 | table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx) |
||
4089 | table += "};\n" |
||
4090 | return table |
||
4091 | |||
4092 | #--- SequenceOfType ----------------------------------------------------------- |
||
4093 | class SequenceOfType (SeqOfType): |
||
4094 | def to_python (self, ctx): |
||
4095 | # name, tag (None for no tag, EXPLICIT() for explicit), typ) |
||
4096 | # or '' + (1,) for optional |
||
4097 | sizestr = '' |
||
4098 | if self.size_constr != None: |
||
4099 | print("#Ignoring size constraint:", self.size_constr.subtype) |
||
4100 | return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (), |
||
4101 | self.val.to_python (ctx), |
||
4102 | sizestr) |
||
4103 | |||
4104 | def eth_reg_sub(self, ident, ectx): |
||
4105 | itmnm = ident |
||
4106 | if not self.val.IsNamed (): |
||
4107 | itmnm += '/' + ITEM_FIELD_NAME |
||
4108 | self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident) |
||
4109 | |||
4110 | def eth_tname(self): |
||
4111 | if self.val.type != 'Type_Ref': |
||
4112 | return '#' + self.type + '_' + str(id(self)) |
||
4113 | if not self.HasConstraint(): |
||
4114 | return "SEQUENCE_OF_" + self.val.eth_tname() |
||
4115 | elif self.constr.IsSize(): |
||
4116 | return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname() |
||
4117 | else: |
||
4118 | return '#' + self.type + '_' + str(id(self)) |
||
4119 | |||
4120 | def eth_ftype(self, ectx): |
||
4121 | return ('FT_UINT32', 'BASE_DEC') |
||
4122 | |||
4123 | def eth_need_tree(self): |
||
4124 | return True |
||
4125 | |||
4126 | def GetTTag(self, ectx): |
||
4127 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE') |
||
4128 | |||
4129 | def eth_type_default_pars(self, ectx, tname): |
||
4130 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4131 | (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) |
||
4132 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of' |
||
4133 | return pars |
||
4134 | |||
4135 | def eth_type_default_body(self, ectx, tname): |
||
4136 | if (ectx.Ber()): |
||
4137 | if (ectx.constraints_check and self.HasSizeConstraint()): |
||
4138 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset', |
||
4139 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4140 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) |
||
4141 | else: |
||
4142 | body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset', |
||
4143 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4144 | ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) |
||
4145 | elif (ectx.Per() and not self.HasConstraint()): |
||
4146 | body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset', |
||
4147 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4148 | ('%(ETT_INDEX)s', '%(TABLE)s',),)) |
||
4149 | elif (ectx.Per() and self.constr.type == 'Size'): |
||
4150 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset', |
||
4151 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4152 | ('%(ETT_INDEX)s', '%(TABLE)s',), |
||
4153 | ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),)) |
||
4154 | else: |
||
4155 | body = '#error Can not decode %s' % (tname) |
||
4156 | return body |
||
4157 | |||
4158 | |||
4159 | #--- SetOfType ---------------------------------------------------------------- |
||
4160 | class SetOfType (SeqOfType): |
||
4161 | def eth_reg_sub(self, ident, ectx): |
||
4162 | itmnm = ident |
||
4163 | if not self.val.IsNamed (): |
||
4164 | itmnm += '/' + ITEM_FIELD_NAME |
||
4165 | self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident) |
||
4166 | |||
4167 | def eth_tname(self): |
||
4168 | if self.val.type != 'Type_Ref': |
||
4169 | return '#' + self.type + '_' + str(id(self)) |
||
4170 | if not self.HasConstraint(): |
||
4171 | return "SET_OF_" + self.val.eth_tname() |
||
4172 | elif self.constr.IsSize(): |
||
4173 | return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname() |
||
4174 | else: |
||
4175 | return '#' + self.type + '_' + str(id(self)) |
||
4176 | |||
4177 | def eth_ftype(self, ectx): |
||
4178 | return ('FT_UINT32', 'BASE_DEC') |
||
4179 | |||
4180 | def eth_need_tree(self): |
||
4181 | return True |
||
4182 | |||
4183 | def GetTTag(self, ectx): |
||
4184 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET') |
||
4185 | |||
4186 | def eth_type_default_pars(self, ectx, tname): |
||
4187 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4188 | (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) |
||
4189 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of' |
||
4190 | return pars |
||
4191 | |||
4192 | def eth_type_default_body(self, ectx, tname): |
||
4193 | if (ectx.Ber()): |
||
4194 | if (ectx.constraints_check and self.HasSizeConstraint()): |
||
4195 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset', |
||
4196 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4197 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) |
||
4198 | else: |
||
4199 | body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset', |
||
4200 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4201 | ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) |
||
4202 | elif (ectx.Per() and not self.HasConstraint()): |
||
4203 | body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset', |
||
4204 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4205 | ('%(ETT_INDEX)s', '%(TABLE)s',),)) |
||
4206 | elif (ectx.Per() and self.constr.type == 'Size'): |
||
4207 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset', |
||
4208 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4209 | ('%(ETT_INDEX)s', '%(TABLE)s',), |
||
4210 | ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),)) |
||
4211 | else: |
||
4212 | body = '#error Can not decode %s' % (tname) |
||
4213 | return body |
||
4214 | |||
4215 | def mk_tag_str (ctx, cls, typ, num): |
||
4216 | |||
4217 | # XXX should do conversion to int earlier! |
||
4218 | val = int (num) |
||
4219 | typ = typ.upper() |
||
4220 | if typ == 'DEFAULT': |
||
4221 | typ = ctx.tags_def |
||
4222 | return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned |
||
4223 | |||
4224 | #--- SequenceType ------------------------------------------------------------- |
||
4225 | class SequenceType (SeqType): |
||
4226 | def to_python (self, ctx): |
||
4227 | # name, tag (None for no tag, EXPLICIT() for explicit), typ) |
||
4228 | # or '' + (1,) for optional |
||
4229 | # XXX should also collect names for SEQUENCE inside SEQUENCE or |
||
4230 | # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come |
||
4231 | # from? for others, element or arm name would be fine) |
||
4232 | seq_name = getattr (self, 'sequence_name', None) |
||
4233 | if seq_name == None: |
||
4234 | seq_name = 'None' |
||
4235 | else: |
||
4236 | seq_name = "'" + seq_name + "'" |
||
4237 | if 'ext_list' in self.__dict__: |
||
4238 | return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (), |
||
4239 | self.elts_to_py (self.elt_list, ctx), |
||
4240 | self.elts_to_py (self.ext_list, ctx), seq_name) |
||
4241 | else: |
||
4242 | return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (), |
||
4243 | self.elts_to_py (self.elt_list, ctx), seq_name) |
||
4244 | def elts_to_py (self, list, ctx): |
||
4245 | # we have elt_type, val= named_type, maybe default=, optional= |
||
4246 | # named_type node: either ident = or typ = |
||
4247 | # need to dismember these in order to generate Python output syntax. |
||
4248 | ctx.indent () |
||
4249 | def elt_to_py (e): |
||
4250 | assert (e.type == 'elt_type') |
||
4251 | nt = e.val |
||
4252 | optflag = e.optional |
||
4253 | #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT! |
||
4254 | assert (nt.type == 'named_type') |
||
4255 | tagstr = 'None' |
||
4256 | identstr = nt.ident |
||
4257 | if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh |
||
4258 | tagstr = mk_tag_str (ctx,nt.typ.tag.cls, |
||
4259 | nt.typ.tag.tag_typ,nt.typ.tag.num) |
||
4260 | |||
4261 | |||
4262 | nt = nt.typ |
||
4263 | return "('%s',%s,%s,%d)" % (identstr, tagstr, |
||
4264 | nt.typ.to_python (ctx), optflag) |
||
4265 | indentstr = ",\n" + ctx.spaces () |
||
4266 | rv = indentstr.join ([elt_to_py (e) for e in list]) |
||
4267 | ctx.outdent () |
||
4268 | return rv |
||
4269 | |||
4270 | def eth_need_tree(self): |
||
4271 | return True |
||
4272 | |||
4273 | def GetTTag(self, ectx): |
||
4274 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE') |
||
4275 | |||
4276 | def eth_type_default_pars(self, ectx, tname): |
||
4277 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4278 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence' |
||
4279 | return pars |
||
4280 | |||
4281 | def eth_type_default_body(self, ectx, tname): |
||
4282 | if (ectx.Ber()): |
||
4283 | body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset', |
||
4284 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4285 | ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) |
||
4286 | elif (ectx.Per()): |
||
4287 | body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset', |
||
4288 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4289 | ('%(ETT_INDEX)s', '%(TABLE)s',),)) |
||
4290 | else: |
||
4291 | body = '#error Can not decode %s' % (tname) |
||
4292 | return body |
||
4293 | |||
4294 | #--- ExtensionAdditionGroup --------------------------------------------------- |
||
4295 | class ExtensionAdditionGroup (SeqType): |
||
4296 | def __init__(self,*args, **kw) : |
||
4297 | self.parent_ident = None |
||
4298 | self.parent_tname = None |
||
4299 | SeqType.__init__ (self,*args, **kw) |
||
4300 | |||
4301 | def eth_omit_field(self): |
||
4302 | return True |
||
4303 | |||
4304 | def eth_tname(self): |
||
4305 | if (self.parent_tname and self.IsNamed()): |
||
4306 | return self.parent_tname + "_" + self.name |
||
4307 | else: |
||
4308 | return SeqType.eth_tname(self) |
||
4309 | |||
4310 | def eth_reg_sub(self, ident, ectx): |
||
4311 | ectx.eth_dummy_eag_field_required() |
||
4312 | ectx.eth_dep_add(self.parent_ident, ident) |
||
4313 | SeqType.eth_reg_sub(self, ident, ectx) |
||
4314 | |||
4315 | def eth_type_default_pars(self, ectx, tname): |
||
4316 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4317 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence' |
||
4318 | return pars |
||
4319 | |||
4320 | def eth_type_default_body(self, ectx, tname): |
||
4321 | if (ectx.Per()): |
||
4322 | body = ectx.eth_fn_call('dissect_%(ER)s_sequence_eag', ret='offset', |
||
4323 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),)) |
||
4324 | else: |
||
4325 | body = '#error Can not decode %s' % (tname) |
||
4326 | return body |
||
4327 | |||
4328 | |||
4329 | #--- SetType ------------------------------------------------------------------ |
||
4330 | class SetType (SeqType): |
||
4331 | |||
4332 | def eth_need_tree(self): |
||
4333 | return True |
||
4334 | |||
4335 | def GetTTag(self, ectx): |
||
4336 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET') |
||
4337 | |||
4338 | def eth_type_default_pars(self, ectx, tname): |
||
4339 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4340 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set' |
||
4341 | return pars |
||
4342 | |||
4343 | def eth_type_default_body(self, ectx, tname): |
||
4344 | if (ectx.Ber()): |
||
4345 | body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset', |
||
4346 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4347 | ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) |
||
4348 | elif (ectx.Per()): |
||
4349 | body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset', |
||
4350 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4351 | ('%(ETT_INDEX)s', '%(TABLE)s',),)) |
||
4352 | else: |
||
4353 | body = '#error Can not decode %s' % (tname) |
||
4354 | return body |
||
4355 | |||
4356 | #--- ChoiceType --------------------------------------------------------------- |
||
4357 | class ChoiceType (Type): |
||
4358 | def to_python (self, ctx): |
||
4359 | # name, tag (None for no tag, EXPLICIT() for explicit), typ) |
||
4360 | # or '' + (1,) for optional |
||
4361 | if 'ext_list' in self.__dict__: |
||
4362 | return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (), |
||
4363 | self.elts_to_py (self.elt_list, ctx), |
||
4364 | self.elts_to_py (self.ext_list, ctx)) |
||
4365 | else: |
||
4366 | return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx)) |
||
4367 | def elts_to_py (self, list, ctx): |
||
4368 | ctx.indent () |
||
4369 | def elt_to_py (nt): |
||
4370 | assert (nt.type == 'named_type') |
||
4371 | tagstr = 'None' |
||
4372 | if hasattr (nt, 'ident'): |
||
4373 | identstr = nt.ident |
||
4374 | else: |
||
4375 | if hasattr (nt.typ, 'val'): |
||
4376 | identstr = nt.typ.val # XXX, making up name |
||
4377 | elif hasattr (nt.typ, 'name'): |
||
4378 | identstr = nt.typ.name |
||
4379 | else: |
||
4380 | identstr = ctx.make_new_name () |
||
4381 | |||
4382 | if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh |
||
4383 | tagstr = mk_tag_str (ctx,nt.typ.tag.cls, |
||
4384 | nt.typ.tag.tag_typ,nt.typ.tag.num) |
||
4385 | |||
4386 | |||
4387 | nt = nt.typ |
||
4388 | return "('%s',%s,%s)" % (identstr, tagstr, |
||
4389 | nt.typ.to_python (ctx)) |
||
4390 | indentstr = ",\n" + ctx.spaces () |
||
4391 | rv = indentstr.join ([elt_to_py (e) for e in list]) |
||
4392 | ctx.outdent () |
||
4393 | return rv |
||
4394 | |||
4395 | def eth_reg_sub(self, ident, ectx): |
||
4396 | #print "eth_reg_sub(ident='%s')" % (ident) |
||
4397 | # check if autotag is required |
||
4398 | autotag = False |
||
4399 | if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')): |
||
4400 | autotag = True |
||
4401 | for e in (self.elt_list): |
||
4402 | if e.HasOwnTag(): autotag = False; break; |
||
4403 | if autotag and hasattr(self, 'ext_list'): |
||
4404 | for e in (self.ext_list): |
||
4405 | if e.HasOwnTag(): autotag = False; break; |
||
4406 | # do autotag |
||
4407 | if autotag: |
||
4408 | atag = 0 |
||
4409 | for e in (self.elt_list): |
||
4410 | e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) |
||
4411 | atag += 1 |
||
4412 | if autotag and hasattr(self, 'ext_list'): |
||
4413 | for e in (self.ext_list): |
||
4414 | e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) |
||
4415 | atag += 1 |
||
4416 | for e in (self.elt_list): |
||
4417 | e.eth_reg(ident, ectx, tstrip=1, parent=ident) |
||
4418 | if ectx.conform.check_item('EXPORTS', ident + '.' + e.name): |
||
4419 | ectx.eth_sel_req(ident, e.name) |
||
4420 | if hasattr(self, 'ext_list'): |
||
4421 | for e in (self.ext_list): |
||
4422 | e.eth_reg(ident, ectx, tstrip=1, parent=ident) |
||
4423 | if ectx.conform.check_item('EXPORTS', ident + '.' + e.name): |
||
4424 | ectx.eth_sel_req(ident, e.name) |
||
4425 | |||
4426 | def sel_item(self, ident, sel, ectx): |
||
4427 | lst = self.elt_list[:] |
||
4428 | if hasattr(self, 'ext_list'): |
||
4429 | lst.extend(self.ext_list) |
||
4430 | ee = None |
||
4431 | for e in (self.elt_list): |
||
4432 | if e.IsNamed() and (e.name == sel): |
||
4433 | ee = e |
||
4434 | break |
||
4435 | if not ee: |
||
4436 | print("#CHOICE %s does not contain item %s" % (ident, sel)) |
||
4437 | return ee |
||
4438 | |||
4439 | def sel_req(self, ident, sel, ectx): |
||
4440 | #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self)) |
||
4441 | ee = self.sel_item(ident, sel, ectx) |
||
4442 | if ee: |
||
4443 | ee.eth_reg(ident, ectx, tstrip=0, selflag=True) |
||
4444 | |||
4445 | def eth_ftype(self, ectx): |
||
4446 | return ('FT_UINT32', 'BASE_DEC') |
||
4447 | |||
4448 | def eth_ftype_sel(self, sel, ectx): |
||
4449 | ee = self.sel_item('', sel, ectx) |
||
4450 | if ee: |
||
4451 | return ee.eth_ftype(ectx) |
||
4452 | else: |
||
4453 | return ('FT_NONE', 'BASE_NONE') |
||
4454 | |||
4455 | def eth_strings(self): |
||
4456 | return '$$' |
||
4457 | |||
4458 | def eth_need_tree(self): |
||
4459 | return True |
||
4460 | |||
4461 | def eth_has_vals(self): |
||
4462 | return True |
||
4463 | |||
4464 | def GetTTag(self, ectx): |
||
4465 | lst = self.elt_list |
||
4466 | cls = 'BER_CLASS_ANY/*choice*/' |
||
4467 | #if hasattr(self, 'ext_list'): |
||
4468 | # lst.extend(self.ext_list) |
||
4469 | #if (len(lst) > 0): |
||
4470 | # cls = lst[0].GetTag(ectx)[0] |
||
4471 | #for e in (lst): |
||
4472 | # if (e.GetTag(ectx)[0] != cls): |
||
4473 | # cls = '-1/*choice*/' |
||
4474 | return (cls, '-1/*choice*/') |
||
4475 | |||
4476 | def GetTTagSel(self, sel, ectx): |
||
4477 | ee = self.sel_item('', sel, ectx) |
||
4478 | if ee: |
||
4479 | return ee.GetTag(ectx) |
||
4480 | else: |
||
4481 | return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/') |
||
4482 | |||
4483 | def IndetermTag(self, ectx): |
||
4484 | #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag())) |
||
4485 | return not self.HasOwnTag() |
||
4486 | |||
4487 | def detect_tagval(self, ectx): |
||
4488 | tagval = False |
||
4489 | lst = self.elt_list[:] |
||
4490 | if hasattr(self, 'ext_list'): |
||
4491 | lst.extend(self.ext_list) |
||
4492 | if (len(lst) > 0) and (not ectx.Per() or lst[0].HasOwnTag()): |
||
4493 | t = lst[0].GetTag(ectx)[0] |
||
4494 | tagval = True |
||
4495 | else: |
||
4496 | t = '' |
||
4497 | tagval = False |
||
4498 | if (t == 'BER_CLASS_UNI'): |
||
4499 | tagval = False |
||
4500 | for e in (lst): |
||
4501 | if not ectx.Per() or e.HasOwnTag(): |
||
4502 | tt = e.GetTag(ectx)[0] |
||
4503 | else: |
||
4504 | tt = '' |
||
4505 | tagval = False |
||
4506 | if (tt != t): |
||
4507 | tagval = False |
||
4508 | return tagval |
||
4509 | |||
4510 | def get_vals(self, ectx): |
||
4511 | tagval = self.detect_tagval(ectx) |
||
4512 | vals = [] |
||
4513 | cnt = 0 |
||
4514 | for e in (self.elt_list): |
||
4515 | if (tagval): val = e.GetTag(ectx)[1] |
||
4516 | else: val = str(cnt) |
||
4517 | vals.append((val, e.name)) |
||
4518 | cnt += 1 |
||
4519 | if hasattr(self, 'ext_list'): |
||
4520 | for e in (self.ext_list): |
||
4521 | if (tagval): val = e.GetTag(ectx)[1] |
||
4522 | else: val = str(cnt) |
||
4523 | vals.append((val, e.name)) |
||
4524 | cnt += 1 |
||
4525 | return vals |
||
4526 | |||
4527 | def eth_type_vals(self, tname, ectx): |
||
4528 | out = '\n' |
||
4529 | vals = self.get_vals(ectx) |
||
4530 | out += ectx.eth_vals(tname, vals) |
||
4531 | return out |
||
4532 | |||
4533 | def reg_enum_vals(self, tname, ectx): |
||
4534 | vals = self.get_vals(ectx) |
||
4535 | for (val, id) in vals: |
||
4536 | ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id)) |
||
4537 | |||
4538 | def eth_type_enum(self, tname, ectx): |
||
4539 | out = '\n' |
||
4540 | vals = self.get_vals(ectx) |
||
4541 | out += ectx.eth_enum(tname, vals) |
||
4542 | return out |
||
4543 | |||
4544 | def eth_type_default_pars(self, ectx, tname): |
||
4545 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4546 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice' |
||
4547 | return pars |
||
4548 | |||
4549 | def eth_type_default_table(self, ectx, tname): |
||
4550 | def out_item(val, e, ext, ectx): |
||
4551 | has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM |
||
4552 | if (has_enum): |
||
4553 | vval = ectx.eth_enum_item(tname, e.name) |
||
4554 | else: |
||
4555 | vval = val |
||
4556 | f = fname + '/' + e.name |
||
4557 | ef = ectx.field[f]['ethname'] |
||
4558 | t = ectx.eth_hf[ef]['ethtype'] |
||
4559 | if (ectx.Ber()): |
||
4560 | opt = '' |
||
4561 | if (not e.HasOwnTag()): |
||
4562 | opt = 'BER_FLAGS_NOOWNTAG' |
||
4563 | elif (e.HasImplicitTag(ectx)): |
||
4564 | if (opt): opt += '|' |
||
4565 | opt += 'BER_FLAGS_IMPLTAG' |
||
4566 | if (not opt): opt = '0' |
||
4567 | if (ectx.Ber()): |
||
4568 | (tc, tn) = e.GetTag(ectx) |
||
4569 | out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \ |
||
4570 | % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t) |
||
4571 | elif (ectx.Per()): |
||
4572 | out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \ |
||
4573 | % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t) |
||
4574 | else: |
||
4575 | out = '' |
||
4576 | return out |
||
4577 | # end out_item() |
||
4578 | #print "eth_type_default_table(tname='%s')" % (tname) |
||
4579 | fname = ectx.eth_type[tname]['ref'][0] |
||
4580 | tagval = self.detect_tagval(ectx) |
||
4581 | table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n" |
||
4582 | cnt = 0 |
||
4583 | if hasattr(self, 'ext_list'): |
||
4584 | ext = 'ASN1_EXTENSION_ROOT' |
||
4585 | else: |
||
4586 | ext = 'ASN1_NO_EXTENSIONS' |
||
4587 | empty_ext_flag = '0' |
||
4588 | if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0): |
||
4589 | empty_ext_flag = ext |
||
4590 | for e in (self.elt_list): |
||
4591 | if (tagval): val = e.GetTag(ectx)[1] |
||
4592 | else: val = str(cnt) |
||
4593 | table += out_item(val, e, ext, ectx) |
||
4594 | cnt += 1 |
||
4595 | if hasattr(self, 'ext_list'): |
||
4596 | for e in (self.ext_list): |
||
4597 | if (tagval): val = e.GetTag(ectx)[1] |
||
4598 | else: val = str(cnt) |
||
4599 | table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx) |
||
4600 | cnt += 1 |
||
4601 | if (ectx.Ber()): |
||
4602 | table += " { 0, NULL, 0, 0, 0, NULL }\n};\n" |
||
4603 | else: |
||
4604 | table += " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag) |
||
4605 | return table |
||
4606 | |||
4607 | def eth_type_default_body(self, ectx, tname): |
||
4608 | if (ectx.Ber()): |
||
4609 | body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset', |
||
4610 | par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4611 | ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'), |
||
4612 | ('%(VAL_PTR)s',),)) |
||
4613 | elif (ectx.Per()): |
||
4614 | body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset', |
||
4615 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4616 | ('%(ETT_INDEX)s', '%(TABLE)s',), |
||
4617 | ('%(VAL_PTR)s',),)) |
||
4618 | else: |
||
4619 | body = '#error Can not decode %s' % (tname) |
||
4620 | return body |
||
4621 | |||
4622 | #--- ChoiceValue ---------------------------------------------------- |
||
4623 | class ChoiceValue (Value): |
||
4624 | def to_str(self, ectx): |
||
4625 | return self.val.to_str(ectx) |
||
4626 | |||
4627 | def fld_obj_eq(self, other): |
||
4628 | return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val)) |
||
4629 | |||
4630 | #--- EnumeratedType ----------------------------------------------------------- |
||
4631 | class EnumeratedType (Type): |
||
4632 | def to_python (self, ctx): |
||
4633 | def strify_one (named_num): |
||
4634 | return "%s=%s" % (named_num.ident, named_num.val) |
||
4635 | return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val)) |
||
4636 | |||
4637 | def eth_ftype(self, ectx): |
||
4638 | return ('FT_UINT32', 'BASE_DEC') |
||
4639 | |||
4640 | def eth_strings(self): |
||
4641 | return '$$' |
||
4642 | |||
4643 | def eth_has_vals(self): |
||
4644 | return True |
||
4645 | |||
4646 | def GetTTag(self, ectx): |
||
4647 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED') |
||
4648 | |||
4649 | def get_vals_etc(self, ectx): |
||
4650 | vals = [] |
||
4651 | lastv = 0 |
||
4652 | used = {} |
||
4653 | maxv = 0 |
||
4654 | root_num = 0 |
||
4655 | ext_num = 0 |
||
4656 | map_table = [] |
||
4657 | for e in (self.val): |
||
4658 | if e.type == 'NamedNumber': |
||
4659 | used[int(e.val)] = True |
||
4660 | for e in (self.val): |
||
4661 | if e.type == 'NamedNumber': |
||
4662 | val = int(e.val) |
||
4663 | else: |
||
4664 | while lastv in used: |
||
4665 | lastv += 1 |
||
4666 | val = lastv |
||
4667 | used[val] = True |
||
4668 | vals.append((val, e.ident)) |
||
4669 | map_table.append(val) |
||
4670 | root_num += 1 |
||
4671 | if val > maxv: |
||
4672 | maxv = val |
||
4673 | if self.ext is not None: |
||
4674 | for e in (self.ext): |
||
4675 | if e.type == 'NamedNumber': |
||
4676 | used[int(e.val)] = True |
||
4677 | for e in (self.ext): |
||
4678 | if e.type == 'NamedNumber': |
||
4679 | val = int(e.val) |
||
4680 | else: |
||
4681 | while lastv in used: |
||
4682 | lastv += 1 |
||
4683 | val = lastv |
||
4684 | used[val] = True |
||
4685 | vals.append((val, e.ident)) |
||
4686 | map_table.append(val) |
||
4687 | ext_num += 1 |
||
4688 | if val > maxv: |
||
4689 | maxv = val |
||
4690 | need_map = False |
||
4691 | for i in range(len(map_table)): |
||
4692 | need_map = need_map or (map_table[i] != i) |
||
4693 | if (not need_map): |
||
4694 | map_table = None |
||
4695 | return (vals, root_num, ext_num, map_table) |
||
4696 | |||
4697 | def eth_type_vals(self, tname, ectx): |
||
4698 | out = '\n' |
||
4699 | vals = self.get_vals_etc(ectx)[0] |
||
4700 | out += ectx.eth_vals(tname, vals) |
||
4701 | return out |
||
4702 | |||
4703 | def reg_enum_vals(self, tname, ectx): |
||
4704 | vals = self.get_vals_etc(ectx)[0] |
||
4705 | for (val, id) in vals: |
||
4706 | ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id)) |
||
4707 | |||
4708 | def eth_type_enum(self, tname, ectx): |
||
4709 | out = '\n' |
||
4710 | vals = self.get_vals_etc(ectx)[0] |
||
4711 | out += ectx.eth_enum(tname, vals) |
||
4712 | return out |
||
4713 | |||
4714 | def eth_type_default_pars(self, ectx, tname): |
||
4715 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4716 | (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:] |
||
4717 | if (self.ext != None): |
||
4718 | ext = 'TRUE' |
||
4719 | else: |
||
4720 | ext = 'FALSE' |
||
4721 | pars['ROOT_NUM'] = str(root_num) |
||
4722 | pars['EXT'] = ext |
||
4723 | pars['EXT_NUM'] = str(ext_num) |
||
4724 | if (map_table): |
||
4725 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map' |
||
4726 | else: |
||
4727 | pars['TABLE'] = 'NULL' |
||
4728 | return pars |
||
4729 | |||
4730 | def eth_type_default_table(self, ectx, tname): |
||
4731 | if (not ectx.Per()): return '' |
||
4732 | map_table = self.get_vals_etc(ectx)[3] |
||
4733 | if (map_table == None): return '' |
||
4734 | table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {" |
||
4735 | table += ", ".join([str(v) for v in map_table]) |
||
4736 | table += "};\n" |
||
4737 | return table |
||
4738 | |||
4739 | def eth_type_default_body(self, ectx, tname): |
||
4740 | if (ectx.Ber()): |
||
4741 | if (ectx.constraints_check and self.HasValueConstraint()): |
||
4742 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset', |
||
4743 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
4744 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
4745 | else: |
||
4746 | body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset', |
||
4747 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), |
||
4748 | ('%(VAL_PTR)s',),)) |
||
4749 | elif (ectx.Per()): |
||
4750 | body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset', |
||
4751 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
4752 | ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),)) |
||
4753 | else: |
||
4754 | body = '#error Can not decode %s' % (tname) |
||
4755 | return body |
||
4756 | |||
4757 | #--- EmbeddedPDVType ----------------------------------------------------------- |
||
4758 | class EmbeddedPDVType (Type): |
||
4759 | def eth_tname(self): |
||
4760 | return 'EMBEDDED_PDV' |
||
4761 | |||
4762 | def eth_ftype(self, ectx): |
||
4763 | return ('FT_NONE', 'BASE_NONE') |
||
4764 | |||
4765 | def GetTTag(self, ectx): |
||
4766 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV') |
||
4767 | |||
4768 | def eth_type_default_pars(self, ectx, tname): |
||
4769 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4770 | if ectx.default_embedded_pdv_cb: |
||
4771 | pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb |
||
4772 | else: |
||
4773 | pars['TYPE_REF_FN'] = 'NULL' |
||
4774 | return pars |
||
4775 | |||
4776 | def eth_type_default_body(self, ectx, tname): |
||
4777 | if (ectx.Ber()): |
||
4778 | body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset', |
||
4779 | par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) |
||
4780 | elif (ectx.Per()): |
||
4781 | body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset', |
||
4782 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) |
||
4783 | else: |
||
4784 | body = '#error Can not decode %s' % (tname) |
||
4785 | return body |
||
4786 | |||
4787 | #--- ExternalType ----------------------------------------------------------- |
||
4788 | class ExternalType (Type): |
||
4789 | def eth_tname(self): |
||
4790 | return 'EXTERNAL' |
||
4791 | |||
4792 | def eth_ftype(self, ectx): |
||
4793 | return ('FT_NONE', 'BASE_NONE') |
||
4794 | |||
4795 | def GetTTag(self, ectx): |
||
4796 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL') |
||
4797 | |||
4798 | def eth_type_default_pars(self, ectx, tname): |
||
4799 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4800 | if ectx.default_external_type_cb: |
||
4801 | pars['TYPE_REF_FN'] = ectx.default_external_type_cb |
||
4802 | else: |
||
4803 | pars['TYPE_REF_FN'] = 'NULL' |
||
4804 | return pars |
||
4805 | |||
4806 | def eth_type_default_body(self, ectx, tname): |
||
4807 | if (ectx.Ber()): |
||
4808 | body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset', |
||
4809 | par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) |
||
4810 | elif (ectx.Per()): |
||
4811 | body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset', |
||
4812 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) |
||
4813 | else: |
||
4814 | body = '#error Can not decode %s' % (tname) |
||
4815 | return body |
||
4816 | |||
4817 | #--- OpenType ----------------------------------------------------------- |
||
4818 | class OpenType (Type): |
||
4819 | def to_python (self, ctx): |
||
4820 | return "asn1.ANY" |
||
4821 | |||
4822 | def single_type(self): |
||
4823 | if (self.HasConstraint() and |
||
4824 | self.constr.type == 'Type' and |
||
4825 | self.constr.subtype.type == 'Type_Ref'): |
||
4826 | return self.constr.subtype.val |
||
4827 | return None |
||
4828 | |||
4829 | def eth_reg_sub(self, ident, ectx): |
||
4830 | t = self.single_type() |
||
4831 | if t: |
||
4832 | ectx.eth_dep_add(ident, t) |
||
4833 | |||
4834 | def eth_tname(self): |
||
4835 | t = self.single_type() |
||
4836 | if t: |
||
4837 | return 'OpenType_' + t |
||
4838 | else: |
||
4839 | return Type.eth_tname(self) |
||
4840 | |||
4841 | def eth_ftype(self, ectx): |
||
4842 | return ('FT_NONE', 'BASE_NONE') |
||
4843 | |||
4844 | def GetTTag(self, ectx): |
||
4845 | return ('BER_CLASS_ANY', '0') |
||
4846 | |||
4847 | def eth_type_default_pars(self, ectx, tname): |
||
4848 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4849 | pars['FN_VARIANT'] = ectx.default_opentype_variant |
||
4850 | t = self.single_type() |
||
4851 | if t: |
||
4852 | t = ectx.type[t]['ethname'] |
||
4853 | pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] |
||
4854 | pars['TYPE_REF_TNAME'] = t |
||
4855 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' |
||
4856 | else: |
||
4857 | pars['TYPE_REF_FN'] = 'NULL' |
||
4858 | return pars |
||
4859 | |||
4860 | def eth_type_default_body(self, ectx, tname): |
||
4861 | if (ectx.Per()): |
||
4862 | body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset', |
||
4863 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) |
||
4864 | else: |
||
4865 | body = '#error Can not decode %s' % (tname) |
||
4866 | return body |
||
4867 | |||
4868 | #--- InstanceOfType ----------------------------------------------------------- |
||
4869 | class InstanceOfType (Type): |
||
4870 | def eth_tname(self): |
||
4871 | return 'INSTANCE_OF' |
||
4872 | |||
4873 | def eth_ftype(self, ectx): |
||
4874 | return ('FT_NONE', 'BASE_NONE') |
||
4875 | |||
4876 | def GetTTag(self, ectx): |
||
4877 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL') |
||
4878 | |||
4879 | def eth_type_default_pars(self, ectx, tname): |
||
4880 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
4881 | if ectx.default_external_type_cb: |
||
4882 | pars['TYPE_REF_FN'] = ectx.default_external_type_cb |
||
4883 | else: |
||
4884 | pars['TYPE_REF_FN'] = 'NULL' |
||
4885 | return pars |
||
4886 | |||
4887 | def eth_type_default_body(self, ectx, tname): |
||
4888 | if (ectx.Ber()): |
||
4889 | body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset', |
||
4890 | par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) |
||
4891 | elif (ectx.Per()): |
||
4892 | body = '#error Can not decode %s' % (tname) |
||
4893 | else: |
||
4894 | body = '#error Can not decode %s' % (tname) |
||
4895 | return body |
||
4896 | |||
4897 | #--- AnyType ----------------------------------------------------------- |
||
4898 | class AnyType (Type): |
||
4899 | def to_python (self, ctx): |
||
4900 | return "asn1.ANY" |
||
4901 | |||
4902 | def eth_ftype(self, ectx): |
||
4903 | return ('FT_NONE', 'BASE_NONE') |
||
4904 | |||
4905 | def GetTTag(self, ectx): |
||
4906 | return ('BER_CLASS_ANY', '0') |
||
4907 | |||
4908 | def eth_type_default_body(self, ectx, tname): |
||
4909 | body = '#error Can not decode %s' % (tname) |
||
4910 | return body |
||
4911 | |||
4912 | class Literal (Node): |
||
4913 | def to_python (self, ctx): |
||
4914 | return self.val |
||
4915 | |||
4916 | #--- NullType ----------------------------------------------------------------- |
||
4917 | class NullType (Type): |
||
4918 | def to_python (self, ctx): |
||
4919 | return 'asn1.NULL' |
||
4920 | |||
4921 | def eth_tname(self): |
||
4922 | return 'NULL' |
||
4923 | |||
4924 | def GetTTag(self, ectx): |
||
4925 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL') |
||
4926 | |||
4927 | def eth_type_default_body(self, ectx, tname): |
||
4928 | if (ectx.Ber()): |
||
4929 | body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset', |
||
4930 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),)) |
||
4931 | elif (ectx.Per()): |
||
4932 | body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset', |
||
4933 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) |
||
4934 | else: |
||
4935 | body = '#error Can not decode %s' % (tname) |
||
4936 | return body |
||
4937 | |||
4938 | #--- NullValue ---------------------------------------------------- |
||
4939 | class NullValue (Value): |
||
4940 | def to_str(self, ectx): |
||
4941 | return 'NULL' |
||
4942 | |||
4943 | #--- RealType ----------------------------------------------------------------- |
||
4944 | class RealType (Type): |
||
4945 | def to_python (self, ctx): |
||
4946 | return 'asn1.REAL' |
||
4947 | |||
4948 | def eth_tname(self): |
||
4949 | return 'REAL' |
||
4950 | |||
4951 | def GetTTag(self, ectx): |
||
4952 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL') |
||
4953 | |||
4954 | def eth_ftype(self, ectx): |
||
4955 | return ('FT_DOUBLE', 'BASE_NONE') |
||
4956 | |||
4957 | def eth_type_default_body(self, ectx, tname): |
||
4958 | if (ectx.Ber()): |
||
4959 | body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset', |
||
4960 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), |
||
4961 | ('%(VAL_PTR)s',),)) |
||
4962 | elif (ectx.Per()): |
||
4963 | body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset', |
||
4964 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
4965 | else: |
||
4966 | body = '#error Can not decode %s' % (tname) |
||
4967 | return body |
||
4968 | |||
4969 | #--- BooleanType -------------------------------------------------------------- |
||
4970 | class BooleanType (Type): |
||
4971 | def to_python (self, ctx): |
||
4972 | return 'asn1.BOOLEAN' |
||
4973 | |||
4974 | def eth_tname(self): |
||
4975 | return 'BOOLEAN' |
||
4976 | |||
4977 | def GetTTag(self, ectx): |
||
4978 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN') |
||
4979 | |||
4980 | def eth_ftype(self, ectx): |
||
4981 | return ('FT_BOOLEAN', 'BASE_NONE') |
||
4982 | |||
4983 | def eth_type_default_body(self, ectx, tname): |
||
4984 | if (ectx.Ber()): |
||
4985 | body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset', |
||
4986 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),)) |
||
4987 | elif (ectx.Per()): |
||
4988 | body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset', |
||
4989 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
4990 | else: |
||
4991 | body = '#error Can not decode %s' % (tname) |
||
4992 | return body |
||
4993 | |||
4994 | #--- OctetStringType ---------------------------------------------------------- |
||
4995 | class OctetStringType (Type): |
||
4996 | def to_python (self, ctx): |
||
4997 | return 'asn1.OCTSTRING' |
||
4998 | |||
4999 | def eth_tname(self): |
||
5000 | if not self.HasConstraint(): |
||
5001 | return 'OCTET_STRING' |
||
5002 | elif self.constr.type == 'Size': |
||
5003 | return 'OCTET_STRING' + '_' + self.constr.eth_constrname() |
||
5004 | else: |
||
5005 | return '#' + self.type + '_' + str(id(self)) |
||
5006 | |||
5007 | def eth_ftype(self, ectx): |
||
5008 | return ('FT_BYTES', 'BASE_NONE') |
||
5009 | |||
5010 | def GetTTag(self, ectx): |
||
5011 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING') |
||
5012 | |||
5013 | def eth_need_pdu(self, ectx): |
||
5014 | pdu = None |
||
5015 | if self.HasContentsConstraint(): |
||
5016 | t = self.constr.GetContents(ectx) |
||
5017 | if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')): |
||
5018 | pdu = { 'type' : t, |
||
5019 | 'new' : ectx.default_containing_variant == '_pdu_new' } |
||
5020 | return pdu |
||
5021 | |||
5022 | def eth_type_default_pars(self, ectx, tname): |
||
5023 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
5024 | (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) |
||
5025 | if self.HasContentsConstraint(): |
||
5026 | pars['FN_VARIANT'] = ectx.default_containing_variant |
||
5027 | t = self.constr.GetContents(ectx) |
||
5028 | if t: |
||
5029 | if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'): |
||
5030 | t = ectx.field[t]['ethname'] |
||
5031 | pars['TYPE_REF_PROTO'] = '' |
||
5032 | pars['TYPE_REF_TNAME'] = t |
||
5033 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s' |
||
5034 | else: |
||
5035 | t = ectx.type[t]['ethname'] |
||
5036 | pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] |
||
5037 | pars['TYPE_REF_TNAME'] = t |
||
5038 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' |
||
5039 | else: |
||
5040 | pars['TYPE_REF_FN'] = 'NULL' |
||
5041 | return pars |
||
5042 | |||
5043 | def eth_type_default_body(self, ectx, tname): |
||
5044 | if (ectx.Ber()): |
||
5045 | if (ectx.constraints_check and self.HasSizeConstraint()): |
||
5046 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret='offset', |
||
5047 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
5048 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5049 | else: |
||
5050 | body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset', |
||
5051 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), |
||
5052 | ('%(VAL_PTR)s',),)) |
||
5053 | elif (ectx.Per()): |
||
5054 | if self.HasContentsConstraint(): |
||
5055 | body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset', |
||
5056 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5057 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),)) |
||
5058 | else: |
||
5059 | body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset', |
||
5060 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5061 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),)) |
||
5062 | else: |
||
5063 | body = '#error Can not decode %s' % (tname) |
||
5064 | return body |
||
5065 | |||
5066 | #--- CharacterStringType ------------------------------------------------------ |
||
5067 | class CharacterStringType (Type): |
||
5068 | def eth_tname(self): |
||
5069 | if not self.HasConstraint(): |
||
5070 | return self.eth_tsname() |
||
5071 | elif self.constr.type == 'Size': |
||
5072 | return self.eth_tsname() + '_' + self.constr.eth_constrname() |
||
5073 | else: |
||
5074 | return '#' + self.type + '_' + str(id(self)) |
||
5075 | |||
5076 | def eth_ftype(self, ectx): |
||
5077 | return ('FT_STRING', 'BASE_NONE') |
||
5078 | |||
5079 | class RestrictedCharacterStringType (CharacterStringType): |
||
5080 | def to_python (self, ctx): |
||
5081 | return 'asn1.' + self.eth_tsname() |
||
5082 | |||
5083 | def GetTTag(self, ectx): |
||
5084 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname()) |
||
5085 | |||
5086 | def eth_type_default_pars(self, ectx, tname): |
||
5087 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
5088 | (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) |
||
5089 | (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1]) |
||
5090 | (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx) |
||
5091 | return pars |
||
5092 | |||
5093 | def eth_type_default_body(self, ectx, tname): |
||
5094 | if (ectx.Ber()): |
||
5095 | if (ectx.constraints_check and self.HasSizeConstraint()): |
||
5096 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret='offset', |
||
5097 | par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'), |
||
5098 | ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
5099 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5100 | else: |
||
5101 | body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset', |
||
5102 | par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'), |
||
5103 | ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), |
||
5104 | ('%(VAL_PTR)s',),)) |
||
5105 | elif (ectx.Per() and self.HasPermAlph()): |
||
5106 | body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset', |
||
5107 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5108 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'), |
||
5109 | ('%(VAL_PTR)s',),)) |
||
5110 | elif (ectx.Per()): |
||
5111 | if (self.eth_tsname() == 'GeneralString'): |
||
5112 | body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', |
||
5113 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) |
||
5114 | elif (self.eth_tsname() == 'GeneralizedTime'): |
||
5115 | body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset', |
||
5116 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5117 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) |
||
5118 | elif (self.eth_tsname() == 'UTCTime'): |
||
5119 | body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset', |
||
5120 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5121 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) |
||
5122 | else: |
||
5123 | body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', |
||
5124 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5125 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) |
||
5126 | else: |
||
5127 | body = '#error Can not decode %s' % (tname) |
||
5128 | return body |
||
5129 | |||
5130 | class BMPStringType (RestrictedCharacterStringType): |
||
5131 | def eth_tsname(self): |
||
5132 | return 'BMPString' |
||
5133 | |||
5134 | class GeneralStringType (RestrictedCharacterStringType): |
||
5135 | def eth_tsname(self): |
||
5136 | return 'GeneralString' |
||
5137 | |||
5138 | class GraphicStringType (RestrictedCharacterStringType): |
||
5139 | def eth_tsname(self): |
||
5140 | return 'GraphicString' |
||
5141 | |||
5142 | class IA5StringType (RestrictedCharacterStringType): |
||
5143 | def eth_tsname(self): |
||
5144 | return 'IA5String' |
||
5145 | |||
5146 | class NumericStringType (RestrictedCharacterStringType): |
||
5147 | def eth_tsname(self): |
||
5148 | return 'NumericString' |
||
5149 | |||
5150 | class PrintableStringType (RestrictedCharacterStringType): |
||
5151 | def eth_tsname(self): |
||
5152 | return 'PrintableString' |
||
5153 | |||
5154 | class TeletexStringType (RestrictedCharacterStringType): |
||
5155 | def eth_tsname(self): |
||
5156 | return 'TeletexString' |
||
5157 | |||
5158 | class T61StringType (RestrictedCharacterStringType): |
||
5159 | def eth_tsname(self): |
||
5160 | return 'T61String' |
||
5161 | def GetTTag(self, ectx): |
||
5162 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString') |
||
5163 | |||
5164 | class UniversalStringType (RestrictedCharacterStringType): |
||
5165 | def eth_tsname(self): |
||
5166 | return 'UniversalString' |
||
5167 | |||
5168 | class UTF8StringType (RestrictedCharacterStringType): |
||
5169 | def eth_tsname(self): |
||
5170 | return 'UTF8String' |
||
5171 | |||
5172 | class VideotexStringType (RestrictedCharacterStringType): |
||
5173 | def eth_tsname(self): |
||
5174 | return 'VideotexString' |
||
5175 | |||
5176 | class VisibleStringType (RestrictedCharacterStringType): |
||
5177 | def eth_tsname(self): |
||
5178 | return 'VisibleString' |
||
5179 | |||
5180 | class ISO646StringType (RestrictedCharacterStringType): |
||
5181 | def eth_tsname(self): |
||
5182 | return 'ISO646String' |
||
5183 | def GetTTag(self, ectx): |
||
5184 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString') |
||
5185 | |||
5186 | class UnrestrictedCharacterStringType (CharacterStringType): |
||
5187 | def to_python (self, ctx): |
||
5188 | return 'asn1.UnrestrictedCharacterString' |
||
5189 | def eth_tsname(self): |
||
5190 | return 'CHARACTER_STRING' |
||
5191 | |||
5192 | #--- UsefulType --------------------------------------------------------------- |
||
5193 | class GeneralizedTime (RestrictedCharacterStringType): |
||
5194 | def eth_tsname(self): |
||
5195 | return 'GeneralizedTime' |
||
5196 | |||
5197 | def eth_type_default_body(self, ectx, tname): |
||
5198 | if (ectx.Ber()): |
||
5199 | body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', |
||
5200 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),)) |
||
5201 | return body |
||
5202 | else: |
||
5203 | return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname) |
||
5204 | |||
5205 | class UTCTime (RestrictedCharacterStringType): |
||
5206 | def eth_tsname(self): |
||
5207 | return 'UTCTime' |
||
5208 | |||
5209 | def eth_type_default_body(self, ectx, tname): |
||
5210 | if (ectx.Ber()): |
||
5211 | body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', |
||
5212 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),)) |
||
5213 | return body |
||
5214 | else: |
||
5215 | return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname) |
||
5216 | |||
5217 | class ObjectDescriptor (RestrictedCharacterStringType): |
||
5218 | def eth_tsname(self): |
||
5219 | return 'ObjectDescriptor' |
||
5220 | |||
5221 | def eth_type_default_body(self, ectx, tname): |
||
5222 | if (ectx.Ber()): |
||
5223 | body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname) |
||
5224 | elif (ectx.Per()): |
||
5225 | body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset', |
||
5226 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5227 | else: |
||
5228 | body = '#error Can not decode %s' % (tname) |
||
5229 | return body |
||
5230 | |||
5231 | #--- ObjectIdentifierType ----------------------------------------------------- |
||
5232 | class ObjectIdentifierType (Type): |
||
5233 | def to_python (self, ctx): |
||
5234 | return 'asn1.OBJECT_IDENTIFIER' |
||
5235 | |||
5236 | def eth_tname(self): |
||
5237 | return 'OBJECT_IDENTIFIER' |
||
5238 | |||
5239 | def eth_ftype(self, ectx): |
||
5240 | return ('FT_OID', 'BASE_NONE') |
||
5241 | |||
5242 | def GetTTag(self, ectx): |
||
5243 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID') |
||
5244 | |||
5245 | def eth_type_default_pars(self, ectx, tname): |
||
5246 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
5247 | pars['FN_VARIANT'] = ectx.default_oid_variant |
||
5248 | return pars |
||
5249 | |||
5250 | def eth_type_default_body(self, ectx, tname): |
||
5251 | if (ectx.Ber()): |
||
5252 | body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset', |
||
5253 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5254 | elif (ectx.Per()): |
||
5255 | body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset', |
||
5256 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5257 | else: |
||
5258 | body = '#error Can not decode %s' % (tname) |
||
5259 | return body |
||
5260 | |||
5261 | #--- ObjectIdentifierValue ---------------------------------------------------- |
||
5262 | class ObjectIdentifierValue (Value): |
||
5263 | def get_num(self, path, val): |
||
5264 | return str(oid_names.get(path + '/' + val, val)) |
||
5265 | |||
5266 | def to_str(self, ectx): |
||
5267 | out = '' |
||
5268 | path = '' |
||
5269 | first = True |
||
5270 | sep = '' |
||
5271 | for v in self.comp_list: |
||
5272 | if isinstance(v, Node) and (v.type == 'name_and_number'): |
||
5273 | vstr = v.number |
||
5274 | elif v.isdigit(): |
||
5275 | vstr = v |
||
5276 | else: |
||
5277 | vstr = self.get_num(path, v) |
||
5278 | if not first and not vstr.isdigit(): |
||
5279 | vstr = ectx.value_get_val(vstr) |
||
5280 | if first: |
||
5281 | if vstr.isdigit(): |
||
5282 | out += '"' + vstr |
||
5283 | else: |
||
5284 | out += ectx.value_get_eth(vstr) + '"' |
||
5285 | else: |
||
5286 | out += sep + vstr |
||
5287 | path += sep + vstr |
||
5288 | first = False |
||
5289 | sep = '.' |
||
5290 | out += '"' |
||
5291 | return out |
||
5292 | |||
5293 | def get_dep(self): |
||
5294 | v = self.comp_list[0] |
||
5295 | if isinstance(v, Node) and (v.type == 'name_and_number'): |
||
5296 | return None |
||
5297 | elif v.isdigit(): |
||
5298 | return None |
||
5299 | else: |
||
5300 | vstr = self.get_num('', v) |
||
5301 | if vstr.isdigit(): |
||
5302 | return None |
||
5303 | else: |
||
5304 | return vstr |
||
5305 | |||
5306 | class NamedNumber(Node): |
||
5307 | def to_python (self, ctx): |
||
5308 | return "('%s',%s)" % (self.ident, self.val) |
||
5309 | |||
5310 | class NamedNumListBase(Node): |
||
5311 | def to_python (self, ctx): |
||
5312 | return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join ( |
||
5313 | [x.to_python (ctx) for x in self.named_list])) |
||
5314 | |||
5315 | #--- RelativeOIDType ---------------------------------------------------------- |
||
5316 | class RelativeOIDType (Type): |
||
5317 | |||
5318 | def eth_tname(self): |
||
5319 | return 'RELATIVE_OID' |
||
5320 | |||
5321 | def eth_ftype(self, ectx): |
||
5322 | return ('FT_REL_OID', 'BASE_NONE') |
||
5323 | |||
5324 | def GetTTag(self, ectx): |
||
5325 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID') |
||
5326 | |||
5327 | def eth_type_default_pars(self, ectx, tname): |
||
5328 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
5329 | pars['FN_VARIANT'] = ectx.default_oid_variant |
||
5330 | return pars |
||
5331 | |||
5332 | def eth_type_default_body(self, ectx, tname): |
||
5333 | if (ectx.Ber()): |
||
5334 | body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset', |
||
5335 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5336 | elif (ectx.Per()): |
||
5337 | body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset', |
||
5338 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5339 | else: |
||
5340 | body = '#error Can not decode %s' % (tname) |
||
5341 | return body |
||
5342 | |||
5343 | |||
5344 | #--- IntegerType -------------------------------------------------------------- |
||
5345 | class IntegerType (Type): |
||
5346 | def to_python (self, ctx): |
||
5347 | return "asn1.INTEGER_class ([%s])" % (",".join ( |
||
5348 | [x.to_python (ctx) for x in self.named_list])) |
||
5349 | |||
5350 | def add_named_value(self, ident, val): |
||
5351 | e = NamedNumber(ident = ident, val = val) |
||
5352 | if not self.named_list: |
||
5353 | self.named_list = [] |
||
5354 | self.named_list.append(e) |
||
5355 | |||
5356 | def eth_tname(self): |
||
5357 | if self.named_list: |
||
5358 | return Type.eth_tname(self) |
||
5359 | if not self.HasConstraint(): |
||
5360 | return 'INTEGER' |
||
5361 | elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange': |
||
5362 | return 'INTEGER' + '_' + self.constr.eth_constrname() |
||
5363 | else: |
||
5364 | return 'INTEGER' + '_' + self.constr.eth_tname() |
||
5365 | |||
5366 | def GetTTag(self, ectx): |
||
5367 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER') |
||
5368 | |||
5369 | |||
5370 | def eth_ftype(self, ectx): |
||
5371 | if self.HasConstraint(): |
||
5372 | if not self.constr.IsNegativ(): |
||
5373 | if self.constr.Needs64b(ectx): |
||
5374 | return ('FT_UINT64', 'BASE_DEC') |
||
5375 | else: |
||
5376 | return ('FT_UINT32', 'BASE_DEC') |
||
5377 | if self.constr.Needs64b(ectx): |
||
5378 | return ('FT_INT64', 'BASE_DEC') |
||
5379 | return ('FT_INT32', 'BASE_DEC') |
||
5380 | |||
5381 | def eth_strings(self): |
||
5382 | if (self.named_list): |
||
5383 | return '$$' |
||
5384 | else: |
||
5385 | return 'NULL' |
||
5386 | |||
5387 | def eth_has_vals(self): |
||
5388 | if (self.named_list): |
||
5389 | return True |
||
5390 | else: |
||
5391 | return False |
||
5392 | |||
5393 | def get_vals(self, ectx): |
||
5394 | vals = [] |
||
5395 | for e in (self.named_list): |
||
5396 | vals.append((int(e.val), e.ident)) |
||
5397 | return vals |
||
5398 | |||
5399 | def eth_type_vals(self, tname, ectx): |
||
5400 | if not self.eth_has_vals(): return '' |
||
5401 | out = '\n' |
||
5402 | vals = self.get_vals(ectx) |
||
5403 | out += ectx.eth_vals(tname, vals) |
||
5404 | return out |
||
5405 | |||
5406 | def reg_enum_vals(self, tname, ectx): |
||
5407 | vals = self.get_vals(ectx) |
||
5408 | for (val, id) in vals: |
||
5409 | ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id)) |
||
5410 | |||
5411 | def eth_type_enum(self, tname, ectx): |
||
5412 | if not self.eth_has_enum(tname, ectx): return '' |
||
5413 | out = '\n' |
||
5414 | vals = self.get_vals(ectx) |
||
5415 | out += ectx.eth_enum(tname, vals) |
||
5416 | return out |
||
5417 | |||
5418 | def eth_type_default_pars(self, ectx, tname): |
||
5419 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
5420 | if self.HasValueConstraint(): |
||
5421 | (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx) |
||
5422 | if (pars['FN_VARIANT'] == '') and self.constr.Needs64b(ectx): |
||
5423 | if ectx.Ber(): pars['FN_VARIANT'] = '64' |
||
5424 | else: pars['FN_VARIANT'] = '_64b' |
||
5425 | return pars |
||
5426 | |||
5427 | def eth_type_default_body(self, ectx, tname): |
||
5428 | if (ectx.Ber()): |
||
5429 | if (ectx.constraints_check and self.HasValueConstraint()): |
||
5430 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset', |
||
5431 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
5432 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) |
||
5433 | else: |
||
5434 | body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset', |
||
5435 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), |
||
5436 | ('%(VAL_PTR)s',),)) |
||
5437 | elif (ectx.Per() and not self.HasValueConstraint()): |
||
5438 | body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset', |
||
5439 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),)) |
||
5440 | elif (ectx.Per() and self.HasValueConstraint()): |
||
5441 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset', |
||
5442 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5443 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),)) |
||
5444 | else: |
||
5445 | body = '#error Can not decode %s' % (tname) |
||
5446 | return body |
||
5447 | |||
5448 | #--- BitStringType ------------------------------------------------------------ |
||
5449 | class BitStringType (Type): |
||
5450 | def to_python (self, ctx): |
||
5451 | return "asn1.BITSTRING_class ([%s])" % (",".join ( |
||
5452 | [x.to_python (ctx) for x in self.named_list])) |
||
5453 | |||
5454 | def eth_tname(self): |
||
5455 | if self.named_list: |
||
5456 | return Type.eth_tname(self) |
||
5457 | elif not self.HasConstraint(): |
||
5458 | return 'BIT_STRING' |
||
5459 | elif self.constr.IsSize(): |
||
5460 | return 'BIT_STRING' + '_' + self.constr.eth_constrname() |
||
5461 | else: |
||
5462 | return '#' + self.type + '_' + str(id(self)) |
||
5463 | |||
5464 | def GetTTag(self, ectx): |
||
5465 | return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING') |
||
5466 | |||
5467 | def eth_ftype(self, ectx): |
||
5468 | return ('FT_BYTES', 'BASE_NONE') |
||
5469 | |||
5470 | def eth_need_tree(self): |
||
5471 | return self.named_list |
||
5472 | |||
5473 | def eth_need_pdu(self, ectx): |
||
5474 | pdu = None |
||
5475 | if self.HasContentsConstraint(): |
||
5476 | t = self.constr.GetContents(ectx) |
||
5477 | if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')): |
||
5478 | pdu = { 'type' : t, |
||
5479 | 'new' : ectx.default_containing_variant == '_pdu_new' } |
||
5480 | return pdu |
||
5481 | |||
5482 | def eth_named_bits(self): |
||
5483 | bits = [] |
||
5484 | if (self.named_list): |
||
5485 | for e in (self.named_list): |
||
5486 | bits.append((int(e.val), e.ident)) |
||
5487 | return bits |
||
5488 | |||
5489 | def eth_type_default_pars(self, ectx, tname): |
||
5490 | pars = Type.eth_type_default_pars(self, ectx, tname) |
||
5491 | pars['LEN_PTR'] = 'NULL' |
||
5492 | (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) |
||
5493 | if 'ETT_INDEX' not in pars: |
||
5494 | pars['ETT_INDEX'] = '-1' |
||
5495 | pars['TABLE'] = 'NULL' |
||
5496 | if self.eth_named_bits(): |
||
5497 | pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits' |
||
5498 | if self.HasContentsConstraint(): |
||
5499 | pars['FN_VARIANT'] = ectx.default_containing_variant |
||
5500 | t = self.constr.GetContents(ectx) |
||
5501 | if t: |
||
5502 | if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'): |
||
5503 | t = ectx.field[t]['ethname'] |
||
5504 | pars['TYPE_REF_PROTO'] = '' |
||
5505 | pars['TYPE_REF_TNAME'] = t |
||
5506 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s' |
||
5507 | else: |
||
5508 | t = ectx.type[t]['ethname'] |
||
5509 | pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] |
||
5510 | pars['TYPE_REF_TNAME'] = t |
||
5511 | pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' |
||
5512 | else: |
||
5513 | pars['TYPE_REF_FN'] = 'NULL' |
||
5514 | return pars |
||
5515 | |||
5516 | def eth_type_default_table(self, ectx, tname): |
||
5517 | #print "eth_type_default_table(tname='%s')" % (tname) |
||
5518 | table = '' |
||
5519 | bits = self.eth_named_bits() |
||
5520 | if (bits and ectx.Ber()): |
||
5521 | table = ectx.eth_bits(tname, bits) |
||
5522 | return table |
||
5523 | |||
5524 | def eth_type_default_body(self, ectx, tname): |
||
5525 | if (ectx.Ber()): |
||
5526 | if (ectx.constraints_check and self.HasSizeConstraint()): |
||
5527 | body = ectx.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret='offset', |
||
5528 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
5529 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',), |
||
5530 | ('%(VAL_PTR)s',),)) |
||
5531 | else: |
||
5532 | body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset', |
||
5533 | par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), |
||
5534 | ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',), |
||
5535 | ('%(VAL_PTR)s',),)) |
||
5536 | elif (ectx.Per()): |
||
5537 | if self.HasContentsConstraint(): |
||
5538 | body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset', |
||
5539 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5540 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),)) |
||
5541 | else: |
||
5542 | body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset', |
||
5543 | par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), |
||
5544 | ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s', '%(LEN_PTR)s'),)) |
||
5545 | else: |
||
5546 | body = '#error Can not decode %s' % (tname) |
||
5547 | return body |
||
5548 | |||
5549 | #--- BStringValue ------------------------------------------------------------ |
||
5550 | bstring_tab = { |
||
5551 | '0000' : '0', |
||
5552 | '0001' : '1', |
||
5553 | '0010' : '2', |
||
5554 | '0011' : '3', |
||
5555 | '0100' : '4', |
||
5556 | '0101' : '5', |
||
5557 | '0110' : '6', |
||
5558 | '0111' : '7', |
||
5559 | '1000' : '8', |
||
5560 | '1001' : '9', |
||
5561 | '1010' : 'A', |
||
5562 | '1011' : 'B', |
||
5563 | '1100' : 'C', |
||
5564 | '1101' : 'D', |
||
5565 | '1110' : 'E', |
||
5566 | '1111' : 'F', |
||
5567 | } |
||
5568 | class BStringValue (Value): |
||
5569 | def to_str(self, ectx): |
||
5570 | v = self.val[1:-2] |
||
5571 | if len(v) % 8: |
||
5572 | v += '0' * (8 - len(v) % 8) |
||
5573 | vv = '0x' |
||
5574 | for i in (list(range(0, len(v), 4))): |
||
5575 | vv += bstring_tab[v[i:i+4]] |
||
5576 | return vv |
||
5577 | |||
5578 | #--- HStringValue ------------------------------------------------------------ |
||
5579 | class HStringValue (Value): |
||
5580 | def to_str(self, ectx): |
||
5581 | vv = '0x' |
||
5582 | vv += self.val[1:-2] |
||
5583 | return vv |
||
5584 | def __int__(self): |
||
5585 | return int(self.val[1:-2], 16) |
||
5586 | |||
5587 | #--- FieldSpec ---------------------------------------------------------------- |
||
5588 | class FieldSpec (Node): |
||
5589 | def __init__(self,*args, **kw) : |
||
5590 | self.name = None |
||
5591 | Node.__init__ (self,*args, **kw) |
||
5592 | |||
5593 | def SetName(self, name): |
||
5594 | self.name = name |
||
5595 | |||
5596 | def get_repr(self): |
||
5597 | return ['#UNSUPPORTED_' + self.type] |
||
5598 | |||
5599 | def fld_repr(self): |
||
5600 | repr = [self.name] |
||
5601 | repr.extend(self.get_repr()) |
||
5602 | return repr |
||
5603 | |||
5604 | class TypeFieldSpec (FieldSpec): |
||
5605 | def get_repr(self): |
||
5606 | return [] |
||
5607 | |||
5608 | class FixedTypeValueFieldSpec (FieldSpec): |
||
5609 | def get_repr(self): |
||
5610 | if isinstance(self.typ, Type_Ref): |
||
5611 | repr = ['TypeReference', self.typ.val] |
||
5612 | else: |
||
5613 | repr = [self.typ.type] |
||
5614 | return repr |
||
5615 | |||
5616 | class VariableTypeValueFieldSpec (FieldSpec): |
||
5617 | def get_repr(self): |
||
5618 | return ['_' + self.type] |
||
5619 | |||
5620 | class FixedTypeValueSetFieldSpec (FieldSpec): |
||
5621 | def get_repr(self): |
||
5622 | return ['_' + self.type] |
||
5623 | |||
5624 | class ObjectFieldSpec (FieldSpec): |
||
5625 | def get_repr(self): |
||
5626 | return ['ClassReference', self.cls.val] |
||
5627 | |||
5628 | class ObjectSetFieldSpec (FieldSpec): |
||
5629 | def get_repr(self): |
||
5630 | return ['ClassReference', self.cls.val] |
||
5631 | |||
5632 | #============================================================================== |
||
5633 | |||
5634 | def p_module_list_1 (t): |
||
5635 | 'module_list : module_list ModuleDefinition' |
||
5636 | t[0] = t[1] + [t[2]] |
||
5637 | |||
5638 | def p_module_list_2 (t): |
||
5639 | 'module_list : ModuleDefinition' |
||
5640 | t[0] = [t[1]] |
||
5641 | |||
5642 | |||
5643 | #--- ITU-T Recommendation X.680 ----------------------------------------------- |
||
5644 | |||
5645 | |||
5646 | # 11 ASN.1 lexical items -------------------------------------------------------- |
||
5647 | |||
5648 | # 11.2 Type references |
||
5649 | def p_type_ref (t): |
||
5650 | 'type_ref : UCASE_IDENT' |
||
5651 | t[0] = Type_Ref(val=t[1]) |
||
5652 | |||
5653 | # 11.3 Identifiers |
||
5654 | def p_identifier (t): |
||
5655 | 'identifier : LCASE_IDENT' |
||
5656 | t[0] = t[1] |
||
5657 | |||
5658 | # 11.4 Value references |
||
5659 | # cause reduce/reduce conflict |
||
5660 | #def p_valuereference (t): |
||
5661 | # 'valuereference : LCASE_IDENT' |
||
5662 | # t[0] = Value_Ref(val=t[1]) |
||
5663 | |||
5664 | # 11.5 Module references |
||
5665 | def p_modulereference (t): |
||
5666 | 'modulereference : UCASE_IDENT' |
||
5667 | t[0] = t[1] |
||
5668 | |||
5669 | |||
5670 | # 12 Module definition -------------------------------------------------------- |
||
5671 | |||
5672 | # 12.1 |
||
5673 | def p_ModuleDefinition (t): |
||
5674 | 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END' |
||
5675 | t[0] = Module (ident = t[1], tag_def = t[3], body = t[7]) |
||
5676 | |||
5677 | def p_ModuleBegin (t): |
||
5678 | 'ModuleBegin : ' |
||
5679 | if t[-4].val == 'Remote-Operations-Information-Objects': |
||
5680 | x880_module_begin() |
||
5681 | |||
5682 | def p_TagDefault_1 (t): |
||
5683 | '''TagDefault : EXPLICIT TAGS |
||
5684 | | IMPLICIT TAGS |
||
5685 | | AUTOMATIC TAGS ''' |
||
5686 | t[0] = Default_Tags (dfl_tag = t[1]) |
||
5687 | |||
5688 | def p_TagDefault_2 (t): |
||
5689 | 'TagDefault : ' |
||
5690 | # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty". |
||
5691 | t[0] = Default_Tags (dfl_tag = 'EXPLICIT') |
||
5692 | |||
5693 | def p_ModuleIdentifier_1 (t): |
||
5694 | 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid |
||
5695 | t [0] = Node('module_ident', val = t[1], ident = t[2]) |
||
5696 | |||
5697 | def p_ModuleIdentifier_2 (t): |
||
5698 | 'ModuleIdentifier : modulereference' # name, oid |
||
5699 | t [0] = Node('module_ident', val = t[1], ident = None) |
||
5700 | |||
5701 | def p_DefinitiveIdentifier (t): |
||
5702 | 'DefinitiveIdentifier : ObjectIdentifierValue' |
||
5703 | t[0] = t[1] |
||
5704 | |||
5705 | #def p_module_ref (t): |
||
5706 | # 'module_ref : UCASE_IDENT' |
||
5707 | # t[0] = t[1] |
||
5708 | |||
5709 | def p_ModuleBody_1 (t): |
||
5710 | 'ModuleBody : Exports Imports AssignmentList' |
||
5711 | t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3]) |
||
5712 | |||
5713 | def p_ModuleBody_2 (t): |
||
5714 | 'ModuleBody : ' |
||
5715 | t[0] = Node ('module_body', exports = [], imports = [], assign_list = []) |
||
5716 | |||
5717 | def p_Exports_1 (t): |
||
5718 | 'Exports : EXPORTS syms_exported SEMICOLON' |
||
5719 | t[0] = t[2] |
||
5720 | |||
5721 | def p_Exports_2 (t): |
||
5722 | 'Exports : EXPORTS ALL SEMICOLON' |
||
5723 | t[0] = [ 'ALL' ] |
||
5724 | |||
5725 | def p_Exports_3 (t): |
||
5726 | 'Exports : ' |
||
5727 | t[0] = [ 'ALL' ] |
||
5728 | |||
5729 | def p_syms_exported_1 (t): |
||
5730 | 'syms_exported : exp_sym_list' |
||
5731 | t[0] = t[1] |
||
5732 | |||
5733 | def p_syms_exported_2 (t): |
||
5734 | 'syms_exported : ' |
||
5735 | t[0] = [] |
||
5736 | |||
5737 | def p_exp_sym_list_1 (t): |
||
5738 | 'exp_sym_list : Symbol' |
||
5739 | t[0] = [t[1]] |
||
5740 | |||
5741 | def p_exp_sym_list_2 (t): |
||
5742 | 'exp_sym_list : exp_sym_list COMMA Symbol' |
||
5743 | t[0] = t[1] + [t[3]] |
||
5744 | |||
5745 | |||
5746 | def p_Imports_1 (t): |
||
5747 | 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON' |
||
5748 | t[0] = t[3] |
||
5749 | global lcase_ident_assigned |
||
5750 | lcase_ident_assigned = {} |
||
5751 | |||
5752 | def p_importsbegin (t): |
||
5753 | 'importsbegin : ' |
||
5754 | global lcase_ident_assigned |
||
5755 | global g_conform |
||
5756 | lcase_ident_assigned = {} |
||
5757 | lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER')) |
||
5758 | |||
5759 | def p_Imports_2 (t): |
||
5760 | 'Imports : ' |
||
5761 | t[0] = [] |
||
5762 | |||
5763 | def p_SymbolsImported_1(t): |
||
5764 | 'SymbolsImported : ' |
||
5765 | t[0] = [] |
||
5766 | |||
5767 | def p_SymbolsImported_2 (t): |
||
5768 | 'SymbolsImported : SymbolsFromModuleList' |
||
5769 | t[0] = t[1] |
||
5770 | |||
5771 | def p_SymbolsFromModuleList_1 (t): |
||
5772 | 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule' |
||
5773 | t[0] = t[1] + [t[2]] |
||
5774 | |||
5775 | def p_SymbolsFromModuleList_2 (t): |
||
5776 | 'SymbolsFromModuleList : SymbolsFromModule' |
||
5777 | t[0] = [t[1]] |
||
5778 | |||
5779 | def p_SymbolsFromModule (t): |
||
5780 | 'SymbolsFromModule : SymbolList FROM GlobalModuleReference' |
||
5781 | t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3]) |
||
5782 | for s in (t[0].symbol_list): |
||
5783 | if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3] |
||
5784 | import_symbols_from_module(t[0].module, t[0].symbol_list) |
||
5785 | |||
5786 | def import_symbols_from_module(module, symbol_list): |
||
5787 | if module.val == 'Remote-Operations-Information-Objects': |
||
5788 | for i in range(len(symbol_list)): |
||
5789 | s = symbol_list[i] |
||
5790 | if isinstance(s, Type_Ref) or isinstance(s, Class_Ref): |
||
5791 | x880_import(s.val) |
||
5792 | if isinstance(s, Type_Ref) and is_class_ident(s.val): |
||
5793 | symbol_list[i] = Class_Ref (val = s.val) |
||
5794 | return |
||
5795 | for i in range(len(symbol_list)): |
||
5796 | s = symbol_list[i] |
||
5797 | if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)): |
||
5798 | import_class_from_module(module.val, s.val) |
||
5799 | if isinstance(s, Type_Ref) and is_class_ident(s.val): |
||
5800 | symbol_list[i] = Class_Ref (val = s.val) |
||
5801 | |||
5802 | def p_GlobalModuleReference (t): |
||
5803 | 'GlobalModuleReference : modulereference AssignedIdentifier' |
||
5804 | t [0] = Node('module_ident', val = t[1], ident = t[2]) |
||
5805 | |||
5806 | def p_AssignedIdentifier_1 (t): |
||
5807 | 'AssignedIdentifier : ObjectIdentifierValue' |
||
5808 | t[0] = t[1] |
||
5809 | |||
5810 | def p_AssignedIdentifier_2 (t): |
||
5811 | 'AssignedIdentifier : LCASE_IDENT_ASSIGNED' |
||
5812 | t[0] = t[1] |
||
5813 | |||
5814 | def p_AssignedIdentifier_3 (t): |
||
5815 | 'AssignedIdentifier : ' |
||
5816 | pass |
||
5817 | |||
5818 | def p_SymbolList_1 (t): |
||
5819 | 'SymbolList : Symbol' |
||
5820 | t[0] = [t[1]] |
||
5821 | |||
5822 | def p_SymbolList_2 (t): |
||
5823 | 'SymbolList : SymbolList COMMA Symbol' |
||
5824 | t[0] = t[1] + [t[3]] |
||
5825 | |||
5826 | def p_Symbol (t): |
||
5827 | '''Symbol : Reference |
||
5828 | | ParameterizedReference''' |
||
5829 | t[0] = t[1] |
||
5830 | |||
5831 | def p_Reference_1 (t): |
||
5832 | '''Reference : type_ref |
||
5833 | | objectclassreference ''' |
||
5834 | t[0] = t[1] |
||
5835 | |||
5836 | def p_Reference_2 (t): |
||
5837 | '''Reference : LCASE_IDENT_ASSIGNED |
||
5838 | | identifier ''' # instead of valuereference wich causes reduce/reduce conflict |
||
5839 | t[0] = Value_Ref(val=t[1]) |
||
5840 | |||
5841 | def p_AssignmentList_1 (t): |
||
5842 | 'AssignmentList : AssignmentList Assignment' |
||
5843 | t[0] = t[1] + [t[2]] |
||
5844 | |||
5845 | def p_AssignmentList_2 (t): |
||
5846 | 'AssignmentList : Assignment SEMICOLON' |
||
5847 | t[0] = [t[1]] |
||
5848 | |||
5849 | def p_AssignmentList_3 (t): |
||
5850 | 'AssignmentList : Assignment' |
||
5851 | t[0] = [t[1]] |
||
5852 | |||
5853 | def p_Assignment (t): |
||
5854 | '''Assignment : TypeAssignment |
||
5855 | | ValueAssignment |
||
5856 | | ValueSetTypeAssignment |
||
5857 | | ObjectClassAssignment |
||
5858 | | ObjectAssignment |
||
5859 | | ObjectSetAssignment |
||
5860 | | ParameterizedAssignment |
||
5861 | | pyquote ''' |
||
5862 | t[0] = t[1] |
||
5863 | |||
5864 | |||
5865 | # 13 Referencing type and value definitions ----------------------------------- |
||
5866 | |||
5867 | # 13.1 |
||
5868 | def p_DefinedType (t): |
||
5869 | '''DefinedType : ExternalTypeReference |
||
5870 | | type_ref |
||
5871 | | ParameterizedType''' |
||
5872 | t[0] = t[1] |
||
5873 | |||
5874 | def p_DefinedValue_1(t): |
||
5875 | '''DefinedValue : ExternalValueReference''' |
||
5876 | t[0] = t[1] |
||
5877 | |||
5878 | def p_DefinedValue_2(t): |
||
5879 | '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict |
||
5880 | t[0] = Value_Ref(val=t[1]) |
||
5881 | |||
5882 | # 13.6 |
||
5883 | def p_ExternalTypeReference (t): |
||
5884 | 'ExternalTypeReference : modulereference DOT type_ref' |
||
5885 | t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3]) |
||
5886 | |||
5887 | def p_ExternalValueReference (t): |
||
5888 | 'ExternalValueReference : modulereference DOT identifier' |
||
5889 | t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3]) |
||
5890 | |||
5891 | |||
5892 | # 15 Assigning types and values ----------------------------------------------- |
||
5893 | |||
5894 | # 15.1 |
||
5895 | def p_TypeAssignment (t): |
||
5896 | 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type' |
||
5897 | t[0] = t[3] |
||
5898 | t[0].SetName(t[1]) |
||
5899 | |||
5900 | # 15.2 |
||
5901 | def p_ValueAssignment (t): |
||
5902 | 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value' |
||
5903 | t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4]) |
||
5904 | |||
5905 | # only "simple" types are supported to simplify grammer |
||
5906 | def p_ValueType (t): |
||
5907 | '''ValueType : type_ref |
||
5908 | | BooleanType |
||
5909 | | IntegerType |
||
5910 | | ObjectIdentifierType |
||
5911 | | OctetStringType |
||
5912 | | RealType ''' |
||
5913 | |||
5914 | t[0] = t[1] |
||
5915 | |||
5916 | # 15.6 |
||
5917 | def p_ValueSetTypeAssignment (t): |
||
5918 | 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet' |
||
5919 | t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4]) |
||
5920 | |||
5921 | # 15.7 |
||
5922 | def p_ValueSet (t): |
||
5923 | 'ValueSet : lbraceignore rbraceignore' |
||
5924 | t[0] = None |
||
5925 | |||
5926 | |||
5927 | # 16 Definition of types and values ------------------------------------------- |
||
5928 | |||
5929 | # 16.1 |
||
5930 | def p_Type (t): |
||
5931 | '''Type : BuiltinType |
||
5932 | | ReferencedType |
||
5933 | | ConstrainedType''' |
||
5934 | t[0] = t[1] |
||
5935 | |||
5936 | # 16.2 |
||
5937 | def p_BuiltinType (t): |
||
5938 | '''BuiltinType : AnyType |
||
5939 | | BitStringType |
||
5940 | | BooleanType |
||
5941 | | CharacterStringType |
||
5942 | | ChoiceType |
||
5943 | | EmbeddedPDVType |
||
5944 | | EnumeratedType |
||
5945 | | ExternalType |
||
5946 | | InstanceOfType |
||
5947 | | IntegerType |
||
5948 | | NullType |
||
5949 | | ObjectClassFieldType |
||
5950 | | ObjectIdentifierType |
||
5951 | | OctetStringType |
||
5952 | | RealType |
||
5953 | | RelativeOIDType |
||
5954 | | SequenceType |
||
5955 | | SequenceOfType |
||
5956 | | SetType |
||
5957 | | SetOfType |
||
5958 | | TaggedType''' |
||
5959 | t[0] = t[1] |
||
5960 | |||
5961 | # 16.3 |
||
5962 | def p_ReferencedType (t): |
||
5963 | '''ReferencedType : DefinedType |
||
5964 | | UsefulType |
||
5965 | | SelectionType''' |
||
5966 | t[0] = t[1] |
||
5967 | |||
5968 | # 16.5 |
||
5969 | def p_NamedType (t): |
||
5970 | 'NamedType : identifier Type' |
||
5971 | t[0] = t[2] |
||
5972 | t[0].SetName (t[1]) |
||
5973 | |||
5974 | # 16.7 |
||
5975 | def p_Value (t): |
||
5976 | '''Value : BuiltinValue |
||
5977 | | ReferencedValue |
||
5978 | | ObjectClassFieldValue''' |
||
5979 | t[0] = t[1] |
||
5980 | |||
5981 | # 16.9 |
||
5982 | def p_BuiltinValue (t): |
||
5983 | '''BuiltinValue : BooleanValue |
||
5984 | | ChoiceValue |
||
5985 | | IntegerValue |
||
5986 | | ObjectIdentifierValue |
||
5987 | | RealValue |
||
5988 | | SequenceValue |
||
5989 | | hex_string |
||
5990 | | binary_string |
||
5991 | | char_string''' # XXX we don't support {data} here |
||
5992 | t[0] = t[1] |
||
5993 | |||
5994 | # 16.11 |
||
5995 | def p_ReferencedValue (t): |
||
5996 | '''ReferencedValue : DefinedValue |
||
5997 | | ValueFromObject''' |
||
5998 | t[0] = t[1] |
||
5999 | |||
6000 | # 16.13 |
||
6001 | #def p_NamedValue (t): |
||
6002 | # 'NamedValue : identifier Value' |
||
6003 | # t[0] = Node ('NamedValue', ident = t[1], value = t[2]) |
||
6004 | |||
6005 | |||
6006 | # 17 Notation for the boolean type -------------------------------------------- |
||
6007 | |||
6008 | # 17.1 |
||
6009 | def p_BooleanType (t): |
||
6010 | 'BooleanType : BOOLEAN' |
||
6011 | t[0] = BooleanType () |
||
6012 | |||
6013 | # 17.2 |
||
6014 | def p_BooleanValue (t): |
||
6015 | '''BooleanValue : TRUE |
||
6016 | | FALSE''' |
||
6017 | t[0] = t[1] |
||
6018 | |||
6019 | |||
6020 | # 18 Notation for the integer type -------------------------------------------- |
||
6021 | |||
6022 | # 18.1 |
||
6023 | def p_IntegerType_1 (t): |
||
6024 | 'IntegerType : INTEGER' |
||
6025 | t[0] = IntegerType (named_list = None) |
||
6026 | |||
6027 | def p_IntegerType_2 (t): |
||
6028 | 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE' |
||
6029 | t[0] = IntegerType(named_list = t[3]) |
||
6030 | |||
6031 | def p_NamedNumberList_1 (t): |
||
6032 | 'NamedNumberList : NamedNumber' |
||
6033 | t[0] = [t[1]] |
||
6034 | |||
6035 | def p_NamedNumberList_2 (t): |
||
6036 | 'NamedNumberList : NamedNumberList COMMA NamedNumber' |
||
6037 | t[0] = t[1] + [t[3]] |
||
6038 | |||
6039 | def p_NamedNumber (t): |
||
6040 | '''NamedNumber : identifier LPAREN SignedNumber RPAREN |
||
6041 | | identifier LPAREN DefinedValue RPAREN''' |
||
6042 | t[0] = NamedNumber(ident = t[1], val = t[3]) |
||
6043 | |||
6044 | def p_SignedNumber_1 (t): |
||
6045 | 'SignedNumber : NUMBER' |
||
6046 | t[0] = t [1] |
||
6047 | |||
6048 | def p_SignedNumber_2 (t): |
||
6049 | 'SignedNumber : MINUS NUMBER' |
||
6050 | t[0] = '-' + t[2] |
||
6051 | |||
6052 | # 18.9 |
||
6053 | def p_IntegerValue (t): |
||
6054 | 'IntegerValue : SignedNumber' |
||
6055 | t[0] = t [1] |
||
6056 | |||
6057 | # 19 Notation for the enumerated type ----------------------------------------- |
||
6058 | |||
6059 | # 19.1 |
||
6060 | def p_EnumeratedType (t): |
||
6061 | 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE' |
||
6062 | t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext']) |
||
6063 | |||
6064 | def p_Enumerations_1 (t): |
||
6065 | 'Enumerations : Enumeration' |
||
6066 | t[0] = { 'val' : t[1], 'ext' : None } |
||
6067 | |||
6068 | def p_Enumerations_2 (t): |
||
6069 | 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec' |
||
6070 | t[0] = { 'val' : t[1], 'ext' : [] } |
||
6071 | |||
6072 | def p_Enumerations_3 (t): |
||
6073 | 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration' |
||
6074 | t[0] = { 'val' : t[1], 'ext' : t[6] } |
||
6075 | |||
6076 | def p_Enumeration_1 (t): |
||
6077 | 'Enumeration : EnumerationItem' |
||
6078 | t[0] = [t[1]] |
||
6079 | |||
6080 | def p_Enumeration_2 (t): |
||
6081 | 'Enumeration : Enumeration COMMA EnumerationItem' |
||
6082 | t[0] = t[1] + [t[3]] |
||
6083 | |||
6084 | def p_EnumerationItem (t): |
||
6085 | '''EnumerationItem : Identifier |
||
6086 | | NamedNumber''' |
||
6087 | t[0] = t[1] |
||
6088 | |||
6089 | def p_Identifier (t): |
||
6090 | 'Identifier : identifier' |
||
6091 | t[0] = Node ('Identifier', ident = t[1]) |
||
6092 | |||
6093 | |||
6094 | # 20 Notation for the real type ----------------------------------------------- |
||
6095 | |||
6096 | # 20.1 |
||
6097 | def p_RealType (t): |
||
6098 | 'RealType : REAL' |
||
6099 | t[0] = RealType () |
||
6100 | |||
6101 | # 20.6 |
||
6102 | def p_RealValue (t): |
||
6103 | '''RealValue : REAL_NUMBER |
||
6104 | | SpecialRealValue''' |
||
6105 | t[0] = t [1] |
||
6106 | |||
6107 | def p_SpecialRealValue (t): |
||
6108 | '''SpecialRealValue : PLUS_INFINITY |
||
6109 | | MINUS_INFINITY''' |
||
6110 | t[0] = t[1] |
||
6111 | |||
6112 | |||
6113 | # 21 Notation for the bitstring type ------------------------------------------ |
||
6114 | |||
6115 | # 21.1 |
||
6116 | def p_BitStringType_1 (t): |
||
6117 | 'BitStringType : BIT STRING' |
||
6118 | t[0] = BitStringType (named_list = None) |
||
6119 | |||
6120 | def p_BitStringType_2 (t): |
||
6121 | 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE' |
||
6122 | t[0] = BitStringType (named_list = t[4]) |
||
6123 | |||
6124 | def p_NamedBitList_1 (t): |
||
6125 | 'NamedBitList : NamedBit' |
||
6126 | t[0] = [t[1]] |
||
6127 | |||
6128 | def p_NamedBitList_2 (t): |
||
6129 | 'NamedBitList : NamedBitList COMMA NamedBit' |
||
6130 | t[0] = t[1] + [t[3]] |
||
6131 | |||
6132 | def p_NamedBit (t): |
||
6133 | '''NamedBit : identifier LPAREN NUMBER RPAREN |
||
6134 | | identifier LPAREN DefinedValue RPAREN''' |
||
6135 | t[0] = NamedNumber (ident = t[1], val = t[3]) |
||
6136 | |||
6137 | |||
6138 | # 22 Notation for the octetstring type ---------------------------------------- |
||
6139 | |||
6140 | # 22.1 |
||
6141 | def p_OctetStringType (t): |
||
6142 | 'OctetStringType : OCTET STRING' |
||
6143 | t[0] = OctetStringType () |
||
6144 | |||
6145 | |||
6146 | # 23 Notation for the null type ----------------------------------------------- |
||
6147 | |||
6148 | # 23.1 |
||
6149 | def p_NullType (t): |
||
6150 | 'NullType : NULL' |
||
6151 | t[0] = NullType () |
||
6152 | |||
6153 | # 23.3 |
||
6154 | def p_NullValue (t): |
||
6155 | 'NullValue : NULL' |
||
6156 | t[0] = NullValue () |
||
6157 | |||
6158 | |||
6159 | # 24 Notation for sequence types ---------------------------------------------- |
||
6160 | |||
6161 | # 24.1 |
||
6162 | def p_SequenceType_1 (t): |
||
6163 | 'SequenceType : SEQUENCE LBRACE RBRACE' |
||
6164 | t[0] = SequenceType (elt_list = []) |
||
6165 | |||
6166 | def p_SequenceType_2 (t): |
||
6167 | 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE' |
||
6168 | t[0] = SequenceType (elt_list = t[3]['elt_list']) |
||
6169 | if 'ext_list' in t[3]: |
||
6170 | t[0].ext_list = t[3]['ext_list'] |
||
6171 | if 'elt_list2' in t[3]: |
||
6172 | t[0].elt_list2 = t[3]['elt_list2'] |
||
6173 | |||
6174 | def p_ExtensionAndException_1 (t): |
||
6175 | 'ExtensionAndException : ELLIPSIS' |
||
6176 | t[0] = [] |
||
6177 | |||
6178 | def p_OptionalExtensionMarker_1 (t): |
||
6179 | 'OptionalExtensionMarker : COMMA ELLIPSIS' |
||
6180 | t[0] = True |
||
6181 | |||
6182 | def p_OptionalExtensionMarker_2 (t): |
||
6183 | 'OptionalExtensionMarker : ' |
||
6184 | t[0] = False |
||
6185 | |||
6186 | def p_ComponentTypeLists_1 (t): |
||
6187 | 'ComponentTypeLists : ComponentTypeList' |
||
6188 | t[0] = {'elt_list' : t[1]} |
||
6189 | |||
6190 | def p_ComponentTypeLists_2 (t): |
||
6191 | 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker' |
||
6192 | t[0] = {'elt_list' : t[1], 'ext_list' : []} |
||
6193 | |||
6194 | def p_ComponentTypeLists_3 (t): |
||
6195 | 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker' |
||
6196 | t[0] = {'elt_list' : t[1], 'ext_list' : t[4]} |
||
6197 | |||
6198 | def p_ComponentTypeLists_4 (t): |
||
6199 | 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList' |
||
6200 | t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]} |
||
6201 | |||
6202 | def p_ComponentTypeLists_5 (t): |
||
6203 | 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList' |
||
6204 | t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]} |
||
6205 | |||
6206 | def p_ComponentTypeLists_6 (t): |
||
6207 | 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker' |
||
6208 | t[0] = {'elt_list' : [], 'ext_list' : []} |
||
6209 | |||
6210 | def p_ComponentTypeLists_7 (t): |
||
6211 | 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker' |
||
6212 | t[0] = {'elt_list' : [], 'ext_list' : t[2]} |
||
6213 | |||
6214 | def p_ExtensionEndMarker (t): |
||
6215 | 'ExtensionEndMarker : COMMA ELLIPSIS' |
||
6216 | pass |
||
6217 | |||
6218 | def p_ExtensionAdditionList_1 (t): |
||
6219 | 'ExtensionAdditionList : COMMA ExtensionAddition' |
||
6220 | t[0] = [t[2]] |
||
6221 | |||
6222 | def p_ExtensionAdditionList_2 (t): |
||
6223 | 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition' |
||
6224 | t[0] = t[1] + [t[3]] |
||
6225 | |||
6226 | def p_ExtensionAddition_1 (t): |
||
6227 | 'ExtensionAddition : ExtensionAdditionGroup' |
||
6228 | t[0] = Node ('elt_type', val = t[1], optional = 0) |
||
6229 | |||
6230 | def p_ExtensionAddition_2 (t): |
||
6231 | 'ExtensionAddition : ComponentType' |
||
6232 | t[0] = t[1] |
||
6233 | |||
6234 | def p_ExtensionAdditionGroup (t): |
||
6235 | 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK' |
||
6236 | t[0] = ExtensionAdditionGroup (ver = t[2], elt_list = t[3]) |
||
6237 | |||
6238 | def p_VersionNumber_1 (t): |
||
6239 | 'VersionNumber : ' |
||
6240 | |||
6241 | def p_VersionNumber_2 (t): |
||
6242 | 'VersionNumber : NUMBER COLON' |
||
6243 | t[0] = t[1] |
||
6244 | |||
6245 | def p_ComponentTypeList_1 (t): |
||
6246 | 'ComponentTypeList : ComponentType' |
||
6247 | t[0] = [t[1]] |
||
6248 | |||
6249 | def p_ComponentTypeList_2 (t): |
||
6250 | 'ComponentTypeList : ComponentTypeList COMMA ComponentType' |
||
6251 | t[0] = t[1] + [t[3]] |
||
6252 | |||
6253 | def p_ComponentType_1 (t): |
||
6254 | 'ComponentType : NamedType' |
||
6255 | t[0] = Node ('elt_type', val = t[1], optional = 0) |
||
6256 | |||
6257 | def p_ComponentType_2 (t): |
||
6258 | 'ComponentType : NamedType OPTIONAL' |
||
6259 | t[0] = Node ('elt_type', val = t[1], optional = 1) |
||
6260 | |||
6261 | def p_ComponentType_3 (t): |
||
6262 | 'ComponentType : NamedType DEFAULT DefaultValue' |
||
6263 | t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3]) |
||
6264 | |||
6265 | def p_ComponentType_4 (t): |
||
6266 | 'ComponentType : COMPONENTS OF Type' |
||
6267 | t[0] = Node ('components_of', typ = t[3]) |
||
6268 | |||
6269 | def p_DefaultValue_1 (t): |
||
6270 | '''DefaultValue : ReferencedValue |
||
6271 | | BooleanValue |
||
6272 | | ChoiceValue |
||
6273 | | IntegerValue |
||
6274 | | RealValue |
||
6275 | | hex_string |
||
6276 | | binary_string |
||
6277 | | char_string |
||
6278 | | ObjectClassFieldValue''' |
||
6279 | t[0] = t[1] |
||
6280 | |||
6281 | def p_DefaultValue_2 (t): |
||
6282 | 'DefaultValue : lbraceignore rbraceignore' |
||
6283 | t[0] = '' |
||
6284 | |||
6285 | # 24.17 |
||
6286 | def p_SequenceValue_1 (t): |
||
6287 | 'SequenceValue : LBRACE RBRACE' |
||
6288 | t[0] = [] |
||
6289 | |||
6290 | |||
6291 | #def p_SequenceValue_2 (t): |
||
6292 | # 'SequenceValue : LBRACE ComponentValueList RBRACE' |
||
6293 | # t[0] = t[2] |
||
6294 | |||
6295 | #def p_ComponentValueList_1 (t): |
||
6296 | # 'ComponentValueList : NamedValue' |
||
6297 | # t[0] = [t[1]] |
||
6298 | |||
6299 | #def p_ComponentValueList_2 (t): |
||
6300 | # 'ComponentValueList : ComponentValueList COMMA NamedValue' |
||
6301 | # t[0] = t[1] + [t[3]] |
||
6302 | |||
6303 | |||
6304 | # 25 Notation for sequence-of types ------------------------------------------- |
||
6305 | |||
6306 | # 25.1 |
||
6307 | def p_SequenceOfType (t): |
||
6308 | '''SequenceOfType : SEQUENCE OF Type |
||
6309 | | SEQUENCE OF NamedType''' |
||
6310 | t[0] = SequenceOfType (val = t[3], size_constr = None) |
||
6311 | |||
6312 | |||
6313 | # 26 Notation for set types --------------------------------------------------- |
||
6314 | |||
6315 | # 26.1 |
||
6316 | def p_SetType_1 (t): |
||
6317 | 'SetType : SET LBRACE RBRACE' |
||
6318 | t[0] = SetType (elt_list = []) |
||
6319 | |||
6320 | def p_SetType_2 (t): |
||
6321 | 'SetType : SET LBRACE ComponentTypeLists RBRACE' |
||
6322 | t[0] = SetType (elt_list = t[3]['elt_list']) |
||
6323 | if 'ext_list' in t[3]: |
||
6324 | t[0].ext_list = t[3]['ext_list'] |
||
6325 | if 'elt_list2' in t[3]: |
||
6326 | t[0].elt_list2 = t[3]['elt_list2'] |
||
6327 | |||
6328 | |||
6329 | # 27 Notation for set-of types ------------------------------------------------ |
||
6330 | |||
6331 | # 27.1 |
||
6332 | def p_SetOfType (t): |
||
6333 | '''SetOfType : SET OF Type |
||
6334 | | SET OF NamedType''' |
||
6335 | t[0] = SetOfType (val = t[3]) |
||
6336 | |||
6337 | # 28 Notation for choice types ------------------------------------------------ |
||
6338 | |||
6339 | # 28.1 |
||
6340 | def p_ChoiceType (t): |
||
6341 | 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE' |
||
6342 | if 'ext_list' in t[3]: |
||
6343 | t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list']) |
||
6344 | else: |
||
6345 | t[0] = ChoiceType (elt_list = t[3]['elt_list']) |
||
6346 | |||
6347 | def p_AlternativeTypeLists_1 (t): |
||
6348 | 'AlternativeTypeLists : AlternativeTypeList' |
||
6349 | t[0] = {'elt_list' : t[1]} |
||
6350 | |||
6351 | def p_AlternativeTypeLists_2 (t): |
||
6352 | 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker' |
||
6353 | t[0] = {'elt_list' : t[1], 'ext_list' : t[4]} |
||
6354 | |||
6355 | def p_ExtensionAdditionAlternatives_1 (t): |
||
6356 | 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList' |
||
6357 | t[0] = t[1] |
||
6358 | |||
6359 | def p_ExtensionAdditionAlternatives_2 (t): |
||
6360 | 'ExtensionAdditionAlternatives : ' |
||
6361 | t[0] = [] |
||
6362 | |||
6363 | def p_ExtensionAdditionAlternativesList_1 (t): |
||
6364 | 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative' |
||
6365 | t[0] = t[2] |
||
6366 | |||
6367 | def p_ExtensionAdditionAlternativesList_2 (t): |
||
6368 | 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative' |
||
6369 | t[0] = t[1] + t[3] |
||
6370 | |||
6371 | def p_ExtensionAdditionAlternative_1 (t): |
||
6372 | 'ExtensionAdditionAlternative : NamedType' |
||
6373 | t[0] = [t[1]] |
||
6374 | |||
6375 | def p_ExtensionAdditionAlternative_2 (t): |
||
6376 | 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup' |
||
6377 | t[0] = t[1] |
||
6378 | |||
6379 | def p_ExtensionAdditionAlternativesGroup (t): |
||
6380 | 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK' |
||
6381 | t[0] = t[3] |
||
6382 | |||
6383 | def p_AlternativeTypeList_1 (t): |
||
6384 | 'AlternativeTypeList : NamedType' |
||
6385 | t[0] = [t[1]] |
||
6386 | |||
6387 | def p_AlternativeTypeList_2 (t): |
||
6388 | 'AlternativeTypeList : AlternativeTypeList COMMA NamedType' |
||
6389 | t[0] = t[1] + [t[3]] |
||
6390 | |||
6391 | # 28.10 |
||
6392 | def p_ChoiceValue_1 (t): |
||
6393 | '''ChoiceValue : identifier COLON Value |
||
6394 | | identifier COLON NullValue ''' |
||
6395 | val = t[3] |
||
6396 | if not isinstance(val, Value): |
||
6397 | val = Value(val=val) |
||
6398 | t[0] = ChoiceValue (choice = t[1], val = val) |
||
6399 | |||
6400 | # 29 Notation for selection types |
||
6401 | |||
6402 | # 29.1 |
||
6403 | def p_SelectionType (t): # |
||
6404 | 'SelectionType : identifier LT Type' |
||
6405 | t[0] = SelectionType (typ = t[3], sel = t[1]) |
||
6406 | |||
6407 | # 30 Notation for tagged types ------------------------------------------------ |
||
6408 | |||
6409 | # 30.1 |
||
6410 | def p_TaggedType_1 (t): |
||
6411 | 'TaggedType : Tag Type' |
||
6412 | t[1].mode = 'default' |
||
6413 | t[0] = t[2] |
||
6414 | t[0].AddTag(t[1]) |
||
6415 | |||
6416 | def p_TaggedType_2 (t): |
||
6417 | '''TaggedType : Tag IMPLICIT Type |
||
6418 | | Tag EXPLICIT Type''' |
||
6419 | t[1].mode = t[2] |
||
6420 | t[0] = t[3] |
||
6421 | t[0].AddTag(t[1]) |
||
6422 | |||
6423 | def p_Tag (t): |
||
6424 | 'Tag : LBRACK Class ClassNumber RBRACK' |
||
6425 | t[0] = Tag(cls = t[2], num = t[3]) |
||
6426 | |||
6427 | def p_ClassNumber_1 (t): |
||
6428 | 'ClassNumber : number' |
||
6429 | t[0] = t[1] |
||
6430 | |||
6431 | def p_ClassNumber_2 (t): |
||
6432 | 'ClassNumber : DefinedValue' |
||
6433 | t[0] = t[1] |
||
6434 | |||
6435 | def p_Class_1 (t): |
||
6436 | '''Class : UNIVERSAL |
||
6437 | | APPLICATION |
||
6438 | | PRIVATE''' |
||
6439 | t[0] = t[1] |
||
6440 | |||
6441 | def p_Class_2 (t): |
||
6442 | 'Class :' |
||
6443 | t[0] = 'CONTEXT' |
||
6444 | |||
6445 | |||
6446 | # 31 Notation for the object identifier type ---------------------------------- |
||
6447 | |||
6448 | # 31.1 |
||
6449 | def p_ObjectIdentifierType (t): |
||
6450 | 'ObjectIdentifierType : OBJECT IDENTIFIER' |
||
6451 | t[0] = ObjectIdentifierType() |
||
6452 | |||
6453 | # 31.3 |
||
6454 | def p_ObjectIdentifierValue (t): |
||
6455 | 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE' |
||
6456 | t[0] = ObjectIdentifierValue (comp_list=t[2]) |
||
6457 | |||
6458 | def p_oid_comp_list_1 (t): |
||
6459 | 'oid_comp_list : oid_comp_list ObjIdComponents' |
||
6460 | t[0] = t[1] + [t[2]] |
||
6461 | |||
6462 | def p_oid_comp_list_2 (t): |
||
6463 | 'oid_comp_list : ObjIdComponents' |
||
6464 | t[0] = [t[1]] |
||
6465 | |||
6466 | def p_ObjIdComponents (t): |
||
6467 | '''ObjIdComponents : NameForm |
||
6468 | | NumberForm |
||
6469 | | NameAndNumberForm''' |
||
6470 | t[0] = t[1] |
||
6471 | |||
6472 | def p_NameForm (t): |
||
6473 | '''NameForm : LCASE_IDENT |
||
6474 | | LCASE_IDENT_ASSIGNED''' |
||
6475 | t [0] = t[1] |
||
6476 | |||
6477 | def p_NumberForm (t): |
||
6478 | '''NumberForm : NUMBER''' |
||
6479 | # | DefinedValue''' |
||
6480 | t [0] = t[1] |
||
6481 | |||
6482 | def p_NameAndNumberForm (t): |
||
6483 | '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN |
||
6484 | | LCASE_IDENT LPAREN NumberForm RPAREN''' |
||
6485 | t[0] = Node('name_and_number', ident = t[1], number = t[3]) |
||
6486 | |||
6487 | # 32 Notation for the relative object identifier type ------------------------- |
||
6488 | |||
6489 | # 32.1 |
||
6490 | def p_RelativeOIDType (t): |
||
6491 | 'RelativeOIDType : RELATIVE_OID' |
||
6492 | t[0] = RelativeOIDType() |
||
6493 | |||
6494 | # 33 Notation for the embedded-pdv type --------------------------------------- |
||
6495 | |||
6496 | # 33.1 |
||
6497 | def p_EmbeddedPDVType (t): |
||
6498 | 'EmbeddedPDVType : EMBEDDED PDV' |
||
6499 | t[0] = EmbeddedPDVType() |
||
6500 | |||
6501 | # 34 Notation for the external type ------------------------------------------- |
||
6502 | |||
6503 | # 34.1 |
||
6504 | def p_ExternalType (t): |
||
6505 | 'ExternalType : EXTERNAL' |
||
6506 | t[0] = ExternalType() |
||
6507 | |||
6508 | # 36 Notation for character string types -------------------------------------- |
||
6509 | |||
6510 | # 36.1 |
||
6511 | def p_CharacterStringType (t): |
||
6512 | '''CharacterStringType : RestrictedCharacterStringType |
||
6513 | | UnrestrictedCharacterStringType''' |
||
6514 | t[0] = t[1] |
||
6515 | |||
6516 | |||
6517 | # 37 Definition of restricted character string types -------------------------- |
||
6518 | |||
6519 | def p_RestrictedCharacterStringType_1 (t): |
||
6520 | 'RestrictedCharacterStringType : BMPString' |
||
6521 | t[0] = BMPStringType () |
||
6522 | def p_RestrictedCharacterStringType_2 (t): |
||
6523 | 'RestrictedCharacterStringType : GeneralString' |
||
6524 | t[0] = GeneralStringType () |
||
6525 | def p_RestrictedCharacterStringType_3 (t): |
||
6526 | 'RestrictedCharacterStringType : GraphicString' |
||
6527 | t[0] = GraphicStringType () |
||
6528 | def p_RestrictedCharacterStringType_4 (t): |
||
6529 | 'RestrictedCharacterStringType : IA5String' |
||
6530 | t[0] = IA5StringType () |
||
6531 | def p_RestrictedCharacterStringType_5 (t): |
||
6532 | 'RestrictedCharacterStringType : ISO646String' |
||
6533 | t[0] = ISO646StringType () |
||
6534 | def p_RestrictedCharacterStringType_6 (t): |
||
6535 | 'RestrictedCharacterStringType : NumericString' |
||
6536 | t[0] = NumericStringType () |
||
6537 | def p_RestrictedCharacterStringType_7 (t): |
||
6538 | 'RestrictedCharacterStringType : PrintableString' |
||
6539 | t[0] = PrintableStringType () |
||
6540 | def p_RestrictedCharacterStringType_8 (t): |
||
6541 | 'RestrictedCharacterStringType : TeletexString' |
||
6542 | t[0] = TeletexStringType () |
||
6543 | def p_RestrictedCharacterStringType_9 (t): |
||
6544 | 'RestrictedCharacterStringType : T61String' |
||
6545 | t[0] = T61StringType () |
||
6546 | def p_RestrictedCharacterStringType_10 (t): |
||
6547 | 'RestrictedCharacterStringType : UniversalString' |
||
6548 | t[0] = UniversalStringType () |
||
6549 | def p_RestrictedCharacterStringType_11 (t): |
||
6550 | 'RestrictedCharacterStringType : UTF8String' |
||
6551 | t[0] = UTF8StringType () |
||
6552 | def p_RestrictedCharacterStringType_12 (t): |
||
6553 | 'RestrictedCharacterStringType : VideotexString' |
||
6554 | t[0] = VideotexStringType () |
||
6555 | def p_RestrictedCharacterStringType_13 (t): |
||
6556 | 'RestrictedCharacterStringType : VisibleString' |
||
6557 | t[0] = VisibleStringType () |
||
6558 | |||
6559 | |||
6560 | # 40 Definition of unrestricted character string types ------------------------ |
||
6561 | |||
6562 | # 40.1 |
||
6563 | def p_UnrestrictedCharacterStringType (t): |
||
6564 | 'UnrestrictedCharacterStringType : CHARACTER STRING' |
||
6565 | t[0] = UnrestrictedCharacterStringType () |
||
6566 | |||
6567 | |||
6568 | # 41 Notation for types defined in clauses 42 to 44 --------------------------- |
||
6569 | |||
6570 | # 42 Generalized time --------------------------------------------------------- |
||
6571 | |||
6572 | def p_UsefulType_1 (t): |
||
6573 | 'UsefulType : GeneralizedTime' |
||
6574 | t[0] = GeneralizedTime() |
||
6575 | |||
6576 | # 43 Universal time ----------------------------------------------------------- |
||
6577 | |||
6578 | def p_UsefulType_2 (t): |
||
6579 | 'UsefulType : UTCTime' |
||
6580 | t[0] = UTCTime() |
||
6581 | |||
6582 | # 44 The object descriptor type ----------------------------------------------- |
||
6583 | |||
6584 | def p_UsefulType_3 (t): |
||
6585 | 'UsefulType : ObjectDescriptor' |
||
6586 | t[0] = ObjectDescriptor() |
||
6587 | |||
6588 | |||
6589 | # 45 Constrained types -------------------------------------------------------- |
||
6590 | |||
6591 | # 45.1 |
||
6592 | def p_ConstrainedType_1 (t): |
||
6593 | 'ConstrainedType : Type Constraint' |
||
6594 | t[0] = t[1] |
||
6595 | t[0].AddConstraint(t[2]) |
||
6596 | |||
6597 | def p_ConstrainedType_2 (t): |
||
6598 | 'ConstrainedType : TypeWithConstraint' |
||
6599 | t[0] = t[1] |
||
6600 | |||
6601 | # 45.5 |
||
6602 | def p_TypeWithConstraint_1 (t): |
||
6603 | '''TypeWithConstraint : SET Constraint OF Type |
||
6604 | | SET SizeConstraint OF Type''' |
||
6605 | t[0] = SetOfType (val = t[4], constr = t[2]) |
||
6606 | |||
6607 | def p_TypeWithConstraint_2 (t): |
||
6608 | '''TypeWithConstraint : SEQUENCE Constraint OF Type |
||
6609 | | SEQUENCE SizeConstraint OF Type''' |
||
6610 | t[0] = SequenceOfType (val = t[4], constr = t[2]) |
||
6611 | |||
6612 | def p_TypeWithConstraint_3 (t): |
||
6613 | '''TypeWithConstraint : SET Constraint OF NamedType |
||
6614 | | SET SizeConstraint OF NamedType''' |
||
6615 | t[0] = SetOfType (val = t[4], constr = t[2]) |
||
6616 | |||
6617 | def p_TypeWithConstraint_4 (t): |
||
6618 | '''TypeWithConstraint : SEQUENCE Constraint OF NamedType |
||
6619 | | SEQUENCE SizeConstraint OF NamedType''' |
||
6620 | t[0] = SequenceOfType (val = t[4], constr = t[2]) |
||
6621 | |||
6622 | # 45.6 |
||
6623 | # 45.7 |
||
6624 | def p_Constraint (t): |
||
6625 | 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN' |
||
6626 | t[0] = t[2] |
||
6627 | |||
6628 | def p_ConstraintSpec (t): |
||
6629 | '''ConstraintSpec : ElementSetSpecs |
||
6630 | | GeneralConstraint''' |
||
6631 | t[0] = t[1] |
||
6632 | |||
6633 | # 46 Element set specification ------------------------------------------------ |
||
6634 | |||
6635 | # 46.1 |
||
6636 | def p_ElementSetSpecs_1 (t): |
||
6637 | 'ElementSetSpecs : RootElementSetSpec' |
||
6638 | t[0] = t[1] |
||
6639 | |||
6640 | def p_ElementSetSpecs_2 (t): |
||
6641 | 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS' |
||
6642 | t[0] = t[1] |
||
6643 | t[0].ext = True |
||
6644 | |||
6645 | def p_ElementSetSpecs_3 (t): |
||
6646 | 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec' |
||
6647 | t[0] = t[1] |
||
6648 | t[0].ext = True |
||
6649 | |||
6650 | def p_RootElementSetSpec (t): |
||
6651 | 'RootElementSetSpec : ElementSetSpec' |
||
6652 | t[0] = t[1] |
||
6653 | |||
6654 | def p_AdditionalElementSetSpec (t): |
||
6655 | 'AdditionalElementSetSpec : ElementSetSpec' |
||
6656 | t[0] = t[1] |
||
6657 | |||
6658 | def p_ElementSetSpec (t): |
||
6659 | 'ElementSetSpec : Unions' |
||
6660 | t[0] = t[1] |
||
6661 | |||
6662 | def p_Unions_1 (t): |
||
6663 | 'Unions : Intersections' |
||
6664 | t[0] = t[1] |
||
6665 | |||
6666 | def p_Unions_2 (t): |
||
6667 | 'Unions : UElems UnionMark Intersections' |
||
6668 | t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]]) |
||
6669 | |||
6670 | def p_UElems (t): |
||
6671 | 'UElems : Unions' |
||
6672 | t[0] = t[1] |
||
6673 | |||
6674 | def p_Intersections_1 (t): |
||
6675 | 'Intersections : IntersectionElements' |
||
6676 | t[0] = t[1] |
||
6677 | |||
6678 | def p_Intersections_2 (t): |
||
6679 | 'Intersections : IElems IntersectionMark IntersectionElements' |
||
6680 | t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]]) |
||
6681 | |||
6682 | def p_IElems (t): |
||
6683 | 'IElems : Intersections' |
||
6684 | t[0] = t[1] |
||
6685 | |||
6686 | def p_IntersectionElements (t): |
||
6687 | 'IntersectionElements : Elements' |
||
6688 | t[0] = t[1] |
||
6689 | |||
6690 | def p_UnionMark (t): |
||
6691 | '''UnionMark : BAR |
||
6692 | | UNION''' |
||
6693 | |||
6694 | def p_IntersectionMark (t): |
||
6695 | '''IntersectionMark : CIRCUMFLEX |
||
6696 | | INTERSECTION''' |
||
6697 | |||
6698 | # 46.5 |
||
6699 | def p_Elements_1 (t): |
||
6700 | 'Elements : SubtypeElements' |
||
6701 | t[0] = t[1] |
||
6702 | |||
6703 | def p_Elements_2 (t): |
||
6704 | 'Elements : LPAREN ElementSetSpec RPAREN' |
||
6705 | t[0] = t[2] |
||
6706 | |||
6707 | # 47 Subtype elements --------------------------------------------------------- |
||
6708 | |||
6709 | # 47.1 General |
||
6710 | def p_SubtypeElements (t): |
||
6711 | '''SubtypeElements : SingleValue |
||
6712 | | ContainedSubtype |
||
6713 | | ValueRange |
||
6714 | | PermittedAlphabet |
||
6715 | | SizeConstraint |
||
6716 | | TypeConstraint |
||
6717 | | InnerTypeConstraints |
||
6718 | | PatternConstraint''' |
||
6719 | t[0] = t[1] |
||
6720 | |||
6721 | # 47.2 Single value |
||
6722 | # 47.2.1 |
||
6723 | def p_SingleValue (t): |
||
6724 | 'SingleValue : Value' |
||
6725 | t[0] = Constraint(type = 'SingleValue', subtype = t[1]) |
||
6726 | |||
6727 | # 47.3 Contained subtype |
||
6728 | # 47.3.1 |
||
6729 | def p_ContainedSubtype (t): |
||
6730 | 'ContainedSubtype : Includes Type' |
||
6731 | t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2]) |
||
6732 | |||
6733 | def p_Includes (t): |
||
6734 | '''Includes : INCLUDES |
||
6735 | | ''' |
||
6736 | |||
6737 | # 47.4 Value range |
||
6738 | # 47.4.1 |
||
6739 | def p_ValueRange (t): |
||
6740 | 'ValueRange : LowerEndpoint RANGE UpperEndpoint' |
||
6741 | t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]]) |
||
6742 | |||
6743 | # 47.4.3 |
||
6744 | def p_LowerEndpoint_1 (t): |
||
6745 | 'LowerEndpoint : LowerEndValue' |
||
6746 | t[0] = t[1] |
||
6747 | |||
6748 | def p_LowerEndpoint_2 (t): |
||
6749 | 'LowerEndpoint : LowerEndValue LT' |
||
6750 | t[0] = t[1] # but not inclusive range |
||
6751 | |||
6752 | def p_UpperEndpoint_1 (t): |
||
6753 | 'UpperEndpoint : UpperEndValue' |
||
6754 | t[0] = t[1] |
||
6755 | |||
6756 | def p_UpperEndpoint_2 (t): |
||
6757 | 'UpperEndpoint : LT UpperEndValue' |
||
6758 | t[0] = t[1] # but not inclusive range |
||
6759 | |||
6760 | # 47.4.4 |
||
6761 | def p_LowerEndValue (t): |
||
6762 | '''LowerEndValue : Value |
||
6763 | | MIN''' |
||
6764 | t[0] = t[1] # XXX |
||
6765 | |||
6766 | def p_UpperEndValue (t): |
||
6767 | '''UpperEndValue : Value |
||
6768 | | MAX''' |
||
6769 | t[0] = t[1] |
||
6770 | |||
6771 | # 47.5 Size constraint |
||
6772 | # 47.5.1 |
||
6773 | def p_SizeConstraint (t): |
||
6774 | 'SizeConstraint : SIZE Constraint' |
||
6775 | t[0] = Constraint (type = 'Size', subtype = t[2]) |
||
6776 | |||
6777 | # 47.6 Type constraint |
||
6778 | # 47.6.1 |
||
6779 | def p_TypeConstraint (t): |
||
6780 | 'TypeConstraint : Type' |
||
6781 | t[0] = Constraint (type = 'Type', subtype = t[1]) |
||
6782 | |||
6783 | # 47.7 Permitted alphabet |
||
6784 | # 47.7.1 |
||
6785 | def p_PermittedAlphabet (t): |
||
6786 | 'PermittedAlphabet : FROM Constraint' |
||
6787 | t[0] = Constraint (type = 'From', subtype = t[2]) |
||
6788 | |||
6789 | # 47.8 Inner subtyping |
||
6790 | # 47.8.1 |
||
6791 | def p_InnerTypeConstraints (t): |
||
6792 | '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint |
||
6793 | | WITH COMPONENTS MultipleTypeConstraints''' |
||
6794 | pass # ignore PER invisible constraint |
||
6795 | |||
6796 | # 47.8.3 |
||
6797 | def p_SingleTypeConstraint (t): |
||
6798 | 'SingleTypeConstraint : Constraint' |
||
6799 | t[0] = t[1] |
||
6800 | |||
6801 | # 47.8.4 |
||
6802 | def p_MultipleTypeConstraints (t): |
||
6803 | '''MultipleTypeConstraints : FullSpecification |
||
6804 | | PartialSpecification''' |
||
6805 | t[0] = t[1] |
||
6806 | |||
6807 | def p_FullSpecification (t): |
||
6808 | 'FullSpecification : LBRACE TypeConstraints RBRACE' |
||
6809 | t[0] = t[2] |
||
6810 | |||
6811 | def p_PartialSpecification (t): |
||
6812 | 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE' |
||
6813 | t[0] = t[4] |
||
6814 | |||
6815 | def p_TypeConstraints_1 (t): |
||
6816 | 'TypeConstraints : named_constraint' |
||
6817 | t [0] = [t[1]] |
||
6818 | |||
6819 | def p_TypeConstraints_2 (t): |
||
6820 | 'TypeConstraints : TypeConstraints COMMA named_constraint' |
||
6821 | t[0] = t[1] + [t[3]] |
||
6822 | |||
6823 | def p_named_constraint_1 (t): |
||
6824 | 'named_constraint : identifier constraint' |
||
6825 | return Node ('named_constraint', ident = t[1], constr = t[2]) |
||
6826 | |||
6827 | def p_named_constraint_2 (t): |
||
6828 | 'named_constraint : constraint' |
||
6829 | return Node ('named_constraint', constr = t[1]) |
||
6830 | |||
6831 | def p_constraint (t): |
||
6832 | 'constraint : value_constraint presence_constraint' |
||
6833 | t[0] = Node ('constraint', value = t[1], presence = t[2]) |
||
6834 | |||
6835 | def p_value_constraint_1 (t): |
||
6836 | 'value_constraint : Constraint' |
||
6837 | t[0] = t[1] |
||
6838 | |||
6839 | def p_value_constraint_2 (t): |
||
6840 | 'value_constraint : ' |
||
6841 | pass |
||
6842 | |||
6843 | def p_presence_constraint_1 (t): |
||
6844 | '''presence_constraint : PRESENT |
||
6845 | | ABSENT |
||
6846 | | OPTIONAL''' |
||
6847 | t[0] = t[1] |
||
6848 | |||
6849 | def p_presence_constraint_2 (t): |
||
6850 | '''presence_constraint : ''' |
||
6851 | pass |
||
6852 | |||
6853 | # 47.9 Pattern constraint |
||
6854 | # 47.9.1 |
||
6855 | def p_PatternConstraint (t): |
||
6856 | 'PatternConstraint : PATTERN Value' |
||
6857 | t[0] = Constraint (type = 'Pattern', subtype = t[2]) |
||
6858 | |||
6859 | # 49 The exception identifier |
||
6860 | |||
6861 | # 49.4 |
||
6862 | def p_ExceptionSpec_1 (t): |
||
6863 | 'ExceptionSpec : EXCLAMATION ExceptionIdentification' |
||
6864 | pass |
||
6865 | |||
6866 | def p_ExceptionSpec_2 (t): |
||
6867 | 'ExceptionSpec : ' |
||
6868 | pass |
||
6869 | |||
6870 | def p_ExceptionIdentification (t): |
||
6871 | '''ExceptionIdentification : SignedNumber |
||
6872 | | DefinedValue |
||
6873 | | Type COLON Value ''' |
||
6874 | pass |
||
6875 | |||
6876 | # /*-----------------------------------------------------------------------*/ |
||
6877 | # /* Value Notation Productions */ |
||
6878 | # /*-----------------------------------------------------------------------*/ |
||
6879 | |||
6880 | |||
6881 | |||
6882 | def p_binary_string (t): |
||
6883 | 'binary_string : BSTRING' |
||
6884 | t[0] = BStringValue(val = t[1]) |
||
6885 | |||
6886 | def p_hex_string (t): |
||
6887 | 'hex_string : HSTRING' |
||
6888 | t[0] = HStringValue(val = t[1]) |
||
6889 | |||
6890 | def p_char_string (t): |
||
6891 | 'char_string : QSTRING' |
||
6892 | t[0] = t[1] |
||
6893 | |||
6894 | def p_number (t): |
||
6895 | 'number : NUMBER' |
||
6896 | t[0] = t[1] |
||
6897 | |||
6898 | |||
6899 | #--- ITU-T Recommendation X.208 ----------------------------------------------- |
||
6900 | |||
6901 | # 27 Notation for the any type ------------------------------------------------ |
||
6902 | |||
6903 | # 27.1 |
||
6904 | def p_AnyType (t): |
||
6905 | '''AnyType : ANY |
||
6906 | | ANY DEFINED BY identifier''' |
||
6907 | t[0] = AnyType() |
||
6908 | |||
6909 | #--- ITU-T Recommendation X.681 ----------------------------------------------- |
||
6910 | |||
6911 | # 7 ASN.1 lexical items ------------------------------------------------------- |
||
6912 | |||
6913 | # 7.1 Information object class references |
||
6914 | |||
6915 | def p_objectclassreference (t): |
||
6916 | 'objectclassreference : CLASS_IDENT' |
||
6917 | t[0] = Class_Ref(val=t[1]) |
||
6918 | |||
6919 | # 7.2 Information object references |
||
6920 | |||
6921 | def p_objectreference (t): |
||
6922 | 'objectreference : LCASE_IDENT' |
||
6923 | t[0] = t[1] |
||
6924 | |||
6925 | # 7.3 Information object set references |
||
6926 | |||
6927 | #def p_objectsetreference (t): |
||
6928 | # 'objectsetreference : UCASE_IDENT' |
||
6929 | # t[0] = t[1] |
||
6930 | |||
6931 | # 7.4 Type field references |
||
6932 | # ucasefieldreference |
||
6933 | # 7.5 Value field references |
||
6934 | # lcasefieldreference |
||
6935 | # 7.6 Value set field references |
||
6936 | # ucasefieldreference |
||
6937 | # 7.7 Object field references |
||
6938 | # lcasefieldreference |
||
6939 | # 7.8 Object set field references |
||
6940 | # ucasefieldreference |
||
6941 | |||
6942 | def p_ucasefieldreference (t): |
||
6943 | 'ucasefieldreference : AMPERSAND UCASE_IDENT' |
||
6944 | t[0] = '&' + t[2] |
||
6945 | |||
6946 | def p_lcasefieldreference (t): |
||
6947 | 'lcasefieldreference : AMPERSAND LCASE_IDENT' |
||
6948 | t[0] = '&' + t[2] |
||
6949 | |||
6950 | # 8 Referencing definitions |
||
6951 | |||
6952 | # 8.1 |
||
6953 | def p_DefinedObjectClass (t): |
||
6954 | '''DefinedObjectClass : objectclassreference |
||
6955 | | UsefulObjectClassReference''' |
||
6956 | t[0] = t[1] |
||
6957 | global obj_class |
||
6958 | obj_class = t[0].val |
||
6959 | |||
6960 | def p_DefinedObject (t): |
||
6961 | '''DefinedObject : objectreference''' |
||
6962 | t[0] = t[1] |
||
6963 | |||
6964 | # 8.4 |
||
6965 | def p_UsefulObjectClassReference (t): |
||
6966 | '''UsefulObjectClassReference : TYPE_IDENTIFIER |
||
6967 | | ABSTRACT_SYNTAX''' |
||
6968 | t[0] = Class_Ref(val=t[1]) |
||
6969 | |||
6970 | # 9 Information object class definition and assignment |
||
6971 | |||
6972 | # 9.1 |
||
6973 | def p_ObjectClassAssignment (t): |
||
6974 | '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass |
||
6975 | | UCASE_IDENT ASSIGNMENT ObjectClass''' |
||
6976 | t[0] = t[3] |
||
6977 | t[0].SetName(t[1]) |
||
6978 | if isinstance(t[0], ObjectClassDefn): |
||
6979 | t[0].reg_types() |
||
6980 | |||
6981 | # 9.2 |
||
6982 | def p_ObjectClass (t): |
||
6983 | '''ObjectClass : DefinedObjectClass |
||
6984 | | ObjectClassDefn |
||
6985 | | ParameterizedObjectClass ''' |
||
6986 | t[0] = t[1] |
||
6987 | |||
6988 | # 9.3 |
||
6989 | def p_ObjectClassDefn (t): |
||
6990 | '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE |
||
6991 | | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec''' |
||
6992 | t[0] = ObjectClassDefn(fields = t[3]) |
||
6993 | |||
6994 | def p_FieldSpecs_1 (t): |
||
6995 | 'FieldSpecs : FieldSpec' |
||
6996 | t[0] = [t[1]] |
||
6997 | |||
6998 | def p_FieldSpecs_2 (t): |
||
6999 | 'FieldSpecs : FieldSpecs COMMA FieldSpec' |
||
7000 | t[0] = t[1] + [t[3]] |
||
7001 | |||
7002 | def p_WithSyntaxSpec (t): |
||
7003 | 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore' |
||
7004 | t[0] = None |
||
7005 | |||
7006 | # 9.4 |
||
7007 | def p_FieldSpec (t): |
||
7008 | '''FieldSpec : TypeFieldSpec |
||
7009 | | FixedTypeValueFieldSpec |
||
7010 | | VariableTypeValueFieldSpec |
||
7011 | | FixedTypeValueSetFieldSpec |
||
7012 | | ObjectFieldSpec |
||
7013 | | ObjectSetFieldSpec ''' |
||
7014 | t[0] = t[1] |
||
7015 | |||
7016 | # 9.5 |
||
7017 | def p_TypeFieldSpec (t): |
||
7018 | '''TypeFieldSpec : ucasefieldreference |
||
7019 | | ucasefieldreference TypeOptionalitySpec ''' |
||
7020 | t[0] = TypeFieldSpec() |
||
7021 | t[0].SetName(t[1]) |
||
7022 | |||
7023 | def p_TypeOptionalitySpec_1 (t): |
||
7024 | 'TypeOptionalitySpec ::= OPTIONAL' |
||
7025 | pass |
||
7026 | |||
7027 | def p_TypeOptionalitySpec_2 (t): |
||
7028 | 'TypeOptionalitySpec ::= DEFAULT Type' |
||
7029 | pass |
||
7030 | |||
7031 | # 9.6 |
||
7032 | def p_FixedTypeValueFieldSpec (t): |
||
7033 | '''FixedTypeValueFieldSpec : lcasefieldreference Type |
||
7034 | | lcasefieldreference Type UNIQUE |
||
7035 | | lcasefieldreference Type ValueOptionalitySpec |
||
7036 | | lcasefieldreference Type UNIQUE ValueOptionalitySpec ''' |
||
7037 | t[0] = FixedTypeValueFieldSpec(typ = t[2]) |
||
7038 | t[0].SetName(t[1]) |
||
7039 | |||
7040 | def p_ValueOptionalitySpec_1 (t): |
||
7041 | 'ValueOptionalitySpec ::= OPTIONAL' |
||
7042 | pass |
||
7043 | |||
7044 | def p_ValueOptionalitySpec_2 (t): |
||
7045 | 'ValueOptionalitySpec ::= DEFAULT Value' |
||
7046 | pass |
||
7047 | |||
7048 | # 9.8 |
||
7049 | |||
7050 | def p_VariableTypeValueFieldSpec (t): |
||
7051 | '''VariableTypeValueFieldSpec : lcasefieldreference FieldName |
||
7052 | | lcasefieldreference FieldName ValueOptionalitySpec ''' |
||
7053 | t[0] = VariableTypeValueFieldSpec() |
||
7054 | t[0].SetName(t[1]) |
||
7055 | |||
7056 | # 9.9 |
||
7057 | def p_FixedTypeValueSetFieldSpec (t): |
||
7058 | '''FixedTypeValueSetFieldSpec : ucasefieldreference Type |
||
7059 | | ucasefieldreference Type ValueSetOptionalitySpec ''' |
||
7060 | t[0] = FixedTypeValueSetFieldSpec() |
||
7061 | t[0].SetName(t[1]) |
||
7062 | |||
7063 | def p_ValueSetOptionalitySpec_1 (t): |
||
7064 | 'ValueSetOptionalitySpec ::= OPTIONAL' |
||
7065 | pass |
||
7066 | |||
7067 | def p_ValueSetOptionalitySpec_2 (t): |
||
7068 | 'ValueSetOptionalitySpec ::= DEFAULT ValueSet' |
||
7069 | pass |
||
7070 | |||
7071 | # 9.11 |
||
7072 | def p_ObjectFieldSpec (t): |
||
7073 | '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass |
||
7074 | | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec ''' |
||
7075 | t[0] = ObjectFieldSpec(cls=t[2]) |
||
7076 | t[0].SetName(t[1]) |
||
7077 | global obj_class |
||
7078 | obj_class = None |
||
7079 | |||
7080 | def p_ObjectOptionalitySpec_1 (t): |
||
7081 | 'ObjectOptionalitySpec ::= OPTIONAL' |
||
7082 | pass |
||
7083 | |||
7084 | def p_ObjectOptionalitySpec_2 (t): |
||
7085 | 'ObjectOptionalitySpec ::= DEFAULT Object' |
||
7086 | pass |
||
7087 | |||
7088 | # 9.12 |
||
7089 | def p_ObjectSetFieldSpec (t): |
||
7090 | '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass |
||
7091 | | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec ''' |
||
7092 | t[0] = ObjectSetFieldSpec(cls=t[2]) |
||
7093 | t[0].SetName(t[1]) |
||
7094 | |||
7095 | def p_ObjectSetOptionalitySpec_1 (t): |
||
7096 | 'ObjectSetOptionalitySpec ::= OPTIONAL' |
||
7097 | pass |
||
7098 | |||
7099 | def p_ObjectSetOptionalitySpec_2 (t): |
||
7100 | 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet' |
||
7101 | pass |
||
7102 | |||
7103 | # 9.13 |
||
7104 | def p_PrimitiveFieldName (t): |
||
7105 | '''PrimitiveFieldName : ucasefieldreference |
||
7106 | | lcasefieldreference ''' |
||
7107 | t[0] = t[1] |
||
7108 | |||
7109 | # 9.13 |
||
7110 | def p_FieldName_1 (t): |
||
7111 | 'FieldName : PrimitiveFieldName' |
||
7112 | t[0] = t[1] |
||
7113 | |||
7114 | def p_FieldName_2 (t): |
||
7115 | 'FieldName : FieldName DOT PrimitiveFieldName' |
||
7116 | t[0] = t[1] + '.' + t[3] |
||
7117 | |||
7118 | # 11 Information object definition and assignment |
||
7119 | |||
7120 | # 11.1 |
||
7121 | def p_ObjectAssignment (t): |
||
7122 | 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object' |
||
7123 | t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4]) |
||
7124 | global obj_class |
||
7125 | obj_class = None |
||
7126 | |||
7127 | # 11.3 |
||
7128 | def p_Object (t): |
||
7129 | '''Object : DefinedObject |
||
7130 | | ObjectDefn |
||
7131 | | ParameterizedObject''' |
||
7132 | t[0] = t[1] |
||
7133 | |||
7134 | # 11.4 |
||
7135 | def p_ObjectDefn (t): |
||
7136 | 'ObjectDefn : lbraceobject bodyobject rbraceobject' |
||
7137 | t[0] = t[2] |
||
7138 | |||
7139 | # {...} block of object definition |
||
7140 | def p_lbraceobject(t): |
||
7141 | 'lbraceobject : braceobjectbegin LBRACE' |
||
7142 | t[0] = t[1] |
||
7143 | |||
7144 | def p_braceobjectbegin(t): |
||
7145 | 'braceobjectbegin : ' |
||
7146 | global lexer |
||
7147 | global obj_class |
||
7148 | if set_class_syntax(obj_class): |
||
7149 | state = 'INITIAL' |
||
7150 | else: |
||
7151 | lexer.level = 1 |
||
7152 | state = 'braceignore' |
||
7153 | lexer.push_state(state) |
||
7154 | |||
7155 | def p_rbraceobject(t): |
||
7156 | 'rbraceobject : braceobjectend RBRACE' |
||
7157 | t[0] = t[2] |
||
7158 | |||
7159 | def p_braceobjectend(t): |
||
7160 | 'braceobjectend : ' |
||
7161 | global lexer |
||
7162 | lexer.pop_state() |
||
7163 | set_class_syntax(None) |
||
7164 | |||
7165 | def p_bodyobject_1 (t): |
||
7166 | 'bodyobject : ' |
||
7167 | t[0] = { } |
||
7168 | |||
7169 | def p_bodyobject_2 (t): |
||
7170 | 'bodyobject : cls_syntax_list' |
||
7171 | t[0] = t[1] |
||
7172 | |||
7173 | def p_cls_syntax_list_1 (t): |
||
7174 | 'cls_syntax_list : cls_syntax_list cls_syntax' |
||
7175 | t[0] = t[1] |
||
7176 | t[0].update(t[2]) |
||
7177 | |||
7178 | def p_cls_syntax_list_2 (t): |
||
7179 | 'cls_syntax_list : cls_syntax' |
||
7180 | t[0] = t[1] |
||
7181 | |||
7182 | # X.681 |
||
7183 | def p_cls_syntax_1 (t): |
||
7184 | 'cls_syntax : Type IDENTIFIED BY Value' |
||
7185 | t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] } |
||
7186 | |||
7187 | def p_cls_syntax_2 (t): |
||
7188 | 'cls_syntax : HAS PROPERTY Value' |
||
7189 | t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] } |
||
7190 | |||
7191 | # X.880 |
||
7192 | def p_cls_syntax_3 (t): |
||
7193 | '''cls_syntax : ERRORS ObjectSet |
||
7194 | | LINKED ObjectSet |
||
7195 | | RETURN RESULT BooleanValue |
||
7196 | | SYNCHRONOUS BooleanValue |
||
7197 | | INVOKE PRIORITY Value |
||
7198 | | RESULT_PRIORITY Value |
||
7199 | | PRIORITY Value |
||
7200 | | ALWAYS RESPONDS BooleanValue |
||
7201 | | IDEMPOTENT BooleanValue ''' |
||
7202 | t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] } |
||
7203 | |||
7204 | def p_cls_syntax_4 (t): |
||
7205 | '''cls_syntax : ARGUMENT Type |
||
7206 | | RESULT Type |
||
7207 | | PARAMETER Type ''' |
||
7208 | t[0] = { get_class_fieled(t[1]) : t[2] } |
||
7209 | |||
7210 | def p_cls_syntax_5 (t): |
||
7211 | 'cls_syntax : CODE Value' |
||
7212 | fld = get_class_fieled(t[1]); |
||
7213 | t[0] = { fld : t[2] } |
||
7214 | if isinstance(t[2], ChoiceValue): |
||
7215 | fldt = fld + '.' + t[2].choice |
||
7216 | t[0][fldt] = t[2] |
||
7217 | |||
7218 | def p_cls_syntax_6 (t): |
||
7219 | '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue |
||
7220 | | RESULT Type OPTIONAL BooleanValue |
||
7221 | | PARAMETER Type OPTIONAL BooleanValue ''' |
||
7222 | t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] } |
||
7223 | |||
7224 | # 12 Information object set definition and assignment |
||
7225 | |||
7226 | # 12.1 |
||
7227 | def p_ObjectSetAssignment (t): |
||
7228 | 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet' |
||
7229 | t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4]) |
||
7230 | |||
7231 | # 12.3 |
||
7232 | def p_ObjectSet (t): |
||
7233 | 'ObjectSet : lbraceignore rbraceignore' |
||
7234 | t[0] = None |
||
7235 | |||
7236 | # 14 Notation for the object class field type --------------------------------- |
||
7237 | |||
7238 | # 14.1 |
||
7239 | def p_ObjectClassFieldType (t): |
||
7240 | 'ObjectClassFieldType : DefinedObjectClass DOT FieldName' |
||
7241 | t[0] = get_type_from_class(t[1], t[3]) |
||
7242 | |||
7243 | # 14.6 |
||
7244 | def p_ObjectClassFieldValue (t): |
||
7245 | '''ObjectClassFieldValue : OpenTypeFieldVal''' |
||
7246 | t[0] = t[1] |
||
7247 | |||
7248 | def p_OpenTypeFieldVal (t): |
||
7249 | '''OpenTypeFieldVal : Type COLON Value |
||
7250 | | NullType COLON NullValue''' |
||
7251 | t[0] = t[3] |
||
7252 | |||
7253 | |||
7254 | # 15 Information from objects ------------------------------------------------- |
||
7255 | |||
7256 | # 15.1 |
||
7257 | |||
7258 | def p_ValueFromObject (t): |
||
7259 | 'ValueFromObject : LCASE_IDENT DOT FieldName' |
||
7260 | t[0] = t[1] + '.' + t[3] |
||
7261 | |||
7262 | |||
7263 | # Annex C - The instance-of type ---------------------------------------------- |
||
7264 | |||
7265 | # C.2 |
||
7266 | def p_InstanceOfType (t): |
||
7267 | 'InstanceOfType : INSTANCE OF DefinedObjectClass' |
||
7268 | t[0] = InstanceOfType() |
||
7269 | |||
7270 | |||
7271 | # --- tables --- |
||
7272 | |||
7273 | useful_object_class_types = { |
||
7274 | # Annex A |
||
7275 | 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(), |
||
7276 | 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(), |
||
7277 | # Annex B |
||
7278 | 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(), |
||
7279 | 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(), |
||
7280 | 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(), |
||
7281 | } |
||
7282 | |||
7283 | object_class_types = { } |
||
7284 | |||
7285 | object_class_typerefs = { } |
||
7286 | |||
7287 | object_class_classrefs = { } |
||
7288 | |||
7289 | # dummy types |
||
7290 | class _VariableTypeValueFieldSpec (AnyType): |
||
7291 | pass |
||
7292 | |||
7293 | class _FixedTypeValueSetFieldSpec (AnyType): |
||
7294 | pass |
||
7295 | |||
7296 | class_types_creator = { |
||
7297 | 'BooleanType' : lambda : BooleanType(), |
||
7298 | 'IntegerType' : lambda : IntegerType(), |
||
7299 | 'ObjectIdentifierType' : lambda : ObjectIdentifierType(), |
||
7300 | 'OpenType' : lambda : OpenType(), |
||
7301 | # dummy types |
||
7302 | '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(), |
||
7303 | '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(), |
||
7304 | } |
||
7305 | |||
7306 | class_names = { } |
||
7307 | |||
7308 | x681_syntaxes = { |
||
7309 | 'TYPE-IDENTIFIER' : { |
||
7310 | ' ' : '&Type', |
||
7311 | 'IDENTIFIED' : 'IDENTIFIED', |
||
7312 | #'BY' : 'BY', |
||
7313 | 'IDENTIFIED BY' : '&id', |
||
7314 | }, |
||
7315 | 'ABSTRACT-SYNTAX' : { |
||
7316 | ' ' : '&Type', |
||
7317 | 'IDENTIFIED' : 'IDENTIFIED', |
||
7318 | #'BY' : 'BY', |
||
7319 | 'IDENTIFIED BY' : '&id', |
||
7320 | 'HAS' : 'HAS', |
||
7321 | 'PROPERTY' : 'PROPERTY', |
||
7322 | 'HAS PROPERTY' : '&property', |
||
7323 | }, |
||
7324 | } |
||
7325 | |||
7326 | class_syntaxes_enabled = { |
||
7327 | 'TYPE-IDENTIFIER' : True, |
||
7328 | 'ABSTRACT-SYNTAX' : True, |
||
7329 | } |
||
7330 | |||
7331 | class_syntaxes = { |
||
7332 | 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'], |
||
7333 | 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'], |
||
7334 | } |
||
7335 | |||
7336 | class_current_syntax = None |
||
7337 | |||
7338 | def get_syntax_tokens(syntaxes): |
||
7339 | tokens = { } |
||
7340 | for s in (syntaxes): |
||
7341 | for k in (list(syntaxes[s].keys())): |
||
7342 | if k.find(' ') < 0: |
||
7343 | tokens[k] = k |
||
7344 | tokens[k] = tokens[k].replace('-', '_') |
||
7345 | return list(tokens.values()) |
||
7346 | |||
7347 | tokens = tokens + get_syntax_tokens(x681_syntaxes) |
||
7348 | |||
7349 | def set_class_syntax(syntax): |
||
7350 | global class_syntaxes_enabled |
||
7351 | global class_current_syntax |
||
7352 | #print "set_class_syntax", syntax, class_current_syntax |
||
7353 | if class_syntaxes_enabled.get(syntax, False): |
||
7354 | class_current_syntax = syntax |
||
7355 | return True |
||
7356 | else: |
||
7357 | class_current_syntax = None |
||
7358 | return False |
||
7359 | |||
7360 | def is_class_syntax(name): |
||
7361 | global class_syntaxes |
||
7362 | global class_current_syntax |
||
7363 | #print "is_class_syntax", name, class_current_syntax |
||
7364 | if not class_current_syntax: |
||
7365 | return False |
||
7366 | return name in class_syntaxes[class_current_syntax] |
||
7367 | |||
7368 | def get_class_fieled(name): |
||
7369 | if not class_current_syntax: |
||
7370 | return None |
||
7371 | return class_syntaxes[class_current_syntax][name] |
||
7372 | |||
7373 | def is_class_ident(name): |
||
7374 | return name in class_names |
||
7375 | |||
7376 | def add_class_ident(name): |
||
7377 | #print "add_class_ident", name |
||
7378 | class_names[name] = name |
||
7379 | |||
7380 | def get_type_from_class(cls, fld): |
||
7381 | flds = fld.split('.') |
||
7382 | if (isinstance(cls, Class_Ref)): |
||
7383 | key = cls.val + '.' + flds[0] |
||
7384 | else: |
||
7385 | key = cls + '.' + flds[0] |
||
7386 | |||
7387 | if key in object_class_classrefs: |
||
7388 | return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:])) |
||
7389 | |||
7390 | if key in object_class_typerefs: |
||
7391 | return Type_Ref(val=object_class_typerefs[key]) |
||
7392 | |||
7393 | creator = lambda : AnyType() |
||
7394 | creator = useful_object_class_types.get(key, creator) |
||
7395 | creator = object_class_types.get(key, creator) |
||
7396 | return creator() |
||
7397 | |||
7398 | def set_type_to_class(cls, fld, pars): |
||
7399 | #print "set_type_to_class", cls, fld, pars |
||
7400 | key = cls + '.' + fld |
||
7401 | typename = 'OpenType' |
||
7402 | if (len(pars) > 0): |
||
7403 | typename = pars[0] |
||
7404 | else: |
||
7405 | pars.append(typename) |
||
7406 | typeref = None |
||
7407 | if (len(pars) > 1): |
||
7408 | if (isinstance(pars[1], Class_Ref)): |
||
7409 | pars[1] = pars[1].val |
||
7410 | typeref = pars[1] |
||
7411 | |||
7412 | msg = None |
||
7413 | if key in object_class_types: |
||
7414 | msg = object_class_types[key]().type |
||
7415 | if key in object_class_typerefs: |
||
7416 | msg = "TypeReference " + object_class_typerefs[key] |
||
7417 | if key in object_class_classrefs: |
||
7418 | msg = "ClassReference " + object_class_classrefs[key] |
||
7419 | |||
7420 | if msg == ' '.join(pars): |
||
7421 | msg = None |
||
7422 | |||
7423 | if msg: |
||
7424 | msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars)) |
||
7425 | msg1 = "Already defined as '%s'" % (msg) |
||
7426 | raise CompError(msg0 + msg1) |
||
7427 | |||
7428 | if (typename == 'ClassReference'): |
||
7429 | if not typeref: return False |
||
7430 | object_class_classrefs[key] = typeref |
||
7431 | return True |
||
7432 | |||
7433 | if (typename == 'TypeReference'): |
||
7434 | if not typeref: return False |
||
7435 | object_class_typerefs[key] = typeref |
||
7436 | return True |
||
7437 | |||
7438 | creator = class_types_creator.get(typename) |
||
7439 | if creator: |
||
7440 | object_class_types[key] = creator |
||
7441 | return True |
||
7442 | else: |
||
7443 | return False |
||
7444 | |||
7445 | def import_class_from_module(mod, cls): |
||
7446 | add_class_ident(cls) |
||
7447 | mcls = "$%s$%s" % (mod, cls) |
||
7448 | for k in list(object_class_classrefs.keys()): |
||
7449 | kk = k.split('.', 1) |
||
7450 | if kk[0] == mcls: |
||
7451 | object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k] |
||
7452 | for k in list(object_class_typerefs.keys()): |
||
7453 | kk = k.split('.', 1) |
||
7454 | if kk[0] == mcls: |
||
7455 | object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k] |
||
7456 | for k in list(object_class_types.keys()): |
||
7457 | kk = k.split('.', 1) |
||
7458 | if kk[0] == mcls: |
||
7459 | object_class_types[cls + '.' + kk[0]] = object_class_types[k] |
||
7460 | |||
7461 | #--- ITU-T Recommendation X.682 ----------------------------------------------- |
||
7462 | |||
7463 | # 8 General constraint specification ------------------------------------------ |
||
7464 | |||
7465 | # 8.1 |
||
7466 | def p_GeneralConstraint (t): |
||
7467 | '''GeneralConstraint : UserDefinedConstraint |
||
7468 | | TableConstraint |
||
7469 | | ContentsConstraint''' |
||
7470 | t[0] = t[1] |
||
7471 | |||
7472 | # 9 User-defined constraints -------------------------------------------------- |
||
7473 | |||
7474 | # 9.1 |
||
7475 | def p_UserDefinedConstraint (t): |
||
7476 | 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE' |
||
7477 | t[0] = Constraint(type = 'UserDefined', subtype = t[4]) |
||
7478 | |||
7479 | def p_UserDefinedConstraintParameterList_1 (t): |
||
7480 | 'UserDefinedConstraintParameterList : ' |
||
7481 | t[0] = [] |
||
7482 | |||
7483 | def p_UserDefinedConstraintParameterList_2 (t): |
||
7484 | 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter' |
||
7485 | t[0] = [t[1]] |
||
7486 | |||
7487 | def p_UserDefinedConstraintParameterList_3 (t): |
||
7488 | 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter' |
||
7489 | t[0] = t[1] + [t[3]] |
||
7490 | |||
7491 | # 9.3 |
||
7492 | def p_UserDefinedConstraintParameter (t): |
||
7493 | 'UserDefinedConstraintParameter : Type' |
||
7494 | t[0] = t[1] |
||
7495 | |||
7496 | # 10 Table constraints, including component relation constraints -------------- |
||
7497 | |||
7498 | # 10.3 |
||
7499 | def p_TableConstraint (t): |
||
7500 | '''TableConstraint : SimpleTableConstraint |
||
7501 | | ComponentRelationConstraint''' |
||
7502 | t[0] = Constraint(type = 'Table', subtype = t[1]) |
||
7503 | |||
7504 | def p_SimpleTableConstraint (t): |
||
7505 | 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE' |
||
7506 | t[0] = t[2] |
||
7507 | |||
7508 | # 10.7 |
||
7509 | def p_ComponentRelationConstraint (t): |
||
7510 | 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE' |
||
7511 | t[0] = t[2] + str(t[5]) |
||
7512 | |||
7513 | def p_AtNotations_1 (t): |
||
7514 | 'AtNotations : AtNotation' |
||
7515 | t[0] = [t[1]] |
||
7516 | |||
7517 | def p_AtNotations_2 (t): |
||
7518 | 'AtNotations : AtNotations COMMA AtNotation' |
||
7519 | t[0] = t[1] + [t[3]] |
||
7520 | |||
7521 | def p_AtNotation_1 (t): |
||
7522 | 'AtNotation : AT ComponentIdList' |
||
7523 | t[0] = '@' + t[2] |
||
7524 | |||
7525 | def p_AtNotation_2 (t): |
||
7526 | 'AtNotation : AT DOT Level ComponentIdList' |
||
7527 | t[0] = '@.' + t[3] + t[4] |
||
7528 | |||
7529 | def p_Level_1 (t): |
||
7530 | 'Level : DOT Level' |
||
7531 | t[0] = '.' + t[2] |
||
7532 | |||
7533 | def p_Level_2 (t): |
||
7534 | 'Level : ' |
||
7535 | t[0] = '' |
||
7536 | |||
7537 | def p_ComponentIdList_1 (t): |
||
7538 | 'ComponentIdList : LCASE_IDENT' |
||
7539 | t[0] = t[1] |
||
7540 | |||
7541 | def p_ComponentIdList_2 (t): |
||
7542 | 'ComponentIdList : ComponentIdList DOT LCASE_IDENT' |
||
7543 | t[0] = t[1] + '.' + t[3] |
||
7544 | |||
7545 | # 11 Contents constraints ----------------------------------------------------- |
||
7546 | |||
7547 | # 11.1 |
||
7548 | def p_ContentsConstraint (t): |
||
7549 | 'ContentsConstraint : CONTAINING type_ref' |
||
7550 | t[0] = Constraint(type = 'Contents', subtype = t[2]) |
||
7551 | |||
7552 | |||
7553 | #--- ITU-T Recommendation X.683 ----------------------------------------------- |
||
7554 | |||
7555 | # 8 Parameterized assignments ------------------------------------------------- |
||
7556 | |||
7557 | # 8.1 |
||
7558 | def p_ParameterizedAssignment (t): |
||
7559 | '''ParameterizedAssignment : ParameterizedTypeAssignment |
||
7560 | | ParameterizedObjectClassAssignment |
||
7561 | | ParameterizedObjectAssignment |
||
7562 | | ParameterizedObjectSetAssignment''' |
||
7563 | t[0] = t[1] |
||
7564 | |||
7565 | # 8.2 |
||
7566 | def p_ParameterizedTypeAssignment (t): |
||
7567 | 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type' |
||
7568 | t[0] = t[4] |
||
7569 | t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx') |
||
7570 | |||
7571 | def p_ParameterizedObjectClassAssignment (t): |
||
7572 | '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass |
||
7573 | | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass''' |
||
7574 | t[0] = t[4] |
||
7575 | t[0].SetName(t[1]) |
||
7576 | if isinstance(t[0], ObjectClassDefn): |
||
7577 | t[0].reg_types() |
||
7578 | |||
7579 | def p_ParameterizedObjectAssignment (t): |
||
7580 | 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object' |
||
7581 | t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5]) |
||
7582 | global obj_class |
||
7583 | obj_class = None |
||
7584 | |||
7585 | def p_ParameterizedObjectSetAssignment (t): |
||
7586 | 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet' |
||
7587 | t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5]) |
||
7588 | |||
7589 | # 8.3 |
||
7590 | def p_ParameterList (t): |
||
7591 | 'ParameterList : lbraceignore rbraceignore' |
||
7592 | |||
7593 | #def p_ParameterList (t): |
||
7594 | # 'ParameterList : LBRACE Parameters RBRACE' |
||
7595 | # t[0] = t[2] |
||
7596 | |||
7597 | #def p_Parameters_1 (t): |
||
7598 | # 'Parameters : Parameter' |
||
7599 | # t[0] = [t[1]] |
||
7600 | |||
7601 | #def p_Parameters_2 (t): |
||
7602 | # 'Parameters : Parameters COMMA Parameter' |
||
7603 | # t[0] = t[1] + [t[3]] |
||
7604 | |||
7605 | #def p_Parameter_1 (t): |
||
7606 | # 'Parameter : Type COLON Reference' |
||
7607 | # t[0] = [t[1], t[3]] |
||
7608 | |||
7609 | #def p_Parameter_2 (t): |
||
7610 | # 'Parameter : Reference' |
||
7611 | # t[0] = t[1] |
||
7612 | |||
7613 | |||
7614 | # 9 Referencing parameterized definitions ------------------------------------- |
||
7615 | |||
7616 | # 9.1 |
||
7617 | def p_ParameterizedReference (t): |
||
7618 | 'ParameterizedReference : Reference LBRACE RBRACE' |
||
7619 | t[0] = t[1] |
||
7620 | #t[0].val += 'xxx' |
||
7621 | |||
7622 | # 9.2 |
||
7623 | def p_ParameterizedType (t): |
||
7624 | 'ParameterizedType : type_ref ActualParameterList' |
||
7625 | t[0] = t[1] |
||
7626 | #t[0].val += 'xxx' |
||
7627 | |||
7628 | |||
7629 | def p_ParameterizedObjectClass (t): |
||
7630 | 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList' |
||
7631 | t[0] = t[1] |
||
7632 | #t[0].val += 'xxx' |
||
7633 | |||
7634 | def p_ParameterizedObject (t): |
||
7635 | 'ParameterizedObject : DefinedObject ActualParameterList' |
||
7636 | t[0] = t[1] |
||
7637 | #t[0].val += 'xxx' |
||
7638 | |||
7639 | # 9.5 |
||
7640 | def p_ActualParameterList (t): |
||
7641 | 'ActualParameterList : lbraceignore rbraceignore' |
||
7642 | |||
7643 | #def p_ActualParameterList (t): |
||
7644 | # 'ActualParameterList : LBRACE ActualParameters RBRACE' |
||
7645 | # t[0] = t[2] |
||
7646 | |||
7647 | #def p_ActualParameters_1 (t): |
||
7648 | # 'ActualParameters : ActualParameter' |
||
7649 | # t[0] = [t[1]] |
||
7650 | |||
7651 | #def p_ActualParameters_2 (t): |
||
7652 | # 'ActualParameters : ActualParameters COMMA ActualParameter' |
||
7653 | # t[0] = t[1] + [t[3]] |
||
7654 | |||
7655 | #def p_ActualParameter (t): |
||
7656 | # '''ActualParameter : Type |
||
7657 | # | Value''' |
||
7658 | # t[0] = t[1] |
||
7659 | |||
7660 | |||
7661 | #--- ITU-T Recommendation X.880 ----------------------------------------------- |
||
7662 | |||
7663 | x880_classes = { |
||
7664 | 'OPERATION' : { |
||
7665 | '&ArgumentType' : [], |
||
7666 | '&argumentTypeOptional' : [ 'BooleanType' ], |
||
7667 | '&returnResult' : [ 'BooleanType' ], |
||
7668 | '&ResultType' : [], |
||
7669 | '&resultTypeOptional' : [ 'BooleanType' ], |
||
7670 | '&Errors' : [ 'ClassReference', 'ERROR' ], |
||
7671 | '&Linked' : [ 'ClassReference', 'OPERATION' ], |
||
7672 | '&synchronous' : [ 'BooleanType' ], |
||
7673 | '&idempotent' : [ 'BooleanType' ], |
||
7674 | '&alwaysReturns' : [ 'BooleanType' ], |
||
7675 | '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ], |
||
7676 | '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ], |
||
7677 | '&operationCode' : [ 'TypeReference', 'Code' ], |
||
7678 | }, |
||
7679 | 'ERROR' : { |
||
7680 | '&ParameterType' : [], |
||
7681 | '¶meterTypeOptional' : [ 'BooleanType' ], |
||
7682 | '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ], |
||
7683 | '&errorCode' : [ 'TypeReference', 'Code' ], |
||
7684 | }, |
||
7685 | 'OPERATION-PACKAGE' : { |
||
7686 | '&Both' : [ 'ClassReference', 'OPERATION' ], |
||
7687 | '&Consumer' : [ 'ClassReference', 'OPERATION' ], |
||
7688 | '&Supplier' : [ 'ClassReference', 'OPERATION' ], |
||
7689 | '&id' : [ 'ObjectIdentifierType' ], |
||
7690 | }, |
||
7691 | 'CONNECTION-PACKAGE' : { |
||
7692 | '&bind' : [ 'ClassReference', 'OPERATION' ], |
||
7693 | '&unbind' : [ 'ClassReference', 'OPERATION' ], |
||
7694 | '&responderCanUnbind' : [ 'BooleanType' ], |
||
7695 | '&unbindCanFail' : [ 'BooleanType' ], |
||
7696 | '&id' : [ 'ObjectIdentifierType' ], |
||
7697 | }, |
||
7698 | 'CONTRACT' : { |
||
7699 | '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ], |
||
7700 | '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ], |
||
7701 | '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ], |
||
7702 | '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ], |
||
7703 | '&id' : [ 'ObjectIdentifierType' ], |
||
7704 | }, |
||
7705 | 'ROS-OBJECT-CLASS' : { |
||
7706 | '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ], |
||
7707 | '&Initiates' : [ 'ClassReference', 'CONTRACT' ], |
||
7708 | '&Responds' : [ 'ClassReference', 'CONTRACT' ], |
||
7709 | '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ], |
||
7710 | '&id' : [ 'ObjectIdentifierType' ], |
||
7711 | }, |
||
7712 | } |
||
7713 | |||
7714 | x880_syntaxes = { |
||
7715 | 'OPERATION' : { |
||
7716 | 'ARGUMENT' : '&ArgumentType', |
||
7717 | 'ARGUMENT OPTIONAL' : '&argumentTypeOptional', |
||
7718 | 'RESULT' : '&ResultType', |
||
7719 | 'RESULT OPTIONAL' : '&resultTypeOptional', |
||
7720 | 'RETURN' : 'RETURN', |
||
7721 | 'RETURN RESULT' : '&returnResult', |
||
7722 | 'ERRORS' : '&Errors', |
||
7723 | 'LINKED' : '&Linked', |
||
7724 | 'SYNCHRONOUS' : '&synchronous', |
||
7725 | 'IDEMPOTENT' : '&idempotent', |
||
7726 | 'ALWAYS' : 'ALWAYS', |
||
7727 | 'RESPONDS' : 'RESPONDS', |
||
7728 | 'ALWAYS RESPONDS' : '&alwaysReturns', |
||
7729 | 'INVOKE' : 'INVOKE', |
||
7730 | 'PRIORITY' : 'PRIORITY', |
||
7731 | 'INVOKE PRIORITY' : '&InvokePriority', |
||
7732 | 'RESULT-PRIORITY': '&ResultPriority', |
||
7733 | 'CODE' : '&operationCode', |
||
7734 | }, |
||
7735 | 'ERROR' : { |
||
7736 | 'PARAMETER' : '&ParameterType', |
||
7737 | 'PARAMETER OPTIONAL' : '¶meterTypeOptional', |
||
7738 | 'PRIORITY' : '&ErrorPriority', |
||
7739 | 'CODE' : '&errorCode', |
||
7740 | }, |
||
7741 | # 'OPERATION-PACKAGE' : { |
||
7742 | # }, |
||
7743 | # 'CONNECTION-PACKAGE' : { |
||
7744 | # }, |
||
7745 | # 'CONTRACT' : { |
||
7746 | # }, |
||
7747 | # 'ROS-OBJECT-CLASS' : { |
||
7748 | # }, |
||
7749 | } |
||
7750 | |||
7751 | def x880_module_begin(): |
||
7752 | #print "x880_module_begin()" |
||
7753 | for name in list(x880_classes.keys()): |
||
7754 | add_class_ident(name) |
||
7755 | |||
7756 | def x880_import(name): |
||
7757 | if name in x880_syntaxes: |
||
7758 | class_syntaxes_enabled[name] = True |
||
7759 | class_syntaxes[name] = x880_syntaxes[name] |
||
7760 | if name in x880_classes: |
||
7761 | add_class_ident(name) |
||
7762 | for f in (list(x880_classes[name].keys())): |
||
7763 | set_type_to_class(name, f, x880_classes[name][f]) |
||
7764 | |||
7765 | tokens = tokens + get_syntax_tokens(x880_syntaxes) |
||
7766 | |||
7767 | # {...} OID value |
||
7768 | #def p_lbrace_oid(t): |
||
7769 | # 'lbrace_oid : brace_oid_begin LBRACE' |
||
7770 | # t[0] = t[1] |
||
7771 | |||
7772 | #def p_brace_oid_begin(t): |
||
7773 | # 'brace_oid_begin : ' |
||
7774 | # global in_oid |
||
7775 | # in_oid = True |
||
7776 | |||
7777 | #def p_rbrace_oid(t): |
||
7778 | # 'rbrace_oid : brace_oid_end RBRACE' |
||
7779 | # t[0] = t[2] |
||
7780 | |||
7781 | #def p_brace_oid_end(t): |
||
7782 | # 'brace_oid_end : ' |
||
7783 | # global in_oid |
||
7784 | # in_oid = False |
||
7785 | |||
7786 | # {...} block to be ignored |
||
7787 | def p_lbraceignore(t): |
||
7788 | 'lbraceignore : braceignorebegin LBRACE' |
||
7789 | t[0] = t[1] |
||
7790 | |||
7791 | def p_braceignorebegin(t): |
||
7792 | 'braceignorebegin : ' |
||
7793 | global lexer |
||
7794 | lexer.level = 1 |
||
7795 | lexer.push_state('braceignore') |
||
7796 | |||
7797 | def p_rbraceignore(t): |
||
7798 | 'rbraceignore : braceignoreend RBRACE' |
||
7799 | t[0] = t[2] |
||
7800 | |||
7801 | def p_braceignoreend(t): |
||
7802 | 'braceignoreend : ' |
||
7803 | global lexer |
||
7804 | lexer.pop_state() |
||
7805 | |||
7806 | def p_error(t): |
||
7807 | global input_file |
||
7808 | raise ParseError(t, input_file) |
||
7809 | |||
7810 | def p_pyquote (t): |
||
7811 | '''pyquote : PYQUOTE''' |
||
7812 | t[0] = PyQuote (val = t[1]) |
||
7813 | |||
7814 | |||
7815 | def testlex (s): |
||
7816 | lexer.input (s) |
||
7817 | while True: |
||
7818 | token = lexer.token () |
||
7819 | if not token: |
||
7820 | break |
||
7821 | print(token) |
||
7822 | |||
7823 | |||
7824 | def do_module (ast, defined_dict): |
||
7825 | assert (ast.type == 'Module') |
||
7826 | ctx = Ctx (defined_dict) |
||
7827 | print(ast.to_python (ctx)) |
||
7828 | print(ctx.output_assignments ()) |
||
7829 | print(ctx.output_pyquotes ()) |
||
7830 | |||
7831 | def eth_do_module (ast, ectx): |
||
7832 | assert (ast.type == 'Module') |
||
7833 | if ectx.dbg('s'): print(ast.str_depth(0)) |
||
7834 | ast.to_eth(ectx) |
||
7835 | |||
7836 | def testyacc(s, fn, defined_dict): |
||
7837 | ast = yacc.parse(s, debug=0) |
||
7838 | time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) |
||
7839 | print("""#!/usr/bin/env python |
||
7840 | # Auto-generated from %s at %s |
||
7841 | from PyZ3950 import asn1""" % (fn, time_str)) |
||
7842 | for module in ast: |
||
7843 | eth_do_module (module, defined_dict) |
||
7844 | |||
7845 | |||
7846 | # Wireshark compiler |
||
7847 | def eth_usage(): |
||
7848 | print(""" |
||
7849 | asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ... |
||
7850 | -h|? : Usage |
||
7851 | -b : BER (default is PER) |
||
7852 | -u : Unaligned (default is aligned) |
||
7853 | -p proto : Protocol name (implies -S). Default is module-name |
||
7854 | from input_file (renamed by #.MODULE if present) |
||
7855 | -o name : Output files name core (default is <proto>) |
||
7856 | -O dir : Output directory for dissector |
||
7857 | -c cnf_file : Conformance file |
||
7858 | -I path : Path for conformance file includes |
||
7859 | -e : Create conformance file for exported types |
||
7860 | -E : Just create conformance file for exported types |
||
7861 | -S : Single output for multiple modules |
||
7862 | -s template : Single file output (template is input file |
||
7863 | without .c/.h extension) |
||
7864 | -k : Keep intermediate files though single file output is used |
||
7865 | -L : Suppress #line directive from .cnf file |
||
7866 | -D dir : Directory for input_file(s) (default: '.') |
||
7867 | -C : Add check for SIZE constraints |
||
7868 | -r prefix : Remove the prefix from type names |
||
7869 | |||
7870 | input_file(s) : Input ASN.1 file(s) |
||
7871 | |||
7872 | -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o] |
||
7873 | l - lex |
||
7874 | y - yacc |
||
7875 | p - parsing |
||
7876 | s - internal ASN.1 structure |
||
7877 | a - list of assignments |
||
7878 | t - tables |
||
7879 | c - conformance values |
||
7880 | m - list of compiled modules with dependency |
||
7881 | o - list of output files |
||
7882 | """) |
||
7883 | |||
7884 | def eth_main(): |
||
7885 | global input_file |
||
7886 | global g_conform |
||
7887 | global lexer |
||
7888 | print("ASN.1 to Wireshark dissector compiler"); |
||
7889 | try: |
||
7890 | opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLCr:"); |
||
7891 | except getopt.GetoptError: |
||
7892 | eth_usage(); sys.exit(2) |
||
7893 | if len(args) < 1: |
||
7894 | eth_usage(); sys.exit(2) |
||
7895 | |||
7896 | conform = EthCnf() |
||
7897 | conf_to_read = None |
||
7898 | output = EthOut() |
||
7899 | ectx = EthCtx(conform, output) |
||
7900 | ectx.encoding = 'per' |
||
7901 | ectx.proto_opt = None |
||
7902 | ectx.fld_opt = {} |
||
7903 | ectx.tag_opt = False |
||
7904 | ectx.outnm_opt = None |
||
7905 | ectx.aligned = True |
||
7906 | ectx.dbgopt = '' |
||
7907 | ectx.new = True |
||
7908 | ectx.expcnf = False |
||
7909 | ectx.justexpcnf = False |
||
7910 | ectx.merge_modules = False |
||
7911 | ectx.group_by_prot = False |
||
7912 | ectx.conform.last_group = 0 |
||
7913 | ectx.conform.suppress_line = False; |
||
7914 | ectx.output.outnm = None |
||
7915 | ectx.output.single_file = None |
||
7916 | ectx.constraints_check = False; |
||
7917 | for o, a in opts: |
||
7918 | if o in ("-h", "-?"): |
||
7919 | eth_usage(); sys.exit(2) |
||
7920 | if o in ("-c",): |
||
7921 | conf_to_read = relpath(a) |
||
7922 | if o in ("-I",): |
||
7923 | ectx.conform.include_path.append(relpath(a)) |
||
7924 | if o in ("-E",): |
||
7925 | ectx.expcnf = True |
||
7926 | ectx.justexpcnf = True |
||
7927 | if o in ("-D",): |
||
7928 | ectx.srcdir = relpath(a) |
||
7929 | if o in ("-C",): |
||
7930 | ectx.constraints_check = True |
||
7931 | if o in ("-X",): |
||
7932 | warnings.warn("Command line option -X is obsolete and can be removed") |
||
7933 | if o in ("-T",): |
||
7934 | warnings.warn("Command line option -T is obsolete and can be removed") |
||
7935 | |||
7936 | if conf_to_read: |
||
7937 | ectx.conform.read(conf_to_read) |
||
7938 | |||
7939 | for o, a in opts: |
||
7940 | if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-X", "-T"): |
||
7941 | pass # already processed |
||
7942 | else: |
||
7943 | par = [] |
||
7944 | if a: par.append(a) |
||
7945 | ectx.conform.set_opt(o, par, "commandline", 0) |
||
7946 | |||
7947 | (ld, yd, pd) = (0, 0, 0); |
||
7948 | if ectx.dbg('l'): ld = 1 |
||
7949 | if ectx.dbg('y'): yd = 1 |
||
7950 | if ectx.dbg('p'): pd = 2 |
||
7951 | lexer = lex.lex(debug=ld) |
||
7952 | parser = yacc.yacc(method='LALR', debug=yd, outputdir='.') |
||
7953 | parser.defaulted_states = {} |
||
7954 | g_conform = ectx.conform |
||
7955 | ast = [] |
||
7956 | for fn in args: |
||
7957 | input_file = fn |
||
7958 | lexer.lineno = 1 |
||
7959 | if (ectx.srcdir): fn = ectx.srcdir + '/' + fn |
||
7960 | # Read ASN.1 definition, trying one of the common encodings. |
||
7961 | data = open(fn, "rb").read() |
||
7962 | for encoding in ('utf-8', 'windows-1252'): |
||
7963 | try: |
||
7964 | data = data.decode(encoding) |
||
7965 | break |
||
7966 | except: |
||
7967 | warnings.warn_explicit("Decoding %s as %s failed, trying next." % (fn, encoding), UserWarning, '', 0) |
||
7968 | # Py2 compat, name.translate in eth_output_hf_arr fails with unicode |
||
7969 | if not isinstance(data, str): |
||
7970 | data = data.encode('utf-8') |
||
7971 | ast.extend(yacc.parse(data, lexer=lexer, debug=pd)) |
||
7972 | ectx.eth_clean() |
||
7973 | if (ectx.merge_modules): # common output for all module |
||
7974 | ectx.eth_clean() |
||
7975 | for module in ast: |
||
7976 | eth_do_module(module, ectx) |
||
7977 | ectx.eth_prepare() |
||
7978 | ectx.eth_do_output() |
||
7979 | elif (ectx.groups()): # group by protocols/group |
||
7980 | groups = [] |
||
7981 | pr2gr = {} |
||
7982 | if (ectx.group_by_prot): # group by protocols |
||
7983 | for module in ast: |
||
7984 | prot = module.get_proto(ectx) |
||
7985 | if prot not in pr2gr: |
||
7986 | pr2gr[prot] = len(groups) |
||
7987 | groups.append([]) |
||
7988 | groups[pr2gr[prot]].append(module) |
||
7989 | else: # group by groups |
||
7990 | pass |
||
7991 | for gm in (groups): |
||
7992 | ectx.eth_clean() |
||
7993 | for module in gm: |
||
7994 | eth_do_module(module, ectx) |
||
7995 | ectx.eth_prepare() |
||
7996 | ectx.eth_do_output() |
||
7997 | else: # output for each module |
||
7998 | for module in ast: |
||
7999 | ectx.eth_clean() |
||
8000 | eth_do_module(module, ectx) |
||
8001 | ectx.eth_prepare() |
||
8002 | ectx.eth_do_output() |
||
8003 | |||
8004 | if ectx.dbg('m'): |
||
8005 | ectx.dbg_modules() |
||
8006 | |||
8007 | if ectx.dbg('c'): |
||
8008 | ectx.conform.dbg_print() |
||
8009 | if not ectx.justexpcnf: |
||
8010 | ectx.conform.unused_report() |
||
8011 | |||
8012 | if ectx.dbg('o'): |
||
8013 | ectx.output.dbg_print() |
||
8014 | ectx.output.make_single_file() |
||
8015 | |||
8016 | |||
8017 | # Python compiler |
||
8018 | def main(): |
||
8019 | testfn = testyacc |
||
8020 | if len (sys.argv) == 1: |
||
8021 | while True: |
||
8022 | s = input ('Query: ') |
||
8023 | if len (s) == 0: |
||
8024 | break |
||
8025 | testfn (s, 'console', {}) |
||
8026 | else: |
||
8027 | defined_dict = {} |
||
8028 | for fn in sys.argv [1:]: |
||
8029 | f = open (fn, "r") |
||
8030 | testfn (f.read (), fn, defined_dict) |
||
8031 | f.close () |
||
8032 | lexer.lineno = 1 |
||
8033 | |||
8034 | |||
8035 | #--- BODY --------------------------------------------------------------------- |
||
8036 | |||
8037 | if __name__ == '__main__': |
||
8038 | if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')): |
||
8039 | eth_main() |
||
8040 | else: |
||
8041 | main() |
||
8042 | |||
8043 | #------------------------------------------------------------------------------ |
||
8044 | # |
||
8045 | # Editor modelines - http://www.wireshark.org/tools/modelines.html |
||
8046 | # |
||
8047 | # c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil |
||
8048 | # vi: set shiftwidth=4 tabstop=8 expandtab: |
||
8049 | # :indentSize=4:tabSize=8:noTabs=true: |