FIXUP: give names to sec_vt_command's
[wireshark-wip.git] / tools / asn2wrs.py
blob32d7375bb6a4e73da1744e86ea76b59fa3227b8e
1 #!/usr/bin/env python
4 # asn2wrs.py
5 # ASN.1 to Wireshark dissector compiler
6 # Copyright 2004 Tomas Kukosa
8 # $Id$
10 # Permission is hereby granted, free of charge, to any person obtaining a
11 # copy of this software and associated documentation files (the
12 # "Software"), to deal in the Software without restriction, including
13 # without limitation the rights to use, copy, modify, merge, publish,
14 # distribute, and/or sell copies of the Software, and to permit persons
15 # to whom the Software is furnished to do so, provided that the above
16 # copyright notice(s) and this permission notice appear in all copies of
17 # the Software and that both the above copyright notice(s) and this
18 # permission notice appear in supporting documentation.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
23 # OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 # HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
25 # INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
26 # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
27 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
28 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 # Except as contained in this notice, the name of a copyright holder
31 # shall not be used in advertising or otherwise to promote the sale, use
32 # or other dealings in this Software without prior written authorization
33 # of the copyright holder.
36 """ASN.1 to Wireshark dissector compiler"""
39 # Compiler from ASN.1 specification to the Wireshark dissector
41 # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license
42 # http://www.pobox.com/~asl2/software/PyZ3950/
43 # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
45 # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
46 # http://www.dabeaz.com/ply/
49 # ITU-T Recommendation X.680 (07/2002),
50 # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
52 # ITU-T Recommendation X.681 (07/2002),
53 # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
55 # ITU-T Recommendation X.682 (07/2002),
56 # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
58 # ITU-T Recommendation X.683 (07/2002),
59 # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
61 # ITU-T Recommendation X.880 (07/1994),
62 # Information technology - Remote Operations: Concepts, model and notation
65 import warnings
67 import re
68 import sys
69 import os
70 import os.path
71 import time
72 import getopt
73 import traceback
75 import lex
76 import yacc
78 from functools import partial
80 if sys.version_info[0] < 3:
81 from string import maketrans
84 # OID name -> number conversion table
85 oid_names = {
86 '/itu-t' : 0,
87 '/itu' : 0,
88 '/ccitt' : 0,
89 '/itu-r' : 0,
90 '0/recommendation' : 0,
91 '0.0/a' : 1,
92 '0.0/b' : 2,
93 '0.0/c' : 3,
94 '0.0/d' : 4,
95 '0.0/e' : 5,
96 '0.0/f' : 6,
97 '0.0/g' : 7,
98 '0.0/h' : 8,
99 '0.0/i' : 9,
100 '0.0/j' : 10,
101 '0.0/k' : 11,
102 '0.0/l' : 12,
103 '0.0/m' : 13,
104 '0.0/n' : 14,
105 '0.0/o' : 15,
106 '0.0/p' : 16,
107 '0.0/q' : 17,
108 '0.0/r' : 18,
109 '0.0/s' : 19,
110 '0.0/t' : 20,
111 '0.0/tseries' : 20,
112 '0.0/u' : 21,
113 '0.0/v' : 22,
114 '0.0/w' : 23,
115 '0.0/x' : 24,
116 '0.0/y' : 25,
117 '0.0/z' : 26,
118 '0/question' : 1,
119 '0/administration' : 2,
120 '0/network-operator' : 3,
121 '0/identified-organization' : 4,
122 '0/r-recommendation' : 5,
123 '0/data' : 9,
124 '/iso' : 1,
125 '1/standard' : 0,
126 '1/registration-authority' : 1,
127 '1/member-body' : 2,
128 '1/identified-organization' : 3,
129 '/joint-iso-itu-t' : 2,
130 '/joint-iso-ccitt' : 2,
131 '2/presentation' : 0,
132 '2/asn1' : 1,
133 '2/association-control' : 2,
134 '2/reliable-transfer' : 3,
135 '2/remote-operations' : 4,
136 '2/ds' : 5,
137 '2/directory' : 5,
138 '2/mhs' : 6,
139 '2/mhs-motis' : 6,
140 '2/ccr' : 7,
141 '2/oda' : 8,
142 '2/ms' : 9,
143 '2/osi-management' : 9,
144 '2/transaction-processing' : 10,
145 '2/dor' : 11,
146 '2/distinguished-object-reference' : 11,
147 '2/reference-data-transfe' : 12,
148 '2/network-layer' : 13,
149 '2/network-layer-management' : 13,
150 '2/transport-layer' : 14,
151 '2/transport-layer-management' : 14,
152 '2/datalink-layer' : 15,
153 '2/datalink-layer-managemen' : 15,
154 '2/datalink-layer-management-information' : 15,
155 '2/country' : 16,
156 '2/registration-procedures' : 17,
157 '2/registration-procedure' : 17,
158 '2/physical-layer' : 18,
159 '2/physical-layer-management' : 18,
160 '2/mheg' : 19,
161 '2/genericULS' : 20,
162 '2/generic-upper-layers-security' : 20,
163 '2/guls' : 20,
164 '2/transport-layer-security-protocol' : 21,
165 '2/network-layer-security-protocol' : 22,
166 '2/international-organizations' : 23,
167 '2/internationalRA' : 23,
168 '2/sios' : 24,
169 '2/uuid' : 25,
170 '2/odp' : 26,
171 '2/upu' : 40,
174 ITEM_FIELD_NAME = '_item'
175 UNTAG_TYPE_NAME = '_untag'
177 def asn2c(id):
178 return id.replace('-', '_').replace('.', '_').replace('&', '_')
180 input_file = None
181 g_conform = None
182 lexer = None
183 in_oid = False
185 class LexError(Exception):
186 def __init__(self, tok, filename=None):
187 self.tok = tok
188 self.filename = filename
189 self.msg = "Unexpected character %r" % (self.tok.value[0])
190 Exception.__init__(self, self.msg)
191 def __repr__(self):
192 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
193 __str__ = __repr__
196 class ParseError(Exception):
197 def __init__(self, tok, filename=None):
198 self.tok = tok
199 self.filename = filename
200 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
201 Exception.__init__(self, self.msg)
202 def __repr__(self):
203 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
204 __str__ = __repr__
207 class DuplicateError(Exception):
208 def __init__(self, type, ident):
209 self.type = type
210 self.ident = ident
211 self.msg = "Duplicate %s for %s" % (self.type, self.ident)
212 Exception.__init__(self, self.msg)
213 def __repr__(self):
214 return self.msg
215 __str__ = __repr__
217 class CompError(Exception):
218 def __init__(self, msg):
219 self.msg = msg
220 Exception.__init__(self, self.msg)
221 def __repr__(self):
222 return self.msg
223 __str__ = __repr__
226 states = (
227 ('braceignore','exclusive'),
230 precedence = (
231 ('left', 'UNION', 'BAR'),
232 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
234 # 11 ASN.1 lexical items
236 static_tokens = {
237 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
238 r'\.\.' : 'RANGE', # 11.17 Range separator
239 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
240 r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
241 r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
242 # 11.26 Single character lexical items
243 r'\{' : 'LBRACE',
244 r'\}' : 'RBRACE',
245 r'<' : 'LT',
246 #r'>' : 'GT',
247 r',' : 'COMMA',
248 r'\.' : 'DOT',
249 r'\(' : 'LPAREN',
250 r'\)' : 'RPAREN',
251 r'\[' : 'LBRACK',
252 r'\]' : 'RBRACK',
253 r'-' : 'MINUS',
254 r':' : 'COLON',
255 #r'=' : 'EQ',
256 #r'"' : 'QUOTATION',
257 #r"'" : 'APOSTROPHE',
258 r';' : 'SEMICOLON',
259 r'@' : 'AT',
260 r'\!' : 'EXCLAMATION',
261 r'\^' : 'CIRCUMFLEX',
262 r'\&' : 'AMPERSAND',
263 r'\|' : 'BAR'
266 # 11.27 Reserved words
268 # all keys in reserved_words must start w/ upper case
269 reserved_words = {
270 'ABSENT' : 'ABSENT',
271 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
272 'ALL' : 'ALL',
273 'APPLICATION' : 'APPLICATION',
274 'AUTOMATIC' : 'AUTOMATIC',
275 'BEGIN' : 'BEGIN',
276 'BIT' : 'BIT',
277 'BOOLEAN' : 'BOOLEAN',
278 'BY' : 'BY',
279 'CHARACTER' : 'CHARACTER',
280 'CHOICE' : 'CHOICE',
281 'CLASS' : 'CLASS',
282 'COMPONENT' : 'COMPONENT',
283 'COMPONENTS' : 'COMPONENTS',
284 'CONSTRAINED' : 'CONSTRAINED',
285 'CONTAINING' : 'CONTAINING',
286 'DEFAULT' : 'DEFAULT',
287 'DEFINITIONS' : 'DEFINITIONS',
288 'EMBEDDED' : 'EMBEDDED',
289 # 'ENCODED' : 'ENCODED',
290 'END' : 'END',
291 'ENUMERATED' : 'ENUMERATED',
292 # 'EXCEPT' : 'EXCEPT',
293 'EXPLICIT' : 'EXPLICIT',
294 'EXPORTS' : 'EXPORTS',
295 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
296 'EXTERNAL' : 'EXTERNAL',
297 'FALSE' : 'FALSE',
298 'FROM' : 'FROM',
299 'GeneralizedTime' : 'GeneralizedTime',
300 'IDENTIFIER' : 'IDENTIFIER',
301 'IMPLICIT' : 'IMPLICIT',
302 # 'IMPLIED' : 'IMPLIED',
303 'IMPORTS' : 'IMPORTS',
304 'INCLUDES' : 'INCLUDES',
305 'INSTANCE' : 'INSTANCE',
306 'INTEGER' : 'INTEGER',
307 'INTERSECTION' : 'INTERSECTION',
308 'MAX' : 'MAX',
309 'MIN' : 'MIN',
310 'MINUS-INFINITY' : 'MINUS_INFINITY',
311 'NULL' : 'NULL',
312 'OBJECT' : 'OBJECT',
313 'ObjectDescriptor' : 'ObjectDescriptor',
314 'OCTET' : 'OCTET',
315 'OF' : 'OF',
316 'OPTIONAL' : 'OPTIONAL',
317 'PATTERN' : 'PATTERN',
318 'PDV' : 'PDV',
319 'PLUS-INFINITY' : 'PLUS_INFINITY',
320 'PRESENT' : 'PRESENT',
321 'PRIVATE' : 'PRIVATE',
322 'REAL' : 'REAL',
323 'RELATIVE-OID' : 'RELATIVE_OID',
324 'SEQUENCE' : 'SEQUENCE',
325 'SET' : 'SET',
326 'SIZE' : 'SIZE',
327 'STRING' : 'STRING',
328 'SYNTAX' : 'SYNTAX',
329 'TAGS' : 'TAGS',
330 'TRUE' : 'TRUE',
331 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
332 'UNION' : 'UNION',
333 'UNIQUE' : 'UNIQUE',
334 'UNIVERSAL' : 'UNIVERSAL',
335 'UTCTime' : 'UTCTime',
336 'WITH' : 'WITH',
337 # X.208 obsolete but still used
338 'ANY' : 'ANY',
339 'DEFINED' : 'DEFINED',
342 for k in list(static_tokens.keys()):
343 if static_tokens [k] == None:
344 static_tokens [k] = k
346 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
347 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
348 'General']
350 for s in StringTypes:
351 reserved_words[s + 'String'] = s + 'String'
353 tokens = list(static_tokens.values()) \
354 + list(reserved_words.values()) \
355 + ['BSTRING', 'HSTRING', 'QSTRING',
356 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
357 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
360 cur_mod = __import__ (__name__) # XXX blech!
362 for (k, v) in list(static_tokens.items ()):
363 cur_mod.__dict__['t_' + v] = k
365 # 11.10 Binary strings
366 def t_BSTRING (t):
367 r"'[01]*'B"
368 return t
370 # 11.12 Hexadecimal strings
371 def t_HSTRING (t):
372 r"'[0-9A-Fa-f]*'H"
373 return t
375 def t_QSTRING (t):
376 r'"([^"]|"")*"'
377 return t
379 def t_UCASE_IDENT (t):
380 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
381 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
382 if (is_class_syntax(t.value)): t.type = t.value
383 t.type = reserved_words.get(t.value, t.type)
384 return t
386 lcase_ident_assigned = {}
387 def t_LCASE_IDENT (t):
388 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
389 if (not in_oid and (t.value in lcase_ident_assigned)): t.type = 'LCASE_IDENT_ASSIGNED'
390 return t
392 # 11.9 Real numbers
393 def t_REAL_NUMBER (t):
394 r"[0-9]+\.[0-9]*(?!\.)"
395 return t
397 # 11.8 Numbers
398 def t_NUMBER (t):
399 r"0|([1-9][0-9]*)"
400 return t
402 # 11.6 Comments
403 pyquote_str = 'PYQUOTE'
404 def t_COMMENT(t):
405 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
406 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
407 if t.value[2:2+len (pyquote_str)] == pyquote_str:
408 t.value = t.value[2+len(pyquote_str):]
409 t.value = t.value.lstrip ()
410 t.type = pyquote_str
411 return t
412 return None
414 t_ignore = " \t\r"
416 def t_NEWLINE(t):
417 r'\n+'
418 t.lexer.lineno += t.value.count("\n")
420 def t_error(t):
421 global input_file
422 raise LexError(t, input_file)
424 # state 'braceignore'
426 def t_braceignore_lbrace(t):
427 r'\{'
428 t.lexer.level +=1
430 def t_braceignore_rbrace(t):
431 r'\}'
432 t.lexer.level -=1
433 # If closing brace, return token
434 if t.lexer.level == 0:
435 t.type = 'RBRACE'
436 return t
438 def t_braceignore_QSTRING (t):
439 r'"([^"]|"")*"'
440 t.lexer.lineno += t.value.count("\n")
442 def t_braceignore_COMMENT(t):
443 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
444 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
446 def t_braceignore_nonspace(t):
447 r'[^\s\{\}\"-]+|-(?!-)'
449 t_braceignore_ignore = " \t\r"
451 def t_braceignore_NEWLINE(t):
452 r'\n+'
453 t.lexer.lineno += t.value.count("\n")
455 def t_braceignore_error(t):
456 t.lexer.skip(1)
458 class Ctx:
459 def __init__ (self, defined_dict, indent = 0):
460 self.tags_def = 'EXPLICIT' # default = explicit
461 self.indent_lev = 0
462 self.assignments = {}
463 self.dependencies = {}
464 self.pyquotes = []
465 self.defined_dict = defined_dict
466 self.name_ctr = 0
467 def spaces (self):
468 return " " * (4 * self.indent_lev)
469 def indent (self):
470 self.indent_lev += 1
471 def outdent (self):
472 self.indent_lev -= 1
473 assert (self.indent_lev >= 0)
474 def register_assignment (self, ident, val, dependencies):
475 if ident in self.assignments:
476 raise DuplicateError("assignment", ident)
477 if ident in self.defined_dict:
478 raise Exception("cross-module duplicates for %s" % ident)
479 self.defined_dict [ident] = 1
480 self.assignments[ident] = val
481 self.dependencies [ident] = dependencies
482 return ""
483 # return "#%s depends on %s" % (ident, str (dependencies))
484 def register_pyquote (self, val):
485 self.pyquotes.append (val)
486 return ""
487 def output_assignments (self):
488 already_output = {}
489 text_list = []
490 assign_keys = list(self.assignments.keys())
491 to_output_count = len (assign_keys)
492 while True:
493 any_output = 0
494 for (ident, val) in list(self.assignments.items ()):
495 if ident in already_output:
496 continue
497 ok = 1
498 for d in self.dependencies [ident]:
499 if ((d not in already_output) and
500 (d in assign_keys)):
501 ok = 0
502 if ok:
503 text_list.append ("%s=%s" % (ident,
504 self.assignments [ident]))
505 already_output [ident] = 1
506 any_output = 1
507 to_output_count -= 1
508 assert (to_output_count >= 0)
509 if not any_output:
510 if to_output_count == 0:
511 break
512 # OK, we detected a cycle
513 cycle_list = []
514 for ident in list(self.assignments.keys ()):
515 if ident not in already_output:
516 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
517 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
519 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
520 for (ident, val) in list(self.assignments.items ()):
521 if ident not in already_output:
522 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
523 break
525 return "\n".join (text_list)
526 def output_pyquotes (self):
527 return "\n".join (self.pyquotes)
528 def make_new_name (self):
529 self.name_ctr += 1
530 return "_compiler_generated_name_%d" % (self.name_ctr,)
532 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
533 EF_TYPE = 0x0001
534 EF_VALS = 0x0002
535 EF_ENUM = 0x0004
536 EF_WS_DLL = 0x0010 # exported from shared library
537 EF_EXTERN = 0x0020
538 EF_NO_PROT = 0x0040
539 EF_NO_TYPE = 0x0080
540 EF_UCASE = 0x0100
541 EF_TABLE = 0x0400
542 EF_DEFINE = 0x0800
543 EF_MODULE = 0x1000
545 #--- common dependency computation ---
546 # Input : list of items
547 # dictionary with lists of dependency
550 # Output : list of two outputs:
551 # [0] list of items in dependency
552 # [1] list of cycle dependency cycles
553 def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False):
554 item_ord = []
555 item_cyc = []
556 x = {} # already emitted
557 #print '# Dependency computation'
558 for t in items:
559 if map_fn(t) in x:
560 #print 'Continue: %s : %s' % (t, (map_fn(t))
561 continue
562 stack = [t]
563 stackx = {t : dependency.get(t, [])[:]}
564 #print 'Push: %s : %s' % (t, str(stackx[t]))
565 while stack:
566 if stackx[stack[-1]]: # has dependencies
567 d = stackx[stack[-1]].pop(0)
568 if map_fn(d) in x or ignore_fn(d):
569 continue
570 if d in stackx: # cyclic dependency
571 c = stack[:]
572 c.reverse()
573 c = [d] + c[0:c.index(d)+1]
574 c.reverse()
575 item_cyc.append(c)
576 #print 'Cyclic: %s ' % (' -> '.join(c))
577 continue
578 stack.append(d)
579 stackx[d] = dependency.get(d, [])[:]
580 #print 'Push: %s : %s' % (d, str(stackx[d]))
581 else:
582 #print 'Pop: %s' % (stack[-1])
583 del stackx[stack[-1]]
584 e = map_fn(stack.pop())
585 if e in x:
586 continue
587 #print 'Add: %s' % (e)
588 item_ord.append(e)
589 x[e] = True
590 return (item_ord, item_cyc)
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 path_parts.insert(0, '..')
599 return '/'.join(path_parts)
602 #--- EthCtx -------------------------------------------------------------------
603 class EthCtx:
604 def __init__(self, conform, output, indent = 0):
605 self.conform = conform
606 self.output = output
607 self.conform.ectx = self
608 self.output.ectx = self
609 self.encoding = 'per'
610 self.aligned = False
611 self.default_oid_variant = ''
612 self.default_opentype_variant = ''
613 self.default_containing_variant = '_pdu_new'
614 self.default_embedded_pdv_cb = None
615 self.default_external_type_cb = None
616 self.remove_prefix = None
617 self.srcdir = None
618 self.emitted_pdu = {}
619 self.module = {}
620 self.module_ord = []
621 self.all_type_attr = {}
622 self.all_tags = {}
623 self.all_vals = {}
625 def encp(self): # encoding protocol
626 encp = self.encoding
627 return encp
629 # Encoding
630 def Per(self): return self.encoding == 'per'
631 def Ber(self): return self.encoding == 'ber'
632 def Aligned(self): return self.aligned
633 def Unaligned(self): return not self.aligned
634 def NeedTags(self): return self.tag_opt or self.Ber()
635 def NAPI(self): return False # disable planned features
637 def Module(self): # current module name
638 return self.modules[-1][0]
640 def groups(self):
641 return self.group_by_prot or (self.conform.last_group > 0)
643 def dbg(self, d):
644 if (self.dbgopt.find(d) >= 0):
645 return True
646 else:
647 return False
649 def value_max(self, a, b):
650 if (a == 'MAX') or (b == 'MAX'): return 'MAX';
651 if a == 'MIN': return b;
652 if b == 'MIN': return a;
653 try:
654 if (int(a) > int(b)):
655 return a
656 else:
657 return b
658 except (ValueError, TypeError):
659 pass
660 return "MAX((%s),(%s))" % (a, b)
662 def value_min(self, a, b):
663 if (a == 'MIN') or (b == 'MIN'): return 'MIN';
664 if a == 'MAX': return b;
665 if b == 'MAX': return a;
666 try:
667 if (int(a) < int(b)):
668 return a
669 else:
670 return b
671 except (ValueError, TypeError):
672 pass
673 return "MIN((%s),(%s))" % (a, b)
675 def value_get_eth(self, val):
676 if isinstance(val, Value):
677 return val.to_str(self)
678 ethname = val
679 if val in self.value:
680 ethname = self.value[val]['ethname']
681 return ethname
683 def value_get_val(self, nm):
684 val = asn2c(nm)
685 if nm in self.value:
686 if self.value[nm]['import']:
687 v = self.get_val_from_all(nm, self.value[nm]['import'])
688 if v is None:
689 msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto'])
690 warnings.warn_explicit(msg, UserWarning, '', 0)
691 else:
692 val = v
693 else:
694 val = self.value[nm]['value']
695 if isinstance (val, Value):
696 val = val.to_str(self)
697 else:
698 msg = 'Need value of unknown value identifier %s' % (nm)
699 warnings.warn_explicit(msg, UserWarning, '', 0)
700 return val
702 def eth_get_type_attr(self, type):
703 #print "eth_get_type_attr(%s)" % (type)
704 types = [type]
705 while (not self.type[type]['import']):
706 val = self.type[type]['val']
707 #print val
708 ttype = type
709 while (val.type == 'TaggedType'):
710 val = val.val
711 ttype += '/' + UNTAG_TYPE_NAME
712 if (val.type != 'Type_Ref'):
713 if (type != ttype):
714 types.append(ttype)
715 break
716 type = val.val
717 types.append(type)
718 attr = {}
719 #print " ", types
720 while len(types):
721 t = types.pop()
722 if (self.type[t]['import']):
723 attr.update(self.type[t]['attr'])
724 attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import']))
725 elif (self.type[t]['val'].type == 'SelectionType'):
726 val = self.type[t]['val']
727 (ftype, display) = val.eth_ftype(self)
728 attr.update({ 'TYPE' : ftype, 'DISPLAY' : display,
729 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' });
730 else:
731 attr.update(self.type[t]['attr'])
732 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
733 #print " ", attr
734 return attr
736 def eth_get_type_attr_from_all(self, type, module):
737 attr = {}
738 if module in self.all_type_attr and type in self.all_type_attr[module]:
739 attr = self.all_type_attr[module][type]
740 return attr
742 def get_ttag_from_all(self, type, module):
743 ttag = None
744 if module in self.all_tags and type in self.all_tags[module]:
745 ttag = self.all_tags[module][type]
746 return ttag
748 def get_val_from_all(self, nm, module):
749 val = None
750 if module in self.all_vals and nm in self.all_vals[module]:
751 val = self.all_vals[module][nm]
752 return val
754 def get_obj_repr(self, ident, flds=[], not_flds=[]):
755 def set_type_fn(cls, field, fnfield):
756 obj[fnfield + '_fn'] = 'NULL'
757 obj[fnfield + '_pdu'] = 'NULL'
758 if field in val and isinstance(val[field], Type_Ref):
759 p = val[field].eth_type_default_pars(self, '')
760 obj[fnfield + '_fn'] = p['TYPE_REF_FN']
761 obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration
762 if (self.conform.check_item('PDU', cls + '.' + field)):
763 obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname']
764 return
765 # end of get_type_fn()
766 obj = { '_name' : ident, '_ident' : asn2c(ident)}
767 obj['_class'] = self.oassign[ident].cls
768 obj['_module'] = self.oassign[ident].module
769 val = self.oassign[ident].val
770 for f in flds:
771 if f not in val:
772 return None
773 for f in not_flds:
774 if f in val:
775 return None
776 for f in list(val.keys()):
777 if isinstance(val[f], Node):
778 obj[f] = val[f].fld_obj_repr(self)
779 else:
780 obj[f] = str(val[f])
781 if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'):
782 set_type_fn(obj['_class'], '&Type', '_type')
783 if (obj['_class'] == 'OPERATION'):
784 set_type_fn(obj['_class'], '&ArgumentType', '_argument')
785 set_type_fn(obj['_class'], '&ResultType', '_result')
786 if (obj['_class'] == 'ERROR'):
787 set_type_fn(obj['_class'], '&ParameterType', '_parameter')
788 return obj
790 #--- eth_reg_module -----------------------------------------------------------
791 def eth_reg_module(self, module):
792 #print "eth_reg_module(module='%s')" % (module)
793 name = module.get_name()
794 self.modules.append([name, module.get_proto(self)])
795 if name in self.module:
796 raise DuplicateError("module", name)
797 self.module[name] = []
798 self.module_ord.append(name)
800 #--- eth_module_dep_add ------------------------------------------------------------
801 def eth_module_dep_add(self, module, dep):
802 self.module[module].append(dep)
804 #--- eth_exports ------------------------------------------------------------
805 def eth_exports(self, exports):
806 self.exports_all = False
807 if ((len(exports) == 1) and (exports[0] == 'ALL')):
808 self.exports_all = True
809 return
810 for e in (exports):
811 if isinstance(e, Type_Ref):
812 self.exports.append(e.val)
813 elif isinstance(e, Class_Ref):
814 self.cexports.append(e.val)
815 else:
816 self.vexports.append(e)
818 #--- eth_reg_assign ---------------------------------------------------------
819 def eth_reg_assign(self, ident, val, virt=False):
820 #print "eth_reg_assign(ident='%s')" % (ident)
821 if ident in self.assign:
822 raise DuplicateError("assignment", ident)
823 self.assign[ident] = { 'val' : val , 'virt' : virt }
824 self.assign_ord.append(ident)
825 if (self.exports_all):
826 self.exports.append(ident)
828 #--- eth_reg_vassign --------------------------------------------------------
829 def eth_reg_vassign(self, vassign):
830 ident = vassign.ident
831 #print "eth_reg_vassign(ident='%s')" % (ident)
832 if ident in self.vassign:
833 raise DuplicateError("value assignment", ident)
834 self.vassign[ident] = vassign
835 self.vassign_ord.append(ident)
836 if (self.exports_all):
837 self.vexports.append(ident)
839 #--- eth_reg_oassign --------------------------------------------------------
840 def eth_reg_oassign(self, oassign):
841 ident = oassign.ident
842 #print "eth_reg_oassign(ident='%s')" % (ident)
843 if ident in self.oassign:
844 if self.oassign[ident] == oassign:
845 return # OK - already defined
846 else:
847 raise DuplicateError("information object assignment", ident)
848 self.oassign[ident] = oassign
849 self.oassign_ord.append(ident)
850 self.oassign_cls.setdefault(oassign.cls, []).append(ident)
852 #--- eth_import_type --------------------------------------------------------
853 def eth_import_type(self, ident, mod, proto):
854 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
855 if ident in self.type:
856 #print "already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-'))
857 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
858 return # OK - already defined
859 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
860 return # OK - already imported
861 else:
862 raise DuplicateError("type", ident)
863 self.type[ident] = {'import' : mod, 'proto' : proto,
864 'ethname' : '' }
865 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
866 'STRINGS' : 'NULL', 'BITMASK' : '0' }
867 mident = "$%s$%s" % (mod, ident)
868 if (self.conform.check_item('TYPE_ATTR', mident)):
869 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', mident))
870 else:
871 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
872 if (self.conform.check_item('IMPORT_TAG', mident)):
873 self.conform.copy_item('IMPORT_TAG', ident, mident)
874 self.type_imp.append(ident)
876 #--- dummy_import_type --------------------------------------------------------
877 def dummy_import_type(self, ident):
878 # dummy imported
879 if ident in self.type:
880 raise Exception("Try to dummy import for existing type :%s" % ident)
881 ethtype = asn2c(ident)
882 self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
883 'ethname' : ethtype }
884 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
885 'STRINGS' : 'NULL', 'BITMASK' : '0' }
886 self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
887 print("Dummy imported: %s (%s)" % (ident, ethtype))
888 return ethtype
890 #--- eth_import_class --------------------------------------------------------
891 def eth_import_class(self, ident, mod, proto):
892 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
893 if ident in self.objectclass:
894 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
895 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
896 return # OK - already defined
897 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
898 return # OK - already imported
899 else:
900 raise DuplicateError("object class", ident)
901 self.objectclass[ident] = {'import' : mod, 'proto' : proto,
902 'ethname' : '' }
903 self.objectclass_imp.append(ident)
905 #--- eth_import_value -------------------------------------------------------
906 def eth_import_value(self, ident, mod, proto):
907 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
908 if ident in self.value:
909 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
910 if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) :
911 return # OK - already defined
912 elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) :
913 return # OK - already imported
914 else:
915 raise DuplicateError("value", ident)
916 self.value[ident] = {'import' : mod, 'proto' : proto,
917 'ethname' : ''}
918 self.value_imp.append(ident)
920 #--- eth_sel_req ------------------------------------------------------------
921 def eth_sel_req(self, typ, sel):
922 key = typ + '.' + sel
923 if key not in self.sel_req:
924 self.sel_req[key] = { 'typ' : typ , 'sel' : sel}
925 self.sel_req_ord.append(key)
926 return key
928 #--- eth_comp_req ------------------------------------------------------------
929 def eth_comp_req(self, type):
930 self.comp_req_ord.append(type)
932 #--- eth_dep_add ------------------------------------------------------------
933 def eth_dep_add(self, type, dep):
934 if type not in self.type_dep:
935 self.type_dep[type] = []
936 self.type_dep[type].append(dep)
938 #--- eth_reg_type -----------------------------------------------------------
939 def eth_reg_type(self, ident, val):
940 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
941 if ident in self.type:
942 if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) :
943 # replace imported type
944 del self.type[ident]
945 self.type_imp.remove(ident)
946 else:
947 raise DuplicateError("type", ident)
948 val.ident = ident
949 self.type[ident] = { 'val' : val, 'import' : None }
950 self.type[ident]['module'] = self.Module()
951 self.type[ident]['proto'] = self.proto
952 if len(ident.split('/')) > 1:
953 self.type[ident]['tname'] = val.eth_tname()
954 else:
955 self.type[ident]['tname'] = asn2c(ident)
956 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
957 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
958 self.type[ident]['vals_ext'] = self.conform.use_item('USE_VALS_EXT', ident)
959 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
960 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
961 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
962 self.type[ident]['ethname'] = ''
963 if (val.type == 'Type_Ref') or (val.type == 'TaggedType') or (val.type == 'SelectionType') :
964 self.type[ident]['attr'] = {}
965 else:
966 (ftype, display) = val.eth_ftype(self)
967 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
968 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
969 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
970 self.type_ord.append(ident)
971 # PDU
972 if (self.conform.check_item('PDU', ident)):
973 self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident))
975 #--- eth_reg_objectclass ----------------------------------------------------------
976 def eth_reg_objectclass(self, ident, val):
977 #print "eth_reg_objectclass(ident='%s')" % (ident)
978 if ident in self.objectclass:
979 if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) :
980 # replace imported object class
981 del self.objectclass[ident]
982 self.objectclass_imp.remove(ident)
983 elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \
984 isinstance(val, Class_Ref) and \
985 (self.objectclass[ident]['val'].val == val.val):
986 pass # ignore duplicated CLASS1 ::= CLASS2
987 else:
988 raise DuplicateError("object class", ident)
989 self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto }
990 self.objectclass[ident]['val'] = val
991 self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident)
992 self.objectclass_ord.append(ident)
994 #--- eth_reg_value ----------------------------------------------------------
995 def eth_reg_value(self, ident, type, value, ethname=None):
996 #print "eth_reg_value(ident='%s')" % (ident)
997 if ident in self.value:
998 if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) :
999 # replace imported value
1000 del self.value[ident]
1001 self.value_imp.remove(ident)
1002 elif ethname:
1003 self.value[ident]['ethname'] = ethname
1004 return
1005 else:
1006 raise DuplicateError("value", ident)
1007 self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto,
1008 'type' : type, 'value' : value,
1009 'no_emit' : False }
1010 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
1011 self.value[ident]['ethname'] = ''
1012 if (ethname): self.value[ident]['ethname'] = ethname
1013 self.value_ord.append(ident)
1015 #--- eth_reg_field ----------------------------------------------------------
1016 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
1017 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
1018 if ident in self.field:
1019 if pdu and (type == self.field[ident]['type']):
1020 pass # OK already created PDU
1021 else:
1022 raise DuplicateError("field", ident)
1023 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
1024 'modified' : '', 'attr' : {} }
1025 name = ident.split('/')[-1]
1026 if self.remove_prefix and name.startswith(self.remove_prefix):
1027 name = name[len(self.remove_prefix):]
1029 if len(ident.split('/')) > 1 and name == ITEM_FIELD_NAME: # Sequence/Set of type
1030 if len(self.field[ident]['type'].split('/')) > 1:
1031 self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2]
1032 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
1033 else:
1034 self.field[ident]['attr']['NAME'] = '"%s"' % self.field[ident]['type']
1035 self.field[ident]['attr']['ABBREV'] = asn2c(self.field[ident]['type'])
1036 else:
1037 self.field[ident]['attr']['NAME'] = '"%s"' % name
1038 self.field[ident]['attr']['ABBREV'] = asn2c(name)
1039 if self.conform.check_item('FIELD_ATTR', ident):
1040 self.field[ident]['modified'] = '#' + str(id(self))
1041 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
1042 if (pdu):
1043 self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0)
1044 self.pdu_ord.append(ident)
1045 else:
1046 self.field_ord.append(ident)
1047 if parent:
1048 self.eth_dep_add(parent, type)
1050 def eth_dummy_eag_field_required(self):
1051 if (not self.dummy_eag_field):
1052 self.dummy_eag_field = 'dummy_eag_field'
1054 #--- eth_clean --------------------------------------------------------------
1055 def eth_clean(self):
1056 self.proto = self.proto_opt;
1057 #--- ASN.1 tables ----------------
1058 self.assign = {}
1059 self.assign_ord = []
1060 self.field = {}
1061 self.pdu_ord = []
1062 self.field_ord = []
1063 self.type = {}
1064 self.type_ord = []
1065 self.type_imp = []
1066 self.type_dep = {}
1067 self.sel_req = {}
1068 self.sel_req_ord = []
1069 self.comp_req_ord = []
1070 self.vassign = {}
1071 self.vassign_ord = []
1072 self.value = {}
1073 self.value_ord = []
1074 self.value_imp = []
1075 self.objectclass = {}
1076 self.objectclass_ord = []
1077 self.objectclass_imp = []
1078 self.oassign = {}
1079 self.oassign_ord = []
1080 self.oassign_cls = {}
1081 #--- Modules ------------
1082 self.modules = []
1083 self.exports_all = False
1084 self.exports = []
1085 self.cexports = []
1086 self.vexports = []
1087 #--- types -------------------
1088 self.eth_type = {}
1089 self.eth_type_ord = []
1090 self.eth_export_ord = []
1091 self.eth_type_dupl = {}
1092 self.named_bit = []
1093 #--- value dependencies -------------------
1094 self.value_dep = {}
1095 #--- values -------------------
1096 self.eth_value = {}
1097 self.eth_value_ord = []
1098 #--- fields -------------------------
1099 self.eth_hf = {}
1100 self.eth_hf_ord = []
1101 self.eth_hfpdu_ord = []
1102 self.eth_hf_dupl = {}
1103 self.dummy_eag_field = None
1104 #--- type dependencies -------------------
1105 self.eth_type_ord1 = []
1106 self.eth_dep_cycle = []
1107 self.dep_cycle_eth_type = {}
1108 #--- value dependencies and export -------------------
1109 self.eth_value_ord1 = []
1110 self.eth_vexport_ord = []
1112 #--- eth_prepare ------------------------------------------------------------
1113 def eth_prepare(self):
1114 self.eproto = asn2c(self.proto)
1116 #--- dummy types/fields for PDU registration ---
1117 nm = 'NULL'
1118 if (self.conform.check_item('PDU', nm)):
1119 self.eth_reg_type('_dummy/'+nm, NullType())
1120 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
1122 #--- required PDUs ----------------------------
1123 for t in self.type_ord:
1124 pdu = self.type[t]['val'].eth_need_pdu(self)
1125 if not pdu: continue
1126 f = pdu['type']
1127 pdu['reg'] = None
1128 pdu['hidden'] = False
1129 pdu['need_decl'] = True
1130 if f not in self.field:
1131 self.eth_reg_field(f, f, pdu=pdu)
1133 #--- values -> named values -------------------
1134 t_for_update = {}
1135 for v in self.value_ord:
1136 if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1137 if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1138 tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v)
1139 else:
1140 tnm = self.value[v]['type'].val
1141 if tnm in self.type \
1142 and not self.type[tnm]['import'] \
1143 and (self.type[tnm]['val'].type == 'IntegerType'):
1144 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
1145 self.value[v]['no_emit'] = True
1146 t_for_update[tnm] = True
1147 for t in list(t_for_update.keys()):
1148 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
1149 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
1151 #--- required components of ---------------------------
1152 #print "self.comp_req_ord = ", self.comp_req_ord
1153 for t in self.comp_req_ord:
1154 self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
1156 #--- required selection types ---------------------------
1157 #print "self.sel_req_ord = ", self.sel_req_ord
1158 for t in self.sel_req_ord:
1159 tt = self.sel_req[t]['typ']
1160 if tt not in self.type:
1161 self.dummy_import_type(t)
1162 elif self.type[tt]['import']:
1163 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
1164 else:
1165 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
1167 #--- types -------------------
1168 for t in self.type_imp: # imported types
1169 nm = asn2c(t)
1170 self.eth_type[nm] = { 'import' : self.type[t]['import'],
1171 'proto' : asn2c(self.type[t]['proto']),
1172 'attr' : {}, 'ref' : []}
1173 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1174 self.type[t]['ethname'] = nm
1175 for t in self.type_ord: # dummy import for missing type reference
1176 tp = self.type[t]['val']
1177 #print "X : %s %s " % (t, tp.type)
1178 if isinstance(tp, TaggedType):
1179 #print "%s : %s " % (tp.type, t)
1180 tp = tp.val
1181 if isinstance(tp, Type_Ref):
1182 #print "%s : %s ::= %s " % (tp.type, t, tp.val)
1183 if tp.val not in self.type:
1184 self.dummy_import_type(tp.val)
1185 for t in self.type_ord:
1186 nm = self.type[t]['tname']
1187 if ((nm.find('#') >= 0) or
1188 ((len(t.split('/'))>1) and
1189 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or
1190 self.conform.get_fn_presence('/'.join((t,ITEM_FIELD_NAME))) or self.conform.check_item('FN_PARS', '/'.join((t,ITEM_FIELD_NAME)))) and
1191 not self.conform.check_item('TYPE_RENAME', t))):
1192 if len(t.split('/')) == 2 and t.split('/')[1] == ITEM_FIELD_NAME: # Sequence of type at the 1st level
1193 nm = t.split('/')[0] + t.split('/')[1]
1194 elif t.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type at next levels
1195 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
1196 elif t.split('/')[-1] == UNTAG_TYPE_NAME: # Untagged type
1197 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
1198 else:
1199 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
1200 nm = asn2c(nm)
1201 if nm in self.eth_type:
1202 if nm in self.eth_type_dupl:
1203 self.eth_type_dupl[nm].append(t)
1204 else:
1205 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
1206 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
1207 if nm in self.eth_type:
1208 self.eth_type[nm]['ref'].append(t)
1209 else:
1210 self.eth_type_ord.append(nm)
1211 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0, 'vals_ext' : 0,
1212 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
1213 'val' : self.type[t]['val'],
1214 'attr' : {}, 'ref' : [t]}
1215 self.type[t]['ethname'] = nm
1216 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
1217 self.eth_export_ord.append(nm)
1218 self.eth_type[nm]['export'] |= self.type[t]['export']
1219 self.eth_type[nm]['enum'] |= self.type[t]['enum']
1220 self.eth_type[nm]['vals_ext'] |= self.type[t]['vals_ext']
1221 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
1222 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
1223 if self.type[t]['attr'].get('STRINGS') == '$$':
1224 use_ext = self.type[t]['vals_ext']
1225 if (use_ext):
1226 self.eth_type[nm]['attr']['STRINGS'] = '&%s_ext' % (self.eth_vals_nm(nm))
1227 else:
1228 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
1229 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1230 for t in self.eth_type_ord:
1231 bits = self.eth_type[t]['val'].eth_named_bits()
1232 if (bits):
1233 for (val, id) in bits:
1234 self.named_bit.append({'name' : id, 'val' : val,
1235 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
1236 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1237 'strings' : 'NULL',
1238 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
1239 if self.eth_type[t]['val'].eth_need_tree():
1240 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
1241 else:
1242 self.eth_type[t]['tree'] = None
1244 #--- register values from enums ------------
1245 for t in self.eth_type_ord:
1246 if (self.eth_type[t]['val'].eth_has_enum(t, self)):
1247 self.eth_type[t]['val'].reg_enum_vals(t, self)
1249 #--- value dependencies -------------------
1250 for v in self.value_ord:
1251 if isinstance (self.value[v]['value'], Value):
1252 dep = self.value[v]['value'].get_dep()
1253 else:
1254 dep = self.value[v]['value']
1255 if dep and dep in self.value:
1256 self.value_dep.setdefault(v, []).append(dep)
1258 #--- exports all necessary values
1259 for v in self.value_ord:
1260 if not self.value[v]['export']: continue
1261 deparr = self.value_dep.get(v, [])
1262 while deparr:
1263 d = deparr.pop()
1264 if not self.value[d]['import']:
1265 if not self.value[d]['export']:
1266 self.value[d]['export'] = EF_TYPE
1267 deparr.extend(self.value_dep.get(d, []))
1269 #--- values -------------------
1270 for v in self.value_imp:
1271 nm = asn2c(v)
1272 self.eth_value[nm] = { 'import' : self.value[v]['import'],
1273 'proto' : asn2c(self.value[v]['proto']),
1274 'ref' : []}
1275 self.value[v]['ethname'] = nm
1276 for v in self.value_ord:
1277 if (self.value[v]['ethname']):
1278 continue
1279 if (self.value[v]['no_emit']):
1280 continue
1281 nm = asn2c(v)
1282 self.eth_value[nm] = { 'import' : None,
1283 'proto' : asn2c(self.value[v]['proto']),
1284 'export' : self.value[v]['export'], 'ref' : [v] }
1285 self.eth_value[nm]['value'] = self.value[v]['value']
1286 self.eth_value_ord.append(nm)
1287 self.value[v]['ethname'] = nm
1289 #--- fields -------------------------
1290 for f in (self.pdu_ord + self.field_ord):
1291 if len(f.split('/')) > 1 and f.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type
1292 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
1293 else:
1294 nm = f.split('/')[-1]
1295 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
1296 nm = asn2c(nm)
1297 if (self.field[f]['pdu']):
1298 nm += '_PDU'
1299 if (not self.merge_modules or self.field[f]['pdu']['export']):
1300 nm = self.eproto + '_' + nm
1301 t = self.field[f]['type']
1302 if t in self.type:
1303 ethtype = self.type[t]['ethname']
1304 else: # undefined type
1305 ethtype = self.dummy_import_type(t)
1306 ethtypemod = ethtype + self.field[f]['modified']
1307 if nm in self.eth_hf:
1308 if nm in self.eth_hf_dupl:
1309 if ethtypemod in self.eth_hf_dupl[nm]:
1310 nm = self.eth_hf_dupl[nm][ethtypemod]
1311 self.eth_hf[nm]['ref'].append(f)
1312 self.field[f]['ethname'] = nm
1313 continue
1314 else:
1315 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
1316 self.eth_hf_dupl[nm][ethtype] = nmx
1317 nm = nmx
1318 else:
1319 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
1320 self.eth_hf[nm]['ref'].append(f)
1321 self.field[f]['ethname'] = nm
1322 continue
1323 else:
1324 nmx = nm + '_01'
1325 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
1326 ethtypemod : nmx}
1327 nm = nmx
1328 if (self.field[f]['pdu']):
1329 self.eth_hfpdu_ord.append(nm)
1330 else:
1331 self.eth_hf_ord.append(nm)
1332 fullname = 'hf_%s_%s' % (self.eproto, nm)
1333 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
1334 attr.update(self.field[f]['attr'])
1335 if (self.NAPI() and 'NAME' in attr):
1336 attr['NAME'] += self.field[f]['idx']
1337 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
1338 use_vals_ext = self.eth_type[ethtype].get('vals_ext')
1339 if (use_vals_ext):
1340 attr['DISPLAY'] += '|BASE_EXT_STRING'
1341 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
1342 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
1343 'attr' : attr.copy(),
1344 'ref' : [f]}
1345 self.field[f]['ethname'] = nm
1346 if (self.dummy_eag_field):
1347 self.dummy_eag_field = '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
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)
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
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
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
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
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
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
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
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
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
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
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')
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
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')
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
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')
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
1555 #--- eth_out_pdu_decl ----------------------------------------------------------
1556 def eth_out_pdu_decl(self, f):
1557 t = self.eth_hf[f]['ethtype']
1558 is_new = self.eth_hf[f]['pdu']['new']
1559 out = ''
1560 if (not self.eth_hf[f]['pdu']['export']):
1561 out += 'static '
1562 if (is_new):
1563 out += 'int '
1564 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n'
1565 else:
1566 out += 'void '
1567 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);\n'
1568 return out
1570 #--- eth_output_hf ----------------------------------------------------------
1571 def eth_output_hf (self):
1572 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1573 fx = self.output.file_open('hf')
1574 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1575 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1576 if (self.named_bit):
1577 fx.write('/* named bits */\n')
1578 for nb in self.named_bit:
1579 fx.write("static int %s = -1;\n" % (nb['ethname']))
1580 if (self.dummy_eag_field):
1581 fx.write("static int %s = -1; /* never registered */ \n" % (self.dummy_eag_field))
1582 self.output.file_close(fx)
1584 #--- eth_output_hf_arr ------------------------------------------------------
1585 def eth_output_hf_arr (self):
1586 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1587 fx = self.output.file_open('hfarr')
1588 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1589 t = self.eth_hf[f]['ethtype']
1590 if self.remove_prefix and t.startswith(self.remove_prefix):
1591 t = t[len(self.remove_prefix):]
1592 name=self.eth_hf[f]['attr']['NAME']
1593 try: # Python < 3
1594 trantab = maketrans("- ", "__")
1595 except:
1596 trantab = str.maketrans("- ", "__")
1597 name = name.translate(trantab)
1598 namelower = name.lower()
1599 tquoted_lower = '"' + t.lower() + '"'
1600 # Try to avoid giving blurbs that give no more info than the name
1601 if tquoted_lower == namelower or \
1602 t == "NULL" or \
1603 tquoted_lower.replace("t_", "") == namelower:
1604 blurb = 'NULL'
1605 else:
1606 blurb = '"%s"' % (t)
1607 attr = self.eth_hf[f]['attr'].copy()
1608 if attr['TYPE'] == 'FT_NONE':
1609 attr['ABBREV'] = '"%s.%s_element"' % (self.proto, attr['ABBREV'])
1610 else:
1611 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1612 if 'BLURB' not in attr:
1613 attr['BLURB'] = blurb
1614 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1615 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1616 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1617 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1618 for nb in self.named_bit:
1619 fx.write(' { &%s,\n' % (nb['ethname']))
1620 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1621 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1622 fx.write(' NULL, HFILL }},\n')
1623 self.output.file_close(fx)
1625 #--- eth_output_ett ---------------------------------------------------------
1626 def eth_output_ett (self):
1627 fx = self.output.file_open('ett')
1628 fempty = True
1629 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1630 for t in self.eth_type_ord:
1631 if self.eth_type[t]['tree']:
1632 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1633 fempty = False
1634 self.output.file_close(fx, discard=fempty)
1636 #--- eth_output_ett_arr -----------------------------------------------------
1637 def eth_output_ett_arr(self):
1638 fx = self.output.file_open('ettarr')
1639 fempty = True
1640 #fx.write(" &ett_%s,\n" % (self.eproto))
1641 for t in self.eth_type_ord:
1642 if self.eth_type[t]['tree']:
1643 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1644 fempty = False
1645 self.output.file_close(fx, discard=fempty)
1647 #--- eth_output_export ------------------------------------------------------
1648 def eth_output_export(self):
1649 fx = self.output.file_open('exp', ext='h')
1650 for t in self.eth_export_ord: # vals
1651 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1652 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1653 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1654 if not self.eth_type[t]['export'] & EF_TABLE:
1655 if self.eth_type[t]['export'] & EF_WS_DLL:
1656 fx.write("WS_DLL_PUBLIC ")
1657 else:
1658 fx.write("extern ")
1659 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1660 else:
1661 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1662 for t in self.eth_export_ord: # functions
1663 if (self.eth_type[t]['export'] & EF_TYPE):
1664 if self.eth_type[t]['export'] & EF_EXTERN:
1665 if self.eth_type[t]['export'] & EF_WS_DLL:
1666 fx.write("WS_DLL_PUBLIC ")
1667 else:
1668 fx.write("extern ")
1669 fx.write(self.eth_type_fn_h(t))
1670 for f in self.eth_hfpdu_ord: # PDUs
1671 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']):
1672 fx.write(self.eth_out_pdu_decl(f))
1673 self.output.file_close(fx)
1675 #--- eth_output_expcnf ------------------------------------------------------
1676 def eth_output_expcnf(self):
1677 fx = self.output.file_open('exp', ext='cnf')
1678 fx.write('#.MODULE\n')
1679 maxw = 0
1680 for (m, p) in self.modules:
1681 if (len(m) > maxw): maxw = len(m)
1682 for (m, p) in self.modules:
1683 fx.write("%-*s %s\n" % (maxw, m, p))
1684 fx.write('#.END\n\n')
1685 for cls in self.objectclass_ord:
1686 if self.objectclass[cls]['export']:
1687 cnm = cls
1688 if self.objectclass[cls]['export'] & EF_MODULE:
1689 cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm)
1690 fx.write('#.CLASS %s\n' % (cnm))
1691 maxw = 2
1692 for fld in self.objectclass[cls]['val'].fields:
1693 w = len(fld.fld_repr()[0])
1694 if (w > maxw): maxw = w
1695 for fld in self.objectclass[cls]['val'].fields:
1696 repr = fld.fld_repr()
1697 fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:])))
1698 fx.write('#.END\n\n')
1699 if self.Ber():
1700 fx.write('#.IMPORT_TAG\n')
1701 for t in self.eth_export_ord: # tags
1702 if (self.eth_type[t]['export'] & EF_TYPE):
1703 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1704 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1705 fx.write('#.END\n\n')
1706 fx.write('#.TYPE_ATTR\n')
1707 for t in self.eth_export_ord: # attributes
1708 if (self.eth_type[t]['export'] & EF_TYPE):
1709 tnm = self.eth_type[t]['ref'][0]
1710 if self.eth_type[t]['export'] & EF_MODULE:
1711 tnm = "$%s$%s" % (self.type[tnm]['module'], tnm)
1712 fx.write('%-24s ' % tnm)
1713 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1714 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1715 fx.write('#.END\n\n')
1716 self.output.file_close(fx, keep_anyway=True)
1718 #--- eth_output_val ------------------------------------------------------
1719 def eth_output_val(self):
1720 fx = self.output.file_open('val', ext='h')
1721 for v in self.eth_value_ord1:
1722 vv = self.eth_value[v]['value']
1723 if isinstance (vv, Value):
1724 vv = vv.to_str(self)
1725 fx.write("#define %-30s %s\n" % (v, vv))
1726 for t in self.eth_type_ord1:
1727 if self.eth_type[t]['import']:
1728 continue
1729 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1730 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1731 self.output.file_close(fx)
1733 #--- eth_output_valexp ------------------------------------------------------
1734 def eth_output_valexp(self):
1735 if (not len(self.eth_vexport_ord)): return
1736 fx = self.output.file_open('valexp', ext='h')
1737 for v in self.eth_vexport_ord:
1738 vv = self.eth_value[v]['value']
1739 if isinstance (vv, Value):
1740 vv = vv.to_str(self)
1741 fx.write("#define %-30s %s\n" % (v, vv))
1742 self.output.file_close(fx)
1744 #--- eth_output_types -------------------------------------------------------
1745 def eth_output_types(self):
1746 def out_pdu(f):
1747 t = self.eth_hf[f]['ethtype']
1748 is_new = self.eth_hf[f]['pdu']['new']
1749 impl = 'FALSE'
1750 out = ''
1751 if (not self.eth_hf[f]['pdu']['export']):
1752 out += 'static '
1753 if (is_new):
1754 out += 'int '
1755 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n'
1756 else:
1757 out += 'void '
1758 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1759 if (is_new):
1760 out += ' int offset = 0;\n'
1761 off_par = 'offset'
1762 ret_par = 'offset'
1763 else:
1764 off_par = '0'
1765 ret_par = None
1766 if (self.Per()):
1767 if (self.Aligned()):
1768 aligned = 'TRUE'
1769 else:
1770 aligned = 'FALSE'
1771 out += " asn1_ctx_t asn1_ctx;\n"
1772 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1773 if (self.Ber()):
1774 out += " asn1_ctx_t asn1_ctx;\n"
1775 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
1776 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1777 elif (self.Per()):
1778 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1779 else:
1780 par=((),)
1781 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1782 if (self.Per() and is_new):
1783 out += ' offset += 7; offset >>= 3;\n'
1784 if (is_new):
1785 out += ' return offset;\n'
1786 out += '}\n'
1787 return out
1788 #end out_pdu()
1789 fx = self.output.file_open('fn')
1790 pos = fx.tell()
1791 if (len(self.eth_hfpdu_ord)):
1792 first_decl = True
1793 for f in self.eth_hfpdu_ord:
1794 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
1795 if first_decl:
1796 fx.write('/*--- PDUs declarations ---*/\n')
1797 first_decl = False
1798 fx.write(self.eth_out_pdu_decl(f))
1799 if not first_decl:
1800 fx.write('\n')
1801 if self.eth_dep_cycle:
1802 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1803 i = 0
1804 while i < len(self.eth_dep_cycle):
1805 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1806 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1807 fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]]))
1808 fx.write(self.eth_type_fn_h(t))
1809 fx.write('\n')
1810 i += 1
1811 fx.write('\n')
1812 for t in self.eth_type_ord1:
1813 if self.eth_type[t]['import']:
1814 continue
1815 if self.eth_type[t]['val'].eth_has_vals():
1816 if self.eth_type[t]['no_emit'] & EF_VALS:
1817 pass
1818 elif self.eth_type[t]['user_def'] & EF_VALS:
1819 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1820 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1821 pass
1822 else:
1823 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1824 if self.eth_type[t]['no_emit'] & EF_TYPE:
1825 pass
1826 elif self.eth_type[t]['user_def'] & EF_TYPE:
1827 fx.write(self.eth_type_fn_h(t))
1828 else:
1829 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1830 fx.write('\n')
1831 if (len(self.eth_hfpdu_ord)):
1832 fx.write('/*--- PDUs ---*/\n\n')
1833 for f in self.eth_hfpdu_ord:
1834 if (self.eth_hf[f]['pdu']):
1835 if (f in self.emitted_pdu):
1836 fx.write(" /* %s already emitted */\n" % (f))
1837 else:
1838 fx.write(out_pdu(f))
1839 self.emitted_pdu[f] = True
1840 fx.write('\n')
1841 fempty = pos == fx.tell()
1842 self.output.file_close(fx, discard=fempty)
1844 #--- eth_output_dis_hnd -----------------------------------------------------
1845 def eth_output_dis_hnd(self):
1846 fx = self.output.file_open('dis-hnd')
1847 fempty = True
1848 for f in self.eth_hfpdu_ord:
1849 pdu = self.eth_hf[f]['pdu']
1850 if (pdu and pdu['reg'] and not pdu['hidden']):
1851 dis = self.proto
1852 if (pdu['reg'] != '.'):
1853 dis += '.' + pdu['reg']
1854 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1855 fempty = False
1856 fx.write('\n')
1857 self.output.file_close(fx, discard=fempty)
1859 #--- eth_output_dis_reg -----------------------------------------------------
1860 def eth_output_dis_reg(self):
1861 fx = self.output.file_open('dis-reg')
1862 fempty = True
1863 for f in self.eth_hfpdu_ord:
1864 pdu = self.eth_hf[f]['pdu']
1865 if (pdu and pdu['reg']):
1866 new_prefix = ''
1867 if (pdu['new']): new_prefix = 'new_'
1868 dis = self.proto
1869 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1870 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1871 if (not pdu['hidden']):
1872 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1873 fempty = False
1874 fx.write('\n')
1875 self.output.file_close(fx, discard=fempty)
1877 #--- eth_output_dis_tab -----------------------------------------------------
1878 def eth_output_dis_tab(self):
1879 fx = self.output.file_open('dis-tab')
1880 fempty = True
1881 for k in self.conform.get_order('REGISTER'):
1882 reg = self.conform.use_item('REGISTER', k)
1883 if reg['pdu'] not in self.field: continue
1884 f = self.field[reg['pdu']]['ethname']
1885 pdu = self.eth_hf[f]['pdu']
1886 new_prefix = ''
1887 if (pdu['new']): new_prefix = 'new_'
1888 if (reg['rtype'] in ('NUM', 'STR')):
1889 rstr = ''
1890 if (reg['rtype'] == 'STR'):
1891 rstr = 'string'
1892 else:
1893 rstr = 'uint'
1894 if (pdu['reg']):
1895 dis = self.proto
1896 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1897 if (not pdu['hidden']):
1898 hnd = '%s_handle' % (asn2c(dis))
1899 else:
1900 hnd = 'find_dissector("%s")' % (dis)
1901 else:
1902 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1903 rport = self.value_get_eth(reg['rport'])
1904 fx.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
1905 elif (reg['rtype'] in ('BER', 'PER')):
1906 roid = self.value_get_eth(reg['roid'])
1907 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
1908 fempty = False
1909 fx.write('\n')
1910 self.output.file_close(fx, discard=fempty)
1912 #--- eth_output_syn_reg -----------------------------------------------------
1913 def eth_output_syn_reg(self):
1914 fx = self.output.file_open('syn-reg')
1915 fempty = True
1916 first_decl = True
1917 for k in self.conform.get_order('SYNTAX'):
1918 reg = self.conform.use_item('SYNTAX', k)
1919 if first_decl:
1920 fx.write(' /*--- Syntax registrations ---*/\n')
1921 first_decl = False
1922 fx.write(' register_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (k, self.eproto, reg['pdu']));
1923 fempty=False
1924 self.output.file_close(fx, discard=fempty)
1926 #--- eth_output_tables -----------------------------------------------------
1927 def eth_output_tables(self):
1928 for num in list(self.conform.report.keys()):
1929 fx = self.output.file_open('table' + num)
1930 for rep in self.conform.report[num]:
1931 self.eth_output_table(fx, rep)
1932 self.output.file_close(fx)
1934 #--- eth_output_table -----------------------------------------------------
1935 def eth_output_table(self, fx, rep):
1936 def cmp_fn(a, b, cmp_flds, objs):
1937 if not cmp_flds: return 0
1938 obja = objs[a]
1939 objb = objs[b]
1940 res = 0
1941 for f in cmp_flds:
1942 if f[0] == '#':
1943 f = f[1:]
1944 res = int(obja[f]) - int(objb[f])
1945 else:
1946 res = cmp(obja[f], objb[f])
1947 if res: break
1948 return res
1949 if rep['type'] == 'HDR':
1950 fx.write('\n')
1951 if rep['var']:
1952 var = rep['var']
1953 var_list = var.split('.', 1)
1954 cls = var_list[0]
1955 del var_list[0]
1956 flds = []
1957 not_flds = []
1958 sort_flds = []
1959 for f in var_list:
1960 if f[0] == '!':
1961 not_flds.append(f[1:])
1962 continue
1963 if f[0] == '#':
1964 flds.append(f[1:])
1965 sort_flds.append(f)
1966 continue
1967 if f[0] == '@':
1968 flds.append(f[1:])
1969 sort_flds.append(f[1:])
1970 continue
1971 flds.append(f)
1972 objs = {}
1973 objs_ord = []
1974 if (cls in self.oassign_cls):
1975 for ident in self.oassign_cls[cls]:
1976 obj = self.get_obj_repr(ident, flds, not_flds)
1977 if not obj:
1978 continue
1979 obj['_LOOP'] = var
1980 obj['_DICT'] = str(obj)
1981 objs[ident] = obj
1982 objs_ord.append(ident)
1983 if (sort_flds):
1984 objs_ord.sort(cmp=partial(cmp_fn, cmp_flds=sort_flds, objs=objs))
1985 for ident in objs_ord:
1986 obj = objs[ident]
1987 try:
1988 text = rep['text'] % obj
1989 except (KeyError):
1990 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))
1991 fx.write(text)
1992 else:
1993 fx.write("/* Unknown or empty loop list %s */\n" % (var))
1994 else:
1995 fx.write(rep['text'])
1996 if rep['type'] == 'FTR':
1997 fx.write('\n')
1999 #--- dupl_report -----------------------------------------------------
2000 def dupl_report(self):
2001 # types
2002 tmplist = sorted(self.eth_type_dupl.keys())
2003 for t in tmplist:
2004 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
2005 msg += t + "\n"
2006 for tt in self.eth_type_dupl[t]:
2007 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
2008 warnings.warn_explicit(msg, UserWarning, '', 0)
2009 # fields
2010 tmplist = list(self.eth_hf_dupl.keys())
2011 tmplist.sort()
2012 for f in tmplist:
2013 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
2014 msg += f + "\n"
2015 for tt in list(self.eth_hf_dupl[f].keys()):
2016 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
2017 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
2018 msg += "\n"
2019 warnings.warn_explicit(msg, UserWarning, '', 0)
2021 #--- eth_do_output ------------------------------------------------------------
2022 def eth_do_output(self):
2023 if self.dbg('a'):
2024 print("\n# Assignments")
2025 for a in self.assign_ord:
2026 v = ' '
2027 if (self.assign[a]['virt']): v = '*'
2028 print(v, a)
2029 print("\n# Value assignments")
2030 for a in self.vassign_ord:
2031 print(' ', a)
2032 print("\n# Information object assignments")
2033 for a in self.oassign_ord:
2034 print(" %-12s (%s)" % (a, self.oassign[a].cls))
2035 if self.dbg('t'):
2036 print("\n# Imported Types")
2037 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2038 print("-" * 100)
2039 for t in self.type_imp:
2040 print("%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto']))
2041 print("\n# Imported Values")
2042 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2043 print("-" * 100)
2044 for t in self.value_imp:
2045 print("%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto']))
2046 print("\n# Imported Object Classes")
2047 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2048 print("-" * 100)
2049 for t in self.objectclass_imp:
2050 print("%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto']))
2051 print("\n# Exported Types")
2052 print("%-31s %s" % ("Wireshark type", "Export Flag"))
2053 print("-" * 100)
2054 for t in self.eth_export_ord:
2055 print("%-31s 0x%02X" % (t, self.eth_type[t]['export']))
2056 print("\n# Exported Values")
2057 print("%-40s %s" % ("Wireshark name", "Value"))
2058 print("-" * 100)
2059 for v in self.eth_vexport_ord:
2060 vv = self.eth_value[v]['value']
2061 if isinstance (vv, Value):
2062 vv = vv.to_str(self)
2063 print("%-40s %s" % (v, vv))
2064 print("\n# ASN.1 Object Classes")
2065 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2066 print("-" * 100)
2067 for t in self.objectclass_ord:
2068 print("%-40s " % (t))
2069 print("\n# ASN.1 Types")
2070 print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type"))
2071 print("-" * 100)
2072 for t in self.type_ord:
2073 print("%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname']))
2074 print("\n# Wireshark Types")
2075 print("Wireshark type References (ASN.1 types)")
2076 print("-" * 100)
2077 for t in self.eth_type_ord:
2078 sys.stdout.write("%-31s %d" % (t, len(self.eth_type[t]['ref'])))
2079 print(', '.join(self.eth_type[t]['ref']))
2080 print("\n# ASN.1 Values")
2081 print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value"))
2082 print("-" * 100)
2083 for v in self.value_ord:
2084 vv = self.value[v]['value']
2085 if isinstance (vv, Value):
2086 vv = vv.to_str(self)
2087 print("%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname']))
2088 #print "\n# Wireshark Values"
2089 #print "%-40s %s" % ("Wireshark name", "Value")
2090 #print "-" * 100
2091 #for v in self.eth_value_ord:
2092 # vv = self.eth_value[v]['value']
2093 # if isinstance (vv, Value):
2094 # vv = vv.to_str(self)
2095 # print "%-40s %s" % (v, vv)
2096 print("\n# ASN.1 Fields")
2097 print("ASN.1 unique name Wireshark name ASN.1 type")
2098 print("-" * 100)
2099 for f in (self.pdu_ord + self.field_ord):
2100 print("%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type']))
2101 print("\n# Wireshark Fields")
2102 print("Wireshark name Wireshark type References (ASN.1 fields)")
2103 print("-" * 100)
2104 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
2105 sys.stdout.write("%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])))
2106 print(', '.join(self.eth_hf[f]['ref']))
2107 #print "\n# Order after dependencies"
2108 #print '\n'.join(self.eth_type_ord1)
2109 print("\n# Cyclic dependencies")
2110 for c in self.eth_dep_cycle:
2111 print(' -> '.join(c))
2112 self.dupl_report()
2113 self.output.outnm = self.outnm_opt
2114 if (not self.output.outnm):
2115 self.output.outnm = self.proto
2116 self.output.outnm = self.output.outnm.replace('.', '-')
2117 if not self.justexpcnf:
2118 self.eth_output_hf()
2119 self.eth_output_ett()
2120 self.eth_output_types()
2121 self.eth_output_hf_arr()
2122 self.eth_output_ett_arr()
2123 self.eth_output_export()
2124 self.eth_output_val()
2125 self.eth_output_valexp()
2126 self.eth_output_dis_hnd()
2127 self.eth_output_dis_reg()
2128 self.eth_output_dis_tab()
2129 self.eth_output_syn_reg()
2130 self.eth_output_tables()
2131 if self.expcnf:
2132 self.eth_output_expcnf()
2134 def dbg_modules(self):
2135 def print_mod(m):
2136 sys.stdout.write("%-30s " % (m))
2137 dep = self.module[m][:]
2138 for i in range(len(dep)):
2139 if dep[i] not in self.module:
2140 dep[i] = '*' + dep[i]
2141 print(', '.join(dep))
2142 # end of print_mod()
2143 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module)
2144 print("\n# ASN.1 Moudules")
2145 print("Module name Dependency")
2146 print("-" * 100)
2147 new_ord = False
2148 for m in (self.module_ord):
2149 print_mod(m)
2150 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
2151 if new_ord:
2152 print("\n# ASN.1 Moudules - in dependency order")
2153 print("Module name Dependency")
2154 print("-" * 100)
2155 for m in (mod_ord):
2156 print_mod(m)
2157 if mod_cyc:
2158 print("\nCyclic dependencies:")
2159 for i in (list(range(len(mod_cyc)))):
2160 print("%02d: %s" % (i + 1, str(mod_cyc[i])))
2163 #--- EthCnf -------------------------------------------------------------------
2164 class EthCnf:
2165 def __init__(self):
2166 self.ectx = None
2167 self.tblcfg = {}
2168 self.table = {}
2169 self.order = {}
2170 self.fn = {}
2171 self.report = {}
2172 self.suppress_line = False
2173 self.include_path = []
2174 # Value name Default value Duplicity check Usage check
2175 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2176 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2177 self.tblcfg['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2178 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2179 self.tblcfg['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2180 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2181 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2182 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2183 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2184 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2185 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2186 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2187 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2188 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2189 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2190 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2191 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2192 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2193 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2194 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2195 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2196 self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2197 self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2199 for k in list(self.tblcfg.keys()) :
2200 self.table[k] = {}
2201 self.order[k] = []
2203 def add_item(self, table, key, fn, lineno, **kw):
2204 if self.tblcfg[table]['chk_dup'] and key in self.table[table]:
2205 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2206 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
2207 UserWarning, fn, lineno)
2208 return
2209 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2210 self.table[table][key].update(kw)
2211 self.order[table].append(key)
2213 def update_item(self, table, key, fn, lineno, **kw):
2214 if key not in self.table[table]:
2215 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2216 self.order[table].append(key)
2217 self.table[table][key][self.tblcfg[table]['val_nm']] = {}
2218 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
2220 def get_order(self, table):
2221 return self.order[table]
2223 def check_item(self, table, key):
2224 return key in self.table[table]
2226 def copy_item(self, table, dst_key, src_key):
2227 if (src_key in self.table[table]):
2228 self.table[table][dst_key] = self.table[table][src_key]
2230 def check_item_value(self, table, key, **kw):
2231 return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key]
2233 def use_item(self, table, key, **kw):
2234 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
2235 if key not in self.table[table]: return vdflt
2236 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
2237 #print "use_item() - set used for %s %s" % (table, key)
2238 self.table[table][key]['used'] = True
2239 return self.table[table][key].get(vname, vdflt)
2241 def omit_assignment(self, type, ident, module):
2242 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
2243 return True
2244 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
2245 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2246 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
2247 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
2248 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
2249 return False
2251 def add_fn_line(self, name, ctx, line, fn, lineno):
2252 if name not in self.fn:
2253 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2254 if (self.fn[name][ctx]):
2255 self.fn[name][ctx]['text'] += line
2256 else:
2257 self.fn[name][ctx] = {'text' : line, 'used' : False,
2258 'fn' : fn, 'lineno' : lineno}
2259 def get_fn_presence(self, name):
2260 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2261 #if self.fn.has_key(name): print self.fn[name]
2262 return name in self.fn
2263 def get_fn_body_presence(self, name):
2264 return name in self.fn and self.fn[name]['FN_BODY']
2265 def get_fn_text(self, name, ctx):
2266 if (name not in self.fn):
2267 return '';
2268 if (not self.fn[name][ctx]):
2269 return '';
2270 self.fn[name][ctx]['used'] = True
2271 out = self.fn[name][ctx]['text']
2272 if (not self.suppress_line):
2273 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], rel_dissector_path(self.fn[name][ctx]['fn']), out);
2274 return out
2276 def add_pdu(self, par, is_new, fn, lineno):
2277 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2278 (reg, hidden) = (None, False)
2279 if (len(par) > 1): reg = par[1]
2280 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
2281 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False}
2282 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
2283 return
2285 def add_syntax(self, par, fn, lineno):
2286 #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno)
2287 if( (len(par) >=2)):
2288 name = par[1]
2289 else:
2290 name = '"'+par[0]+'"'
2291 attr = { 'pdu' : par[0] }
2292 self.add_item('SYNTAX', name, attr=attr, fn=fn, lineno=lineno)
2293 return
2295 def add_register(self, pdu, par, fn, lineno):
2296 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2297 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
2298 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
2299 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
2300 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
2301 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
2302 if ((len(par)-1) < pmin):
2303 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
2304 return
2305 if ((len(par)-1) > pmax):
2306 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
2307 attr = {'pdu' : pdu, 'rtype' : rtype}
2308 if (rtype in ('NUM', 'STR')):
2309 attr['rtable'] = par[1]
2310 attr['rport'] = par[2]
2311 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
2312 elif (rtype in ('BER', 'PER')):
2313 attr['roid'] = par[1]
2314 attr['roidname'] = '""'
2315 if (len(par)>=3):
2316 attr['roidname'] = par[2]
2317 elif attr['roid'][0] != '"':
2318 attr['roidname'] = '"' + attr['roid'] + '"'
2319 rkey = '/'.join([rtype, attr['roid']])
2320 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
2322 def check_par(self, par, pmin, pmax, fn, lineno):
2323 for i in range(len(par)):
2324 if par[i] == '-':
2325 par[i] = None
2326 continue
2327 if par[i][0] == '#':
2328 par[i:] = []
2329 break
2330 if len(par) < pmin:
2331 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2332 return None
2333 if (pmax >= 0) and (len(par) > pmax):
2334 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
2335 return par[0:pmax]
2336 return par
2338 def read(self, fn):
2339 def get_par(line, pmin, pmax, fn, lineno):
2340 par = line.split(None, pmax)
2341 par = self.check_par(par, pmin, pmax, fn, lineno)
2342 return par
2344 def get_par_nm(line, pmin, pmax, fn, lineno):
2345 if pmax:
2346 par = line.split(None, pmax)
2347 else:
2348 par = [line,]
2349 for i in range(len(par)):
2350 if par[i][0] == '#':
2351 par[i:] = []
2352 break
2353 if len(par) < pmin:
2354 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2355 return None
2356 if len(par) > pmax:
2357 nmpar = par[pmax]
2358 else:
2359 nmpar = ''
2360 nmpars = {}
2361 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2362 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2363 nmpar_end = re.compile(r'\s*$')
2364 result = nmpar_first.search(nmpar)
2365 pos = 0
2366 while result:
2367 k = result.group('attr')
2368 pos = result.end()
2369 result = nmpar_next.search(nmpar, pos)
2370 p1 = pos
2371 if result:
2372 p2 = result.start()
2373 else:
2374 p2 = nmpar_end.search(nmpar, pos).start()
2375 v = nmpar[p1:p2]
2376 nmpars[k] = v
2377 if len(par) > pmax:
2378 par[pmax] = nmpars
2379 return par
2381 f = open(fn, "r")
2382 lineno = 0
2383 is_import = False
2384 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2385 cdirective = re.compile(r'^\s*##')
2386 report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2387 comment = re.compile(r'^\s*#[^.#]')
2388 empty = re.compile(r'^\s*$')
2389 ctx = None
2390 name = ''
2391 default_flags = 0x00
2392 stack = []
2393 while True:
2394 if not f.closed:
2395 line = f.readline()
2396 lineno += 1
2397 else:
2398 line = None
2399 if not line:
2400 if not f.closed:
2401 f.close()
2402 if stack:
2403 frec = stack.pop()
2404 fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import']
2405 continue
2406 else:
2407 break
2408 if comment.search(line): continue
2409 result = directive.search(line)
2410 if result: # directive
2411 rep_result = report.search(result.group('name'))
2412 if result.group('name') == 'END_OF_CNF':
2413 f.close()
2414 elif result.group('name') == 'OPT':
2415 ctx = result.group('name')
2416 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
2417 if not par: continue
2418 self.set_opt(par[0], par[1:], fn, lineno)
2419 ctx = None
2420 elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
2421 'MODULE', 'MODULE_IMPORT',
2422 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2423 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2424 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2425 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR', 'SYNTAX'):
2426 ctx = result.group('name')
2427 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2428 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2429 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2430 ctx = result.group('name')
2431 key = '*'
2432 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2433 key += 'T'
2434 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2435 key += 'V'
2436 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2437 if par:
2438 key += '/' + par[0]
2439 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
2440 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2441 ctx = 'NO_OMIT_ASSGN'
2442 else:
2443 ctx = None
2444 elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2445 ctx = result.group('name')
2446 default_flags = EF_TYPE|EF_VALS
2447 if ctx == 'MODULE_EXPORTS':
2448 ctx = 'EXPORTS'
2449 default_flags |= EF_MODULE
2450 if ctx == 'EXPORTS':
2451 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
2452 else:
2453 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2454 if not par: continue
2455 p = 1
2456 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
2457 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
2458 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
2459 elif (ctx == 'EXPORTS'): p = 0
2460 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
2461 for i in range(p, len(par)):
2462 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
2463 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
2464 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
2465 elif (par[i] == 'WS_DLL'): default_flags |= EF_WS_DLL
2466 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
2467 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2468 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2469 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2470 ctx = result.group('name')
2471 default_flags = EF_ENUM
2472 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
2473 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2474 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
2475 for i in range(0, len(par)):
2476 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2477 elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT
2478 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
2479 elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE
2480 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
2481 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
2482 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2483 elif result.group('name') == 'USE_VALS_EXT':
2484 ctx = result.group('name')
2485 default_flags = 0xFF
2486 elif result.group('name') == 'FN_HDR':
2487 minp = 1
2488 if (ctx in ('FN_PARS',)) and name: minp = 0
2489 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2490 if (not par) and (minp > 0): continue
2491 ctx = result.group('name')
2492 if par: name = par[0]
2493 elif result.group('name') == 'FN_FTR':
2494 minp = 1
2495 if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0
2496 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2497 if (not par) and (minp > 0): continue
2498 ctx = result.group('name')
2499 if par: name = par[0]
2500 elif result.group('name') == 'FN_BODY':
2501 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2502 if not par: continue
2503 ctx = result.group('name')
2504 name = par[0]
2505 if len(par) > 1:
2506 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
2507 elif result.group('name') == 'FN_PARS':
2508 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2509 ctx = result.group('name')
2510 if not par:
2511 name = None
2512 elif len(par) == 1:
2513 name = par[0]
2514 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
2515 elif len(par) > 1:
2516 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2517 ctx = None
2518 elif result.group('name') == 'CLASS':
2519 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2520 if not par: continue
2521 ctx = result.group('name')
2522 name = par[0]
2523 add_class_ident(name)
2524 if not name.split('$')[-1].isupper():
2525 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
2526 UserWarning, fn, lineno)
2527 elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2528 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2529 if not par: continue
2530 self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno)
2531 elif rep_result: # Reports
2532 num = rep_result.group('num')
2533 type = rep_result.group('type')
2534 if type == 'BODY':
2535 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2536 if not par: continue
2537 else:
2538 par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno)
2539 rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno }
2540 if len(par) > 0:
2541 rep['var'] = par[0]
2542 self.report.setdefault(num, []).append(rep)
2543 ctx = 'TABLE'
2544 name = num
2545 elif result.group('name') in ('INCLUDE', 'IMPORT') :
2546 is_imp = result.group('name') == 'IMPORT'
2547 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2548 if not par:
2549 warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno)
2550 continue
2551 fname = par[0]
2552 #print "Try include: %s" % (fname)
2553 if (not os.path.exists(fname)):
2554 fname = os.path.join(os.path.split(fn)[0], par[0])
2555 #print "Try include: %s" % (fname)
2556 i = 0
2557 while not os.path.exists(fname) and (i < len(self.include_path)):
2558 fname = os.path.join(self.include_path[i], par[0])
2559 #print "Try include: %s" % (fname)
2560 i += 1
2561 if (not os.path.exists(fname)):
2562 if is_imp:
2563 continue # just ignore
2564 else:
2565 fname = par[0] # report error
2566 fnew = open(fname, "r")
2567 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import})
2568 fn, f, lineno, is_import = par[0], fnew, 0, is_imp
2569 elif result.group('name') == 'END':
2570 ctx = None
2571 else:
2572 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
2573 continue
2574 if not ctx:
2575 if not empty.match(line):
2576 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
2577 elif ctx == 'OPT':
2578 if empty.match(line): continue
2579 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
2580 if not par: continue
2581 self.set_opt(par[0], par[1:], fn, lineno)
2582 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2583 if empty.match(line): continue
2584 if ctx == 'EXPORTS':
2585 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
2586 else:
2587 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2588 if not par: continue
2589 flags = default_flags
2590 p = 2
2591 if (len(par)>=2):
2592 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
2593 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
2594 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
2595 elif (ctx == 'EXPORTS'): p = 1
2596 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
2597 for i in range(p, len(par)):
2598 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
2599 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
2600 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
2601 elif (par[i] == 'WS_DLL'): flags |= EF_WS_DLL
2602 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
2603 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2604 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2605 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
2606 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
2607 if empty.match(line): continue
2608 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
2609 if not par: continue
2610 flags = default_flags
2611 for i in range(1, len(par)):
2612 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2613 elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT
2614 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
2615 elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE
2616 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
2617 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
2618 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2619 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
2620 elif ctx == 'USE_VALS_EXT':
2621 if empty.match(line): continue
2622 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2623 if not par: continue
2624 flags = default_flags
2625 self.add_item('USE_VALS_EXT', par[0], flag=flags, fn=fn, lineno=lineno)
2626 elif ctx in ('PDU', 'PDU_NEW'):
2627 if empty.match(line): continue
2628 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
2629 if not par: continue
2630 is_new = False
2631 if (ctx == 'PDU_NEW'): is_new = True
2632 self.add_pdu(par[0:2], is_new, fn, lineno)
2633 if (len(par)>=3):
2634 self.add_register(par[0], par[2:5], fn, lineno)
2635 elif ctx in ('SYNTAX'):
2636 if empty.match(line): continue
2637 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2638 if not par: continue
2639 if not self.check_item('PDU', par[0]):
2640 self.add_pdu(par[0:1], False, fn, lineno)
2641 self.add_syntax(par, fn, lineno)
2642 elif ctx in ('REGISTER', 'REGISTER_NEW'):
2643 if empty.match(line): continue
2644 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
2645 if not par: continue
2646 if not self.check_item('PDU', par[0]):
2647 is_new = False
2648 if (ctx == 'REGISTER_NEW'): is_new = True
2649 self.add_pdu(par[0:1], is_new, fn, lineno)
2650 self.add_register(par[0], par[1:4], fn, lineno)
2651 elif ctx in ('MODULE', 'MODULE_IMPORT'):
2652 if empty.match(line): continue
2653 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2654 if not par: continue
2655 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
2656 elif ctx == 'IMPORT_TAG':
2657 if empty.match(line): continue
2658 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
2659 if not par: continue
2660 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
2661 elif ctx == 'OMIT_ASSIGNMENT':
2662 if empty.match(line): continue
2663 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2664 if not par: continue
2665 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
2666 elif ctx == 'NO_OMIT_ASSGN':
2667 if empty.match(line): continue
2668 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2669 if not par: continue
2670 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
2671 elif ctx == 'VIRTUAL_ASSGN':
2672 if empty.match(line): continue
2673 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
2674 if not par: continue
2675 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
2676 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
2677 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
2678 for nm in par[2:]:
2679 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
2680 if not par[0][0].isupper():
2681 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
2682 UserWarning, fn, lineno)
2683 elif ctx == 'SET_TYPE':
2684 if empty.match(line): continue
2685 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2686 if not par: continue
2687 if not self.check_item('VIRTUAL_ASSGN', par[0]):
2688 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
2689 if not par[1][0].isupper():
2690 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
2691 UserWarning, fn, lineno)
2692 elif ctx == 'ASSIGN_VALUE_TO_TYPE':
2693 if empty.match(line): continue
2694 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2695 if not par: continue
2696 self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno)
2697 elif ctx == 'TYPE_RENAME':
2698 if empty.match(line): continue
2699 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2700 if not par: continue
2701 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2702 if not par[1][0].isupper():
2703 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2704 UserWarning, fn, lineno)
2705 elif ctx == 'FIELD_RENAME':
2706 if empty.match(line): continue
2707 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2708 if not par: continue
2709 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2710 if not par[1][0].islower():
2711 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2712 UserWarning, fn, lineno)
2713 elif ctx == 'TF_RENAME':
2714 if empty.match(line): continue
2715 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2716 if not par: continue
2717 tmpu = par[1][0].upper() + par[1][1:]
2718 tmpl = par[1][0].lower() + par[1][1:]
2719 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
2720 if not tmpu[0].isupper():
2721 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2722 UserWarning, fn, lineno)
2723 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
2724 if not tmpl[0].islower():
2725 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2726 UserWarning, fn, lineno)
2727 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2728 if empty.match(line): continue
2729 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2730 if not par: continue
2731 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
2732 elif ctx == 'FN_PARS':
2733 if empty.match(line): continue
2734 if name:
2735 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
2736 else:
2737 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2738 if not par: continue
2739 if name:
2740 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
2741 else:
2742 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2743 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2744 result = cdirective.search(line)
2745 if result: # directive
2746 line = '#' + line[result.end():]
2747 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
2748 elif ctx == 'CLASS':
2749 if empty.match(line): continue
2750 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
2751 if not par: continue
2752 if not set_type_to_class(name, par[0], par[1:]):
2753 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
2754 UserWarning, fn, lineno)
2755 elif ctx == 'TABLE':
2756 self.report[name][-1]['text'] += line
2758 def set_opt(self, opt, par, fn, lineno):
2759 #print "set_opt: %s, %s" % (opt, par)
2760 if opt in ("-I",):
2761 par = self.check_par(par, 1, 1, fn, lineno)
2762 if not par: return
2763 self.include_path.append(par[0])
2764 elif opt in ("-b", "BER", "CER", "DER"):
2765 par = self.check_par(par, 0, 0, fn, lineno)
2766 self.ectx.encoding = 'ber'
2767 elif opt in ("PER",):
2768 par = self.check_par(par, 0, 0, fn, lineno)
2769 self.ectx.encoding = 'per'
2770 elif opt in ("-p", "PROTO"):
2771 par = self.check_par(par, 1, 1, fn, lineno)
2772 if not par: return
2773 self.ectx.proto_opt = par[0]
2774 self.ectx.merge_modules = True
2775 elif opt in ("ALIGNED",):
2776 par = self.check_par(par, 0, 0, fn, lineno)
2777 self.ectx.aligned = True
2778 elif opt in ("-u", "UNALIGNED"):
2779 par = self.check_par(par, 0, 0, fn, lineno)
2780 self.ectx.aligned = False
2781 elif opt in ("-d",):
2782 par = self.check_par(par, 1, 1, fn, lineno)
2783 if not par: return
2784 self.ectx.dbgopt = par[0]
2785 elif opt in ("-e",):
2786 par = self.check_par(par, 0, 0, fn, lineno)
2787 self.ectx.expcnf = True
2788 elif opt in ("-S",):
2789 par = self.check_par(par, 0, 0, fn, lineno)
2790 self.ectx.merge_modules = True
2791 elif opt in ("GROUP_BY_PROT",):
2792 par = self.check_par(par, 0, 0, fn, lineno)
2793 self.ectx.group_by_prot = True
2794 elif opt in ("-o",):
2795 par = self.check_par(par, 1, 1, fn, lineno)
2796 if not par: return
2797 self.ectx.outnm_opt = par[0]
2798 elif opt in ("-O",):
2799 par = self.check_par(par, 1, 1, fn, lineno)
2800 if not par: return
2801 self.ectx.output.outdir = par[0]
2802 elif opt in ("-s",):
2803 par = self.check_par(par, 1, 1, fn, lineno)
2804 if not par: return
2805 self.ectx.output.single_file = par[0]
2806 elif opt in ("-k",):
2807 par = self.check_par(par, 0, 0, fn, lineno)
2808 self.ectx.output.keep = True
2809 elif opt in ("-L",):
2810 par = self.check_par(par, 0, 0, fn, lineno)
2811 self.suppress_line = True
2812 elif opt in ("EMBEDDED_PDV_CB",):
2813 par = self.check_par(par, 1, 1, fn, lineno)
2814 if not par: return
2815 self.ectx.default_embedded_pdv_cb = par[0]
2816 elif opt in ("EXTERNAL_TYPE_CB",):
2817 par = self.check_par(par, 1, 1, fn, lineno)
2818 if not par: return
2819 self.ectx.default_external_type_cb = par[0]
2820 elif opt in ("-r",):
2821 par = self.check_par(par, 1, 1, fn, lineno)
2822 if not par: return
2823 self.ectx.remove_prefix = par[0]
2824 else:
2825 warnings.warn_explicit("Unknown option %s" % (opt),
2826 UserWarning, fn, lineno)
2828 def dbg_print(self):
2829 print("\n# Conformance values")
2830 print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value"))
2831 print("-" * 100)
2832 tbls = sorted(self.table.keys())
2833 for t in tbls:
2834 keys = sorted(self.table[t].keys())
2835 for k in keys:
2836 print("%-15s %4s %-15s %-20s %s" % (
2837 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']])))
2839 def unused_report(self):
2840 tbls = sorted(self.table.keys())
2841 for t in tbls:
2842 if not self.tblcfg[t]['chk_use']: continue
2843 keys = sorted(self.table[t].keys())
2844 for k in keys:
2845 if not self.table[t][k]['used']:
2846 warnings.warn_explicit("Unused %s for %s" % (t, k),
2847 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2848 fnms = list(self.fn.keys())
2849 fnms.sort()
2850 for f in fnms:
2851 keys = sorted(self.fn[f].keys())
2852 for k in keys:
2853 if not self.fn[f][k]: continue
2854 if not self.fn[f][k]['used']:
2855 warnings.warn_explicit("Unused %s for %s" % (k, f),
2856 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2858 #--- EthOut -------------------------------------------------------------------
2859 class EthOut:
2860 def __init__(self):
2861 self.ectx = None
2862 self.outnm = None
2863 self.outdir = '.'
2864 self.single_file = None
2865 self.created_files = {}
2866 self.created_files_ord = []
2867 self.keep = False
2869 def outcomment(self, ln, comment=None):
2870 if comment:
2871 return '%s %s\n' % (comment, ln)
2872 else:
2873 return '/* %-74s */\n' % (ln)
2875 def created_file_add(self, name, keep_anyway):
2876 name = os.path.normcase(os.path.abspath(name))
2877 if name not in self.created_files:
2878 self.created_files_ord.append(name)
2879 self.created_files[name] = keep_anyway
2880 else:
2881 self.created_files[name] = self.created_files[name] or keep_anyway
2883 def created_file_exists(self, name):
2884 name = os.path.normcase(os.path.abspath(name))
2885 return name in self.created_files
2887 #--- output_fname -------------------------------------------------------
2888 def output_fname(self, ftype, ext='c'):
2889 fn = ''
2890 if not ext in ('cnf',):
2891 fn += 'packet-'
2892 fn += self.outnm
2893 if (ftype):
2894 fn += '-' + ftype
2895 fn += '.' + ext
2896 return fn
2897 #--- file_open -------------------------------------------------------
2898 def file_open(self, ftype, ext='c'):
2899 fn = self.output_fname(ftype, ext=ext)
2900 if self.created_file_exists(fn):
2901 fx = open(fn, 'a')
2902 else:
2903 fx = open(fn, 'w')
2904 comment = None
2905 if ext in ('cnf',):
2906 comment = '#'
2907 fx.write(self.fhdr(fn, comment = comment))
2908 else:
2909 if (not self.single_file and not self.created_file_exists(fn)):
2910 fx.write(self.fhdr(fn))
2911 if not self.ectx.merge_modules:
2912 fx.write('\n')
2913 mstr = "--- "
2914 if self.ectx.groups():
2915 mstr += "Module"
2916 if (len(self.ectx.modules) > 1):
2917 mstr += "s"
2918 for (m, p) in self.ectx.modules:
2919 mstr += " %s" % (m)
2920 else:
2921 mstr += "Module %s" % (self.ectx.Module())
2922 mstr += " --- --- ---"
2923 fx.write(self.outcomment(mstr, comment))
2924 fx.write('\n')
2925 return fx
2926 #--- file_close -------------------------------------------------------
2927 def file_close(self, fx, discard=False, keep_anyway=False):
2928 fx.close()
2929 if discard and not self.created_file_exists(fx.name):
2930 os.unlink(fx.name)
2931 else:
2932 self.created_file_add(fx.name, keep_anyway)
2933 #--- fhdr -------------------------------------------------------
2934 def fhdr(self, fn, comment=None):
2935 out = ''
2936 out += self.outcomment('Do not modify this file. Changes will be overwritten.', comment)
2937 out += self.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment)
2938 out += self.outcomment(os.path.basename(fn), comment)
2939 out += self.outcomment(' '.join(sys.argv), comment)
2940 out += '\n'
2941 # Make Windows path separator look like Unix path separator
2942 out = out.replace('\\', '/')
2943 # Change abolute paths to paths relative to asn1/<proto> subdir
2944 out = re.sub(r'(\s)/\S*(/tools/|/epan/)', r'\1../..\2', out)
2945 out = re.sub(r'(\s)/\S*/asn1/\S*?([\s/])', r'\1.\2', out)
2946 return out
2948 #--- dbg_print -------------------------------------------------------
2949 def dbg_print(self):
2950 print("\n# Output files")
2951 print("\n".join(self.created_files_ord))
2952 print("\n")
2954 #--- make_single_file -------------------------------------------------------
2955 def make_single_file(self):
2956 if (not self.single_file): return
2957 in_nm = self.single_file + '.c'
2958 out_nm = os.path.join(self.outdir, self.output_fname(''))
2959 self.do_include(out_nm, in_nm)
2960 in_nm = self.single_file + '.h'
2961 if (os.path.exists(in_nm)):
2962 out_nm = os.path.join(self.outdir, self.output_fname('', ext='h'))
2963 self.do_include(out_nm, in_nm)
2964 if (not self.keep):
2965 for fn in self.created_files_ord:
2966 if not self.created_files[fn]:
2967 os.unlink(fn)
2969 #--- do_include -------------------------------------------------------
2970 def do_include(self, out_nm, in_nm):
2971 def check_file(fn, fnlist):
2972 fnfull = os.path.normcase(os.path.abspath(fn))
2973 if (fnfull in fnlist and os.path.exists(fnfull)):
2974 return os.path.normpath(fn)
2975 return None
2976 fin = open(in_nm, "r")
2977 fout = open(out_nm, "w")
2978 fout.write(self.fhdr(out_nm))
2979 fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n')
2980 fout.write('\n')
2981 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm)))
2983 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2985 cont_linenum = 0;
2987 while (True):
2988 cont_linenum = cont_linenum + 1;
2989 line = fin.readline()
2990 if (line == ''): break
2991 ifile = None
2992 result = include.search(line)
2993 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2994 if (result):
2995 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2996 if (not ifile):
2997 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2998 if (not ifile):
2999 ifile = check_file(result.group('fname'), self.created_files)
3000 if (ifile):
3001 fout.write('\n')
3002 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
3003 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile)))
3004 finc = open(ifile, "r")
3005 fout.write(finc.read())
3006 fout.write('\n')
3007 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
3008 fout.write('#line %u "%s"\n' % (cont_linenum+1, rel_dissector_path(in_nm)) )
3009 finc.close()
3010 else:
3011 fout.write(line)
3013 fout.close()
3014 fin.close()
3017 #--- Node ---------------------------------------------------------------------
3018 class Node:
3019 def __init__(self,*args, **kw):
3020 if len (args) == 0:
3021 self.type = self.__class__.__name__
3022 else:
3023 assert (len(args) == 1)
3024 self.type = args[0]
3025 self.__dict__.update (kw)
3026 def str_child (self, key, child, depth):
3027 indent = " " * (2 * depth)
3028 keystr = indent + key + ": "
3029 if key == 'type': # already processed in str_depth
3030 return ""
3031 if isinstance (child, Node): # ugh
3032 return keystr + "\n" + child.str_depth (depth+1)
3033 if isinstance(child, type ([])):
3034 l = []
3035 for x in child:
3036 if isinstance (x, Node):
3037 l.append (x.str_depth (depth+1))
3038 else:
3039 l.append (indent + " " + str(x) + "\n")
3040 return keystr + "[\n" + ''.join(l) + indent + "]\n"
3041 else:
3042 return keystr + str (child) + "\n"
3043 def str_depth (self, depth): # ugh
3044 indent = " " * (2 * depth)
3045 l = ["%s%s" % (indent, self.type)]
3046 l.append ("".join ([self.str_child (k_v[0], k_v[1], depth + 1) for k_v in list(self.__dict__.items ())]))
3047 return "\n".join (l)
3048 def __repr__(self):
3049 return "\n" + self.str_depth (0)
3050 def to_python (self, ctx):
3051 return self.str_depth (ctx.indent_lev)
3053 def eth_reg(self, ident, ectx):
3054 pass
3056 def fld_obj_repr(self, ectx):
3057 return "/* TO DO %s */" % (str(self))
3060 #--- ValueAssignment -------------------------------------------------------------
3061 class ValueAssignment (Node):
3062 def __init__(self,*args, **kw) :
3063 Node.__init__ (self,*args, **kw)
3065 def eth_reg(self, ident, ectx):
3066 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3067 ectx.eth_reg_vassign(self)
3068 ectx.eth_reg_value(self.ident, self.typ, self.val)
3070 #--- ObjectAssignment -------------------------------------------------------------
3071 class ObjectAssignment (Node):
3072 def __init__(self,*args, **kw) :
3073 Node.__init__ (self,*args, **kw)
3075 def __eq__(self, other):
3076 if self.cls != other.cls:
3077 return False
3078 if len(self.val) != len(other.val):
3079 return False
3080 for f in (list(self.val.keys())):
3081 if f not in other.val:
3082 return False
3083 if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
3084 if not self.val[f].fld_obj_eq(other.val[f]):
3085 return False
3086 else:
3087 if str(self.val[f]) != str(other.val[f]):
3088 return False
3089 return True
3091 def eth_reg(self, ident, ectx):
3092 def make_virtual_type(cls, field, prefix):
3093 if isinstance(self.val, str): return
3094 if field in self.val and not isinstance(self.val[field], Type_Ref):
3095 vnm = prefix + '-' + self.ident
3096 virtual_tr = Type_Ref(val = vnm)
3097 t = self.val[field]
3098 self.val[field] = virtual_tr
3099 ectx.eth_reg_assign(vnm, t, virt=True)
3100 ectx.eth_reg_type(vnm, t)
3101 t.eth_reg_sub(vnm, ectx)
3102 if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field):
3103 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))
3104 return
3105 # end of make_virtual_type()
3106 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3107 self.module = ectx.Module()
3108 ectx.eth_reg_oassign(self)
3109 if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
3110 make_virtual_type(self.cls, '&Type', 'TYPE')
3111 if (self.cls == 'OPERATION'):
3112 make_virtual_type(self.cls, '&ArgumentType', 'ARG')
3113 make_virtual_type(self.cls, '&ResultType', 'RES')
3114 if (self.cls == 'ERROR'):
3115 make_virtual_type(self.cls, '&ParameterType', 'PAR')
3118 #--- Type ---------------------------------------------------------------------
3119 class Type (Node):
3120 def __init__(self,*args, **kw) :
3121 self.name = None
3122 self.constr = None
3123 self.tags = []
3124 self.named_list = None
3125 Node.__init__ (self,*args, **kw)
3127 def IsNamed(self):
3128 if self.name is None :
3129 return False
3130 else:
3131 return True
3133 def HasConstraint(self):
3134 if self.constr is None :
3135 return False
3136 else :
3137 return True
3139 def HasSizeConstraint(self):
3140 return self.HasConstraint() and self.constr.IsSize()
3142 def HasValueConstraint(self):
3143 return self.HasConstraint() and self.constr.IsValue()
3145 def HasPermAlph(self):
3146 return self.HasConstraint() and self.constr.IsPermAlph()
3148 def HasContentsConstraint(self):
3149 return self.HasConstraint() and self.constr.IsContents()
3151 def HasOwnTag(self):
3152 return len(self.tags) > 0
3154 def HasImplicitTag(self, ectx):
3155 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
3157 def IndetermTag(self, ectx):
3158 return False
3160 def AddTag(self, tag):
3161 self.tags[0:0] = [tag]
3163 def GetTag(self, ectx):
3164 #print "GetTag(%s)\n" % self.name;
3165 if (self.HasOwnTag()):
3166 return self.tags[0].GetTag(ectx)
3167 else:
3168 return self.GetTTag(ectx)
3170 def GetTTag(self, ectx):
3171 print("#Unhandled GetTTag() in %s" % (self.type))
3172 print(self.str_depth(1))
3173 return ('BER_CLASS_unknown', 'TAG_unknown')
3175 def SetName(self, name):
3176 self.name = name
3178 def AddConstraint(self, constr):
3179 if not self.HasConstraint():
3180 self.constr = constr
3181 else:
3182 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
3184 def eth_tname(self):
3185 return '#' + self.type + '_' + str(id(self))
3187 def eth_ftype(self, ectx):
3188 return ('FT_NONE', 'BASE_NONE')
3190 def eth_strings(self):
3191 return 'NULL'
3193 def eth_omit_field(self):
3194 return False
3196 def eth_need_tree(self):
3197 return False
3199 def eth_has_vals(self):
3200 return False
3202 def eth_has_enum(self, tname, ectx):
3203 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
3205 def eth_need_pdu(self, ectx):
3206 return None
3208 def eth_named_bits(self):
3209 return None
3211 def eth_reg_sub(self, ident, ectx):
3212 pass
3214 def get_components(self, ectx):
3215 print("#Unhandled get_components() in %s" % (self.type))
3216 print(self.str_depth(1))
3217 return []
3219 def sel_req(self, sel, ectx):
3220 print("#Selection '%s' required for non-CHOICE type %s" % (sel, self.type))
3221 print(self.str_depth(1))
3223 def fld_obj_eq(self, other):
3224 return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
3226 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
3227 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3228 #print " ", self
3229 if (ectx.NeedTags() and (len(self.tags) > tstrip)):
3230 tagged_type = self
3231 for i in range(len(self.tags)-1, tstrip-1, -1):
3232 tagged_type = TaggedType(val=tagged_type, tstrip=i)
3233 tagged_type.AddTag(self.tags[i])
3234 if not tagflag: # 1st tagged level
3235 if self.IsNamed() and not selflag:
3236 tagged_type.SetName(self.name)
3237 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
3238 return
3239 nm = ''
3240 if ident and self.IsNamed() and not tagflag and not selflag:
3241 nm = ident + '/' + self.name
3242 elif ident:
3243 nm = ident
3244 elif self.IsNamed():
3245 nm = self.name
3246 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
3247 if not ident: # Assignment
3248 ectx.eth_reg_assign(nm, self)
3249 if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx):
3250 ectx.eth_reg_type(nm, self)
3251 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
3252 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
3253 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
3254 if ectx.conform.check_item('SET_TYPE', nm):
3255 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
3256 else:
3257 ectx.eth_reg_type(nm, self) # new type
3258 trnm = nm
3259 elif ectx.conform.check_item('SET_TYPE', nm):
3260 trnm = ectx.conform.use_item('SET_TYPE', nm)
3261 elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx):
3262 ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints
3263 trnm = nm
3264 else:
3265 trnm = self.val
3266 else:
3267 ectx.eth_reg_type(nm, self)
3268 trnm = nm
3269 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
3270 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
3271 ectx.eth_reg_assign(vnm, self, virt=True)
3272 ectx.eth_reg_type(vnm, self)
3273 self.eth_reg_sub(vnm, ectx)
3274 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
3275 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
3276 if ident and not tagflag and not self.eth_omit_field():
3277 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
3278 if ectx.conform.check_item('SET_TYPE', nm):
3279 virtual_tr.eth_reg_sub(nm, ectx)
3280 else:
3281 self.eth_reg_sub(nm, ectx)
3283 def eth_get_size_constr(self, ectx):
3284 (minv, maxv, ext) = ('MIN', 'MAX', False)
3285 if self.HasSizeConstraint():
3286 if self.constr.IsSize():
3287 (minv, maxv, ext) = self.constr.GetSize(ectx)
3288 if (self.constr.type == 'Intersection'):
3289 if self.constr.subtype[0].IsSize():
3290 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
3291 elif self.constr.subtype[1].IsSize():
3292 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
3293 if minv == 'MIN': minv = 'NO_BOUND'
3294 if maxv == 'MAX': maxv = 'NO_BOUND'
3295 if (ext): ext = 'TRUE'
3296 else: ext = 'FALSE'
3297 return (minv, maxv, ext)
3299 def eth_get_value_constr(self, ectx):
3300 (minv, maxv, ext) = ('MIN', 'MAX', False)
3301 if self.HasValueConstraint():
3302 (minv, maxv, ext) = self.constr.GetValue(ectx)
3303 if minv == 'MIN': minv = 'NO_BOUND'
3304 if maxv == 'MAX': maxv = 'NO_BOUND'
3305 if str(minv).isdigit():
3306 minv += 'U'
3307 elif (str(minv)[0] == "-") and str(minv)[1:].isdigit():
3308 if (int(minv) == -(2**31)):
3309 minv = "G_MININT32"
3310 elif (int(minv) < -(2**31)):
3311 minv = "G_GINT64_CONSTANT(%s)" % (str(minv))
3312 if str(maxv).isdigit():
3313 if (int(maxv) >= 2**32):
3314 maxv = "G_GINT64_CONSTANT(%sU)" % (str(maxv))
3315 else:
3316 maxv += 'U'
3317 if (ext): ext = 'TRUE'
3318 else: ext = 'FALSE'
3319 return (minv, maxv, ext)
3321 def eth_get_alphabet_constr(self, ectx):
3322 (alph, alphlen) = ('NULL', '0')
3323 if self.HasPermAlph():
3324 alph = self.constr.GetPermAlph(ectx)
3325 if not alph:
3326 alph = 'NULL'
3327 if (alph != 'NULL'):
3328 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
3329 alphlen = str(len(alph) - 2)
3330 else:
3331 alphlen = 'strlen(%s)' % (alph)
3332 return (alph, alphlen)
3334 def eth_type_vals(self, tname, ectx):
3335 if self.eth_has_vals():
3336 print("#Unhandled eth_type_vals('%s') in %s" % (tname, self.type))
3337 print(self.str_depth(1))
3338 return ''
3340 def eth_type_enum(self, tname, ectx):
3341 if self.eth_has_enum(tname, ectx):
3342 print("#Unhandled eth_type_enum('%s') in %s" % (tname, self.type))
3343 print(self.str_depth(1))
3344 return ''
3346 def eth_type_default_table(self, ectx, tname):
3347 return ''
3349 def eth_type_default_body(self, ectx):
3350 print("#Unhandled eth_type_default_body() in %s" % (self.type))
3351 print(self.str_depth(1))
3352 return ''
3354 def eth_type_default_pars(self, ectx, tname):
3355 pars = {
3356 'TNAME' : tname,
3357 'ER' : ectx.encp(),
3358 'FN_VARIANT' : '',
3359 'TREE' : 'tree',
3360 'TVB' : 'tvb',
3361 'OFFSET' : 'offset',
3362 'ACTX' : 'actx',
3363 'HF_INDEX' : 'hf_index',
3364 'VAL_PTR' : 'NULL',
3365 'IMPLICIT_TAG' : 'implicit_tag',
3367 if (ectx.eth_type[tname]['tree']):
3368 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
3369 if (ectx.merge_modules):
3370 pars['PROTOP'] = ''
3371 else:
3372 pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
3373 return pars
3375 def eth_type_fn(self, proto, tname, ectx):
3376 body = self.eth_type_default_body(ectx, tname)
3377 pars = self.eth_type_default_pars(ectx, tname)
3378 if ectx.conform.check_item('FN_PARS', tname):
3379 pars.update(ectx.conform.use_item('FN_PARS', tname))
3380 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
3381 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
3382 pars['DEFAULT_BODY'] = body
3383 for i in range(4):
3384 for k in list(pars.keys()):
3385 try:
3386 pars[k] = pars[k] % pars
3387 except (ValueError,TypeError):
3388 raise sys.exc_info()[0]("%s\n%s" % (str(pars), sys.exc_info()[1]))
3389 out = '\n'
3390 out += self.eth_type_default_table(ectx, tname) % pars
3391 out += ectx.eth_type_fn_hdr(tname)
3392 out += ectx.eth_type_fn_body(tname, body, pars=pars)
3393 out += ectx.eth_type_fn_ftr(tname)
3394 return out
3396 #--- Value --------------------------------------------------------------------
3397 class Value (Node):
3398 def __init__(self,*args, **kw) :
3399 self.name = None
3400 Node.__init__ (self,*args, **kw)
3402 def SetName(self, name) :
3403 self.name = name
3405 def to_str(self, ectx):
3406 return str(self.val)
3408 def get_dep(self):
3409 return None
3411 def fld_obj_repr(self, ectx):
3412 return self.to_str(ectx)
3414 #--- Value_Ref -----------------------------------------------------------------
3415 class Value_Ref (Value):
3416 def to_str(self, ectx):
3417 return asn2c(self.val)
3419 #--- ObjectClass ---------------------------------------------------------------------
3420 class ObjectClass (Node):
3421 def __init__(self,*args, **kw) :
3422 self.name = None
3423 Node.__init__ (self,*args, **kw)
3425 def SetName(self, name):
3426 self.name = name
3427 add_class_ident(self.name)
3429 def eth_reg(self, ident, ectx):
3430 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
3431 ectx.eth_reg_objectclass(self.name, self)
3433 #--- Class_Ref -----------------------------------------------------------------
3434 class Class_Ref (ObjectClass):
3435 pass
3437 #--- ObjectClassDefn ---------------------------------------------------------------------
3438 class ObjectClassDefn (ObjectClass):
3439 def reg_types(self):
3440 for fld in self.fields:
3441 repr = fld.fld_repr()
3442 set_type_to_class(self.name, repr[0], repr[1:])
3445 #--- Tag ---------------------------------------------------------------
3446 class Tag (Node):
3447 def to_python (self, ctx):
3448 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
3449 self.tag_typ,
3450 self.tag.num),
3451 self.typ.to_python (ctx))
3452 def IsImplicit(self, ectx):
3453 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def != 'EXPLICIT')))
3455 def GetTag(self, ectx):
3456 tc = ''
3457 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
3458 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
3459 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
3460 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
3461 return (tc, self.num)
3463 def eth_tname(self):
3464 n = ''
3465 if (self.cls == 'UNIVERSAL'): n = 'U'
3466 elif (self.cls == 'APPLICATION'): n = 'A'
3467 elif (self.cls == 'CONTEXT'): n = 'C'
3468 elif (self.cls == 'PRIVATE'): n = 'P'
3469 return n + str(self.num)
3471 #--- Constraint ---------------------------------------------------------------
3472 constr_cnt = 0
3473 class Constraint (Node):
3474 def to_python (self, ctx):
3475 print("Ignoring constraint:", self.type)
3476 return self.subtype.typ.to_python (ctx)
3477 def __str__ (self):
3478 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
3480 def eth_tname(self):
3481 return '#' + self.type + '_' + str(id(self))
3483 def IsSize(self):
3484 return (self.type == 'Size' and self.subtype.IsValue()) \
3485 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
3487 def GetSize(self, ectx):
3488 (minv, maxv, ext) = ('MIN', 'MAX', False)
3489 if self.IsSize():
3490 if self.type == 'Size':
3491 (minv, maxv, ext) = self.subtype.GetValue(ectx)
3492 elif self.type == 'Intersection':
3493 if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
3494 (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
3495 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
3496 (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
3497 return (minv, maxv, ext)
3499 def IsValue(self):
3500 return self.type == 'SingleValue' \
3501 or self.type == 'ValueRange' \
3502 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
3503 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
3505 def GetValue(self, ectx):
3506 (minv, maxv, ext) = ('MIN', 'MAX', False)
3507 if self.IsValue():
3508 if self.type == 'SingleValue':
3509 minv = ectx.value_get_eth(self.subtype)
3510 maxv = ectx.value_get_eth(self.subtype)
3511 ext = hasattr(self, 'ext') and self.ext
3512 elif self.type == 'ValueRange':
3513 minv = ectx.value_get_eth(self.subtype[0])
3514 maxv = ectx.value_get_eth(self.subtype[1])
3515 ext = hasattr(self, 'ext') and self.ext
3516 elif self.type == 'Intersection':
3517 if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
3518 (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
3519 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
3520 (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
3521 elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
3522 v0 = self.subtype[0].GetValue(ectx)
3523 v1 = self.subtype[1].GetValue(ectx)
3524 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
3525 elif self.type == 'Union':
3526 if self.subtype[0].IsValue() and self.subtype[1].IsValue():
3527 v0 = self.subtype[0].GetValue(ectx)
3528 v1 = self.subtype[1].GetValue(ectx)
3529 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
3530 return (minv, maxv, ext)
3532 def IsAlphabet(self):
3533 return self.type == 'SingleValue' \
3534 or self.type == 'ValueRange' \
3535 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
3536 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
3538 def GetAlphabet(self, ectx):
3539 alph = None
3540 if self.IsAlphabet():
3541 if self.type == 'SingleValue':
3542 alph = ectx.value_get_eth(self.subtype)
3543 elif self.type == 'ValueRange':
3544 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
3545 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
3546 alph = '"'
3547 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
3548 alph += chr(c)
3549 alph += '"'
3550 elif self.type == 'Union':
3551 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
3552 a0 = self.subtype[0].GetAlphabet(ectx)
3553 a1 = self.subtype[1].GetAlphabet(ectx)
3554 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
3555 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
3556 alph = '"' + a0[1:-1] + a1[1:-1] + '"'
3557 else:
3558 alph = a0 + ' ' + a1
3559 return alph
3561 def IsPermAlph(self):
3562 return self.type == 'From' and self.subtype.IsAlphabet() \
3563 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
3565 def GetPermAlph(self, ectx):
3566 alph = None
3567 if self.IsPermAlph():
3568 if self.type == 'From':
3569 alph = self.subtype.GetAlphabet(ectx)
3570 elif self.type == 'Intersection':
3571 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
3572 alph = self.subtype[0].GetPermAlph(ectx)
3573 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
3574 alph = self.subtype[1].GetPermAlph(ectx)
3575 return alph
3577 def IsContents(self):
3578 return self.type == 'Contents' \
3579 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
3581 def GetContents(self, ectx):
3582 contents = None
3583 if self.IsContents():
3584 if self.type == 'Contents':
3585 if self.subtype.type == 'Type_Ref':
3586 contents = self.subtype.val
3587 elif self.type == 'Intersection':
3588 if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
3589 contents = self.subtype[0].GetContents(ectx)
3590 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
3591 contents = self.subtype[1].GetContents(ectx)
3592 return contents
3594 def IsNegativ(self):
3595 def is_neg(sval):
3596 return isinstance(sval, str) and (sval[0] == '-')
3597 if self.type == 'SingleValue':
3598 return is_neg(self.subtype)
3599 elif self.type == 'ValueRange':
3600 if self.subtype[0] == 'MIN': return True
3601 return is_neg(self.subtype[0])
3602 return False
3604 def eth_constrname(self):
3605 def int2str(val):
3606 if isinstance(val, Value_Ref):
3607 return asn2c(val.val)
3608 try:
3609 if (int(val) < 0):
3610 return 'M' + str(-int(val))
3611 else:
3612 return str(int(val))
3613 except (ValueError, TypeError):
3614 return asn2c(str(val))
3616 ext = ''
3617 if hasattr(self, 'ext') and self.ext:
3618 ext = '_'
3619 if self.type == 'SingleValue':
3620 return int2str(self.subtype) + ext
3621 elif self.type == 'ValueRange':
3622 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
3623 elif self.type == 'Size':
3624 return 'SIZE_' + self.subtype.eth_constrname() + ext
3625 else:
3626 if (not hasattr(self, 'constr_num')):
3627 global constr_cnt
3628 constr_cnt += 1
3629 self.constr_num = constr_cnt
3630 return 'CONSTR%03d%s' % (self.constr_num, ext)
3633 class Module (Node):
3634 def to_python (self, ctx):
3635 ctx.tag_def = self.tag_def.dfl_tag
3636 return """#%s
3637 %s""" % (self.ident, self.body.to_python (ctx))
3639 def get_name(self):
3640 return self.ident.val
3642 def get_proto(self, ectx):
3643 if (ectx.proto):
3644 prot = ectx.proto
3645 else:
3646 prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name())
3647 return prot
3649 def to_eth(self, ectx):
3650 ectx.tags_def = 'EXPLICIT' # default = explicit
3651 ectx.proto = self.get_proto(ectx)
3652 ectx.tag_def = self.tag_def.dfl_tag
3653 ectx.eth_reg_module(self)
3654 self.body.to_eth(ectx)
3656 class Module_Body (Node):
3657 def to_python (self, ctx):
3658 # XXX handle exports, imports.
3659 l = [x.to_python (ctx) for x in self.assign_list]
3660 l = [a for a in l if a != '']
3661 return "\n".join (l)
3663 def to_eth(self, ectx):
3664 # Exports
3665 ectx.eth_exports(self.exports)
3666 # Imports
3667 for i in self.imports:
3668 mod = i.module.val
3669 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
3670 ectx.eth_module_dep_add(ectx.Module(), mod)
3671 for s in i.symbol_list:
3672 if isinstance(s, Type_Ref):
3673 ectx.eth_import_type(s.val, mod, proto)
3674 elif isinstance(s, Value_Ref):
3675 ectx.eth_import_value(s.val, mod, proto)
3676 elif isinstance(s, Class_Ref):
3677 ectx.eth_import_class(s.val, mod, proto)
3678 else:
3679 msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
3680 warnings.warn_explicit(msg, UserWarning, '', 0)
3681 # AssignmentList
3682 for a in self.assign_list:
3683 a.eth_reg('', ectx)
3685 class Default_Tags (Node):
3686 def to_python (self, ctx): # not to be used directly
3687 assert (0)
3689 # XXX should just calculate dependencies as we go along.
3690 def calc_dependencies (node, dict, trace = 0):
3691 if not hasattr (node, '__dict__'):
3692 if trace: print("#returning, node=", node)
3693 return
3694 if isinstance (node, Type_Ref):
3695 dict [node.val] = 1
3696 if trace: print("#Setting", node.val)
3697 return
3698 for (a, val) in list(node.__dict__.items ()):
3699 if trace: print("# Testing node ", node, "attr", a, " val", val)
3700 if a[0] == '_':
3701 continue
3702 elif isinstance (val, Node):
3703 calc_dependencies (val, dict, trace)
3704 elif isinstance (val, type ([])):
3705 for v in val:
3706 calc_dependencies (v, dict, trace)
3709 class Type_Assign (Node):
3710 def __init__ (self, *args, **kw):
3711 Node.__init__ (self, *args, **kw)
3712 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3713 to_test = self.val.typ
3714 else:
3715 to_test = self.val
3716 if isinstance (to_test, SequenceType):
3717 to_test.sequence_name = self.name.name
3719 def to_python (self, ctx):
3720 dep_dict = {}
3721 calc_dependencies (self.val, dep_dict, 0)
3722 depend_list = list(dep_dict.keys ())
3723 return ctx.register_assignment (self.name.name,
3724 self.val.to_python (ctx),
3725 depend_list)
3727 class PyQuote (Node):
3728 def to_python (self, ctx):
3729 return ctx.register_pyquote (self.val)
3731 #--- Type_Ref -----------------------------------------------------------------
3732 class Type_Ref (Type):
3733 def to_python (self, ctx):
3734 return self.val
3736 def eth_reg_sub(self, ident, ectx):
3737 ectx.eth_dep_add(ident, self.val)
3739 def eth_tname(self):
3740 if self.HasSizeConstraint():
3741 return asn2c(self.val) + '_' + self.constr.eth_constrname()
3742 else:
3743 return asn2c(self.val)
3745 def tr_need_own_fn(self, ectx):
3746 return ectx.Per() and self.HasSizeConstraint()
3748 def fld_obj_repr(self, ectx):
3749 return self.val
3751 def get_components(self, ectx):
3752 if self.val not in ectx.type or ectx.type[self.val]['import']:
3753 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
3754 warnings.warn_explicit(msg, UserWarning, '', 0)
3755 return []
3756 else:
3757 return ectx.type[self.val]['val'].get_components(ectx)
3759 def GetTTag(self, ectx):
3760 #print "GetTTag(%s)\n" % self.val;
3761 if (ectx.type[self.val]['import']):
3762 if 'ttag' not in ectx.type[self.val]:
3763 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
3764 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
3765 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
3766 warnings.warn_explicit(msg, UserWarning, '', 0)
3767 ttag = ('-1/*imported*/', '-1/*imported*/')
3768 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
3769 return ectx.type[self.val]['ttag']
3770 else:
3771 return ectx.type[self.val]['val'].GetTag(ectx)
3773 def IndetermTag(self, ectx):
3774 if (ectx.type[self.val]['import']):
3775 return False
3776 else:
3777 return ectx.type[self.val]['val'].IndetermTag(ectx)
3779 def eth_type_default_pars(self, ectx, tname):
3780 if tname:
3781 pars = Type.eth_type_default_pars(self, ectx, tname)
3782 else:
3783 pars = {}
3784 t = ectx.type[self.val]['ethname']
3785 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3786 pars['TYPE_REF_TNAME'] = t
3787 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3788 if self.HasSizeConstraint():
3789 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3790 return pars
3792 def eth_type_default_body(self, ectx, tname):
3793 if (ectx.Ber()):
3794 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3795 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3796 elif (ectx.Per()):
3797 if self.HasSizeConstraint():
3798 body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset',
3799 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3800 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3801 else:
3802 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3803 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3804 else:
3805 body = '#error Can not decode %s' % (tname)
3806 return body
3808 #--- SelectionType ------------------------------------------------------------
3809 class SelectionType (Type):
3810 def to_python (self, ctx):
3811 return self.val
3813 def sel_of_typeref(self):
3814 return self.typ.type == 'Type_Ref'
3816 def eth_reg_sub(self, ident, ectx):
3817 if not self.sel_of_typeref():
3818 self.seltype = ''
3819 return
3820 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
3821 ectx.eth_dep_add(ident, self.seltype)
3823 def eth_ftype(self, ectx):
3824 (ftype, display) = ('FT_NONE', 'BASE_NONE')
3825 if self.sel_of_typeref() and not ectx.type[self.seltype]['import']:
3826 (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx)
3827 return (ftype, display)
3829 def GetTTag(self, ectx):
3830 #print "GetTTag(%s)\n" % self.seltype;
3831 if (ectx.type[self.seltype]['import']):
3832 if 'ttag' not in ectx.type[self.seltype]:
3833 if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
3834 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
3835 warnings.warn_explicit(msg, UserWarning, '', 0)
3836 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
3837 return ectx.type[self.seltype]['ttag']
3838 else:
3839 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
3841 def eth_type_default_pars(self, ectx, tname):
3842 pars = Type.eth_type_default_pars(self, ectx, tname)
3843 if self.sel_of_typeref():
3844 t = ectx.type[self.seltype]['ethname']
3845 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3846 pars['TYPE_REF_TNAME'] = t
3847 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3848 return pars
3850 def eth_type_default_body(self, ectx, tname):
3851 if not self.sel_of_typeref():
3852 body = '#error Can not decode %s' % (tname)
3853 elif (ectx.Ber()):
3854 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3855 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3856 elif (ectx.Per()):
3857 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3858 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3859 else:
3860 body = '#error Can not decode %s' % (tname)
3861 return body
3863 #--- TaggedType -----------------------------------------------------------------
3864 class TaggedType (Type):
3865 def eth_tname(self):
3866 tn = ''
3867 for i in range(self.tstrip, len(self.val.tags)):
3868 tn += self.val.tags[i].eth_tname()
3869 tn += '_'
3870 tn += self.val.eth_tname()
3871 return tn
3873 def eth_set_val_name(self, ident, val_name, ectx):
3874 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3875 self.val_name = val_name
3876 ectx.eth_dep_add(ident, self.val_name)
3878 def eth_reg_sub(self, ident, ectx):
3879 self.val_name = ident + '/' + UNTAG_TYPE_NAME
3880 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
3882 def GetTTag(self, ectx):
3883 #print "GetTTag(%s)\n" % self.seltype;
3884 return self.GetTag(ectx)
3886 def eth_ftype(self, ectx):
3887 return self.val.eth_ftype(ectx)
3889 def eth_type_default_pars(self, ectx, tname):
3890 pars = Type.eth_type_default_pars(self, ectx, tname)
3891 t = ectx.type[self.val_name]['ethname']
3892 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3893 pars['TYPE_REF_TNAME'] = t
3894 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3895 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
3896 if self.HasImplicitTag(ectx):
3897 pars['TAG_IMPL'] = 'TRUE'
3898 else:
3899 pars['TAG_IMPL'] = 'FALSE'
3900 return pars
3902 def eth_type_default_body(self, ectx, tname):
3903 if (ectx.Ber()):
3904 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
3905 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3906 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
3907 else:
3908 body = '#error Can not decode %s' % (tname)
3909 return body
3911 #--- SqType -----------------------------------------------------------
3912 class SqType (Type):
3913 def out_item(self, f, val, optional, ext, ectx):
3914 if (val.eth_omit_field()):
3915 t = ectx.type[val.ident]['ethname']
3916 fullname = ectx.dummy_eag_field
3917 else:
3918 ef = ectx.field[f]['ethname']
3919 t = ectx.eth_hf[ef]['ethtype']
3920 fullname = ectx.eth_hf[ef]['fullname']
3921 if (ectx.Ber()):
3922 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
3923 #print val.str_depth(1)
3924 opt = ''
3925 if (optional):
3926 opt = 'BER_FLAGS_OPTIONAL'
3927 if (not val.HasOwnTag()):
3928 if (opt): opt += '|'
3929 opt += 'BER_FLAGS_NOOWNTAG'
3930 elif (val.HasImplicitTag(ectx)):
3931 if (opt): opt += '|'
3932 opt += 'BER_FLAGS_IMPLTAG'
3933 if (val.IndetermTag(ectx)):
3934 if (opt): opt += '|'
3935 opt += 'BER_FLAGS_NOTCHKTAG'
3936 if (not opt): opt = '0'
3937 else:
3938 if optional:
3939 opt = 'ASN1_OPTIONAL'
3940 else:
3941 opt = 'ASN1_NOT_OPTIONAL'
3942 if (ectx.Ber()):
3943 (tc, tn) = val.GetTag(ectx)
3944 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3945 % ('&'+fullname, tc, tn, opt, ectx.eth_type[t]['proto'], t)
3946 elif (ectx.Per()):
3947 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
3948 % ('&'+fullname, ext, opt, ectx.eth_type[t]['proto'], t)
3949 else:
3950 out = ''
3951 return out
3953 #--- SeqType -----------------------------------------------------------
3954 class SeqType (SqType):
3956 def all_components(self):
3957 lst = self.elt_list[:]
3958 if hasattr(self, 'ext_list'):
3959 lst.extend(self.ext_list)
3960 if hasattr(self, 'elt_list2'):
3961 lst.extend(self.elt_list2)
3962 return lst
3964 def need_components(self):
3965 lst = self.all_components()
3966 for e in (lst):
3967 if e.type == 'components_of':
3968 return True
3969 return False
3971 def expand_components(self, ectx):
3972 while self.need_components():
3973 for i in range(len(self.elt_list)):
3974 if self.elt_list[i].type == 'components_of':
3975 comp = self.elt_list[i].typ.get_components(ectx)
3976 self.elt_list[i:i+1] = comp
3977 break
3978 if hasattr(self, 'ext_list'):
3979 for i in range(len(self.ext_list)):
3980 if self.ext_list[i].type == 'components_of':
3981 comp = self.ext_list[i].typ.get_components(ectx)
3982 self.ext_list[i:i+1] = comp
3983 break
3984 if hasattr(self, 'elt_list2'):
3985 for i in range(len(self.elt_list2)):
3986 if self.elt_list2[i].type == 'components_of':
3987 comp = self.elt_list2[i].typ.get_components(ectx)
3988 self.elt_list2[i:i+1] = comp
3989 break
3991 def get_components(self, ectx):
3992 lst = self.elt_list[:]
3993 if hasattr(self, 'elt_list2'):
3994 lst.extend(self.elt_list2)
3995 return lst
3997 def eth_reg_sub(self, ident, ectx, components_available=False):
3998 # check if autotag is required
3999 autotag = False
4000 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
4001 autotag = True
4002 lst = self.all_components()
4003 for e in (self.elt_list):
4004 if e.val.HasOwnTag(): autotag = False; break;
4005 # expand COMPONENTS OF
4006 if self.need_components():
4007 if components_available:
4008 self.expand_components(ectx)
4009 else:
4010 ectx.eth_comp_req(ident)
4011 return
4012 # extension addition groups
4013 if hasattr(self, 'ext_list'):
4014 if (ectx.Per()): # add names
4015 eag_num = 1
4016 for e in (self.ext_list):
4017 if isinstance(e.val, ExtensionAdditionGroup):
4018 e.val.parent_ident = ident
4019 e.val.parent_tname = ectx.type[ident]['tname']
4020 if (e.val.ver):
4021 e.val.SetName("eag_v%s" % (e.val.ver))
4022 else:
4023 e.val.SetName("eag_%d" % (eag_num))
4024 eag_num += 1;
4025 else: # expand
4026 new_ext_list = []
4027 for e in (self.ext_list):
4028 if isinstance(e.val, ExtensionAdditionGroup):
4029 new_ext_list.extend(e.val.elt_list)
4030 else:
4031 new_ext_list.append(e)
4032 self.ext_list = new_ext_list
4033 # do autotag
4034 if autotag:
4035 atag = 0
4036 for e in (self.elt_list):
4037 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4038 atag += 1
4039 if autotag and hasattr(self, 'elt_list2'):
4040 for e in (self.elt_list2):
4041 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4042 atag += 1
4043 if autotag and hasattr(self, 'ext_list'):
4044 for e in (self.ext_list):
4045 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4046 atag += 1
4047 # register components
4048 for e in (self.elt_list):
4049 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4050 if hasattr(self, 'ext_list'):
4051 for e in (self.ext_list):
4052 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4053 if hasattr(self, 'elt_list2'):
4054 for e in (self.elt_list2):
4055 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4057 def eth_type_default_table(self, ectx, tname):
4058 #print "eth_type_default_table(tname='%s')" % (tname)
4059 fname = ectx.eth_type[tname]['ref'][0]
4060 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
4061 if hasattr(self, 'ext_list'):
4062 ext = 'ASN1_EXTENSION_ROOT'
4063 else:
4064 ext = 'ASN1_NO_EXTENSIONS'
4065 empty_ext_flag = '0'
4066 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)):
4067 empty_ext_flag = ext
4068 for e in (self.elt_list):
4069 f = fname + '/' + e.val.name
4070 table += self.out_item(f, e.val, e.optional, ext, ectx)
4071 if hasattr(self, 'ext_list'):
4072 for e in (self.ext_list):
4073 f = fname + '/' + e.val.name
4074 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4075 if hasattr(self, 'elt_list2'):
4076 for e in (self.elt_list2):
4077 f = fname + '/' + e.val.name
4078 table += self.out_item(f, e.val, e.optional, ext, ectx)
4079 if (ectx.Ber()):
4080 table += " { NULL, 0, 0, 0, NULL }\n};\n"
4081 else:
4082 table += " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag)
4083 return table
4085 #--- SeqOfType -----------------------------------------------------------
4086 class SeqOfType (SqType):
4087 def eth_type_default_table(self, ectx, tname):
4088 #print "eth_type_default_table(tname='%s')" % (tname)
4089 fname = ectx.eth_type[tname]['ref'][0]
4090 if self.val.IsNamed ():
4091 f = fname + '/' + self.val.name
4092 else:
4093 f = fname + '/' + ITEM_FIELD_NAME
4094 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
4095 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
4096 table += "};\n"
4097 return table
4099 #--- SequenceOfType -----------------------------------------------------------
4100 class SequenceOfType (SeqOfType):
4101 def to_python (self, ctx):
4102 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4103 # or '' + (1,) for optional
4104 sizestr = ''
4105 if self.size_constr != None:
4106 print("#Ignoring size constraint:", self.size_constr.subtype)
4107 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
4108 self.val.to_python (ctx),
4109 sizestr)
4111 def eth_reg_sub(self, ident, ectx):
4112 itmnm = ident
4113 if not self.val.IsNamed ():
4114 itmnm += '/' + ITEM_FIELD_NAME
4115 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
4117 def eth_tname(self):
4118 if self.val.type != 'Type_Ref':
4119 return '#' + self.type + '_' + str(id(self))
4120 if not self.HasConstraint():
4121 return "SEQUENCE_OF_" + self.val.eth_tname()
4122 elif self.constr.IsSize():
4123 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4124 else:
4125 return '#' + self.type + '_' + str(id(self))
4127 def eth_ftype(self, ectx):
4128 return ('FT_UINT32', 'BASE_DEC')
4130 def eth_need_tree(self):
4131 return True
4133 def GetTTag(self, ectx):
4134 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4136 def eth_type_default_pars(self, ectx, tname):
4137 pars = Type.eth_type_default_pars(self, ectx, tname)
4138 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4139 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
4140 return pars
4142 def eth_type_default_body(self, ectx, tname):
4143 if (ectx.Ber()):
4144 if (ectx.constraints_check and self.HasSizeConstraint()):
4145 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4146 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4147 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4148 else:
4149 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4150 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4151 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4152 elif (ectx.Per() and not self.HasConstraint()):
4153 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4154 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4155 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4156 elif (ectx.Per() and self.constr.type == 'Size'):
4157 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4158 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4159 ('%(ETT_INDEX)s', '%(TABLE)s',),
4160 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
4161 else:
4162 body = '#error Can not decode %s' % (tname)
4163 return body
4166 #--- SetOfType ----------------------------------------------------------------
4167 class SetOfType (SeqOfType):
4168 def eth_reg_sub(self, ident, ectx):
4169 itmnm = ident
4170 if not self.val.IsNamed ():
4171 itmnm += '/' + ITEM_FIELD_NAME
4172 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
4174 def eth_tname(self):
4175 if self.val.type != 'Type_Ref':
4176 return '#' + self.type + '_' + str(id(self))
4177 if not self.HasConstraint():
4178 return "SET_OF_" + self.val.eth_tname()
4179 elif self.constr.IsSize():
4180 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4181 else:
4182 return '#' + self.type + '_' + str(id(self))
4184 def eth_ftype(self, ectx):
4185 return ('FT_UINT32', 'BASE_DEC')
4187 def eth_need_tree(self):
4188 return True
4190 def GetTTag(self, ectx):
4191 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4193 def eth_type_default_pars(self, ectx, tname):
4194 pars = Type.eth_type_default_pars(self, ectx, tname)
4195 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4196 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
4197 return pars
4199 def eth_type_default_body(self, ectx, tname):
4200 if (ectx.Ber()):
4201 if (ectx.constraints_check and self.HasSizeConstraint()):
4202 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4203 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4204 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4205 else:
4206 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4207 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4208 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4209 elif (ectx.Per() and not self.HasConstraint()):
4210 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4211 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4212 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4213 elif (ectx.Per() and self.constr.type == 'Size'):
4214 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4215 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4216 ('%(ETT_INDEX)s', '%(TABLE)s',),
4217 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),))
4218 else:
4219 body = '#error Can not decode %s' % (tname)
4220 return body
4222 def mk_tag_str (ctx, cls, typ, num):
4224 # XXX should do conversion to int earlier!
4225 val = int (num)
4226 typ = typ.upper()
4227 if typ == 'DEFAULT':
4228 typ = ctx.tags_def
4229 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
4231 #--- SequenceType -------------------------------------------------------------
4232 class SequenceType (SeqType):
4233 def to_python (self, ctx):
4234 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4235 # or '' + (1,) for optional
4236 # XXX should also collect names for SEQUENCE inside SEQUENCE or
4237 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
4238 # from? for others, element or arm name would be fine)
4239 seq_name = getattr (self, 'sequence_name', None)
4240 if seq_name == None:
4241 seq_name = 'None'
4242 else:
4243 seq_name = "'" + seq_name + "'"
4244 if 'ext_list' in self.__dict__:
4245 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
4246 self.elts_to_py (self.elt_list, ctx),
4247 self.elts_to_py (self.ext_list, ctx), seq_name)
4248 else:
4249 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
4250 self.elts_to_py (self.elt_list, ctx), seq_name)
4251 def elts_to_py (self, list, ctx):
4252 # we have elt_type, val= named_type, maybe default=, optional=
4253 # named_type node: either ident = or typ =
4254 # need to dismember these in order to generate Python output syntax.
4255 ctx.indent ()
4256 def elt_to_py (e):
4257 assert (e.type == 'elt_type')
4258 nt = e.val
4259 optflag = e.optional
4260 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
4261 assert (nt.type == 'named_type')
4262 tagstr = 'None'
4263 identstr = nt.ident
4264 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4265 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4266 nt.typ.tag.tag_typ,nt.typ.tag.num)
4269 nt = nt.typ
4270 return "('%s',%s,%s,%d)" % (identstr, tagstr,
4271 nt.typ.to_python (ctx), optflag)
4272 indentstr = ",\n" + ctx.spaces ()
4273 rv = indentstr.join ([elt_to_py (e) for e in list])
4274 ctx.outdent ()
4275 return rv
4277 def eth_need_tree(self):
4278 return True
4280 def GetTTag(self, ectx):
4281 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4283 def eth_type_default_pars(self, ectx, tname):
4284 pars = Type.eth_type_default_pars(self, ectx, tname)
4285 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4286 return pars
4288 def eth_type_default_body(self, ectx, tname):
4289 if (ectx.Ber()):
4290 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4291 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4292 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4293 elif (ectx.Per()):
4294 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4295 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4296 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4297 else:
4298 body = '#error Can not decode %s' % (tname)
4299 return body
4301 #--- ExtensionAdditionGroup ---------------------------------------------------
4302 class ExtensionAdditionGroup (SeqType):
4303 def __init__(self,*args, **kw) :
4304 self.parent_ident = None
4305 self.parent_tname = None
4306 SeqType.__init__ (self,*args, **kw)
4308 def eth_omit_field(self):
4309 return True
4311 def eth_tname(self):
4312 if (self.parent_tname and self.IsNamed()):
4313 return self.parent_tname + "_" + self.name
4314 else:
4315 return SeqType.eth_tname(self)
4317 def eth_reg_sub(self, ident, ectx):
4318 ectx.eth_dummy_eag_field_required()
4319 ectx.eth_dep_add(self.parent_ident, ident)
4320 SeqType.eth_reg_sub(self, ident, ectx)
4322 def eth_type_default_pars(self, ectx, tname):
4323 pars = Type.eth_type_default_pars(self, ectx, tname)
4324 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4325 return pars
4327 def eth_type_default_body(self, ectx, tname):
4328 if (ectx.Per()):
4329 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_eag', ret='offset',
4330 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),))
4331 else:
4332 body = '#error Can not decode %s' % (tname)
4333 return body
4336 #--- SetType ------------------------------------------------------------------
4337 class SetType (SeqType):
4339 def eth_need_tree(self):
4340 return True
4342 def GetTTag(self, ectx):
4343 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4345 def eth_type_default_pars(self, ectx, tname):
4346 pars = Type.eth_type_default_pars(self, ectx, tname)
4347 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4348 return pars
4350 def eth_type_default_body(self, ectx, tname):
4351 if (ectx.Ber()):
4352 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4353 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4354 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4355 elif (ectx.Per()):
4356 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4357 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4358 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4359 else:
4360 body = '#error Can not decode %s' % (tname)
4361 return body
4363 #--- ChoiceType ---------------------------------------------------------------
4364 class ChoiceType (Type):
4365 def to_python (self, ctx):
4366 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4367 # or '' + (1,) for optional
4368 if 'ext_list' in self.__dict__:
4369 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
4370 self.elts_to_py (self.elt_list, ctx),
4371 self.elts_to_py (self.ext_list, ctx))
4372 else:
4373 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
4374 def elts_to_py (self, list, ctx):
4375 ctx.indent ()
4376 def elt_to_py (nt):
4377 assert (nt.type == 'named_type')
4378 tagstr = 'None'
4379 if hasattr (nt, 'ident'):
4380 identstr = nt.ident
4381 else:
4382 if hasattr (nt.typ, 'val'):
4383 identstr = nt.typ.val # XXX, making up name
4384 elif hasattr (nt.typ, 'name'):
4385 identstr = nt.typ.name
4386 else:
4387 identstr = ctx.make_new_name ()
4389 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4390 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4391 nt.typ.tag.tag_typ,nt.typ.tag.num)
4394 nt = nt.typ
4395 return "('%s',%s,%s)" % (identstr, tagstr,
4396 nt.typ.to_python (ctx))
4397 indentstr = ",\n" + ctx.spaces ()
4398 rv = indentstr.join ([elt_to_py (e) for e in list])
4399 ctx.outdent ()
4400 return rv
4402 def eth_reg_sub(self, ident, ectx):
4403 #print "eth_reg_sub(ident='%s')" % (ident)
4404 # check if autotag is required
4405 autotag = False
4406 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
4407 autotag = True
4408 for e in (self.elt_list):
4409 if e.HasOwnTag(): autotag = False; break;
4410 if autotag and hasattr(self, 'ext_list'):
4411 for e in (self.ext_list):
4412 if e.HasOwnTag(): autotag = False; break;
4413 # do autotag
4414 if autotag:
4415 atag = 0
4416 for e in (self.elt_list):
4417 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4418 atag += 1
4419 if autotag and hasattr(self, 'ext_list'):
4420 for e in (self.ext_list):
4421 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4422 atag += 1
4423 for e in (self.elt_list):
4424 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4425 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4426 ectx.eth_sel_req(ident, e.name)
4427 if hasattr(self, 'ext_list'):
4428 for e in (self.ext_list):
4429 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4430 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4431 ectx.eth_sel_req(ident, e.name)
4433 def sel_item(self, ident, sel, ectx):
4434 lst = self.elt_list[:]
4435 if hasattr(self, 'ext_list'):
4436 lst.extend(self.ext_list)
4437 ee = None
4438 for e in (self.elt_list):
4439 if e.IsNamed() and (e.name == sel):
4440 ee = e
4441 break
4442 if not ee:
4443 print("#CHOICE %s does not contain item %s" % (ident, sel))
4444 return ee
4446 def sel_req(self, ident, sel, ectx):
4447 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4448 ee = self.sel_item(ident, sel, ectx)
4449 if ee:
4450 ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
4452 def eth_ftype(self, ectx):
4453 return ('FT_UINT32', 'BASE_DEC')
4455 def eth_ftype_sel(self, sel, ectx):
4456 ee = self.sel_item('', sel, ectx)
4457 if ee:
4458 return ee.eth_ftype(ectx)
4459 else:
4460 return ('FT_NONE', 'BASE_NONE')
4462 def eth_strings(self):
4463 return '$$'
4465 def eth_need_tree(self):
4466 return True
4468 def eth_has_vals(self):
4469 return True
4471 def GetTTag(self, ectx):
4472 lst = self.elt_list
4473 cls = 'BER_CLASS_ANY/*choice*/'
4474 #if hasattr(self, 'ext_list'):
4475 # lst.extend(self.ext_list)
4476 #if (len(lst) > 0):
4477 # cls = lst[0].GetTag(ectx)[0]
4478 #for e in (lst):
4479 # if (e.GetTag(ectx)[0] != cls):
4480 # cls = '-1/*choice*/'
4481 return (cls, '-1/*choice*/')
4483 def GetTTagSel(self, sel, ectx):
4484 ee = self.sel_item('', sel, ectx)
4485 if ee:
4486 return ee.GetTag(ectx)
4487 else:
4488 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4490 def IndetermTag(self, ectx):
4491 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4492 return not self.HasOwnTag()
4494 def detect_tagval(self, ectx):
4495 tagval = False
4496 lst = self.elt_list[:]
4497 if hasattr(self, 'ext_list'):
4498 lst.extend(self.ext_list)
4499 if (len(lst) > 0) and (not ectx.Per() or lst[0].HasOwnTag()):
4500 t = lst[0].GetTag(ectx)[0]
4501 tagval = True
4502 else:
4503 t = ''
4504 tagval = False
4505 if (t == 'BER_CLASS_UNI'):
4506 tagval = False
4507 for e in (lst):
4508 if not ectx.Per() or e.HasOwnTag():
4509 tt = e.GetTag(ectx)[0]
4510 else:
4511 tt = ''
4512 tagval = False
4513 if (tt != t):
4514 tagval = False
4515 return tagval
4517 def get_vals(self, ectx):
4518 tagval = self.detect_tagval(ectx)
4519 vals = []
4520 cnt = 0
4521 for e in (self.elt_list):
4522 if (tagval): val = e.GetTag(ectx)[1]
4523 else: val = str(cnt)
4524 vals.append((val, e.name))
4525 cnt += 1
4526 if hasattr(self, 'ext_list'):
4527 for e in (self.ext_list):
4528 if (tagval): val = e.GetTag(ectx)[1]
4529 else: val = str(cnt)
4530 vals.append((val, e.name))
4531 cnt += 1
4532 return vals
4534 def eth_type_vals(self, tname, ectx):
4535 out = '\n'
4536 vals = self.get_vals(ectx)
4537 out += ectx.eth_vals(tname, vals)
4538 return out
4540 def reg_enum_vals(self, tname, ectx):
4541 vals = self.get_vals(ectx)
4542 for (val, id) in vals:
4543 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4545 def eth_type_enum(self, tname, ectx):
4546 out = '\n'
4547 vals = self.get_vals(ectx)
4548 out += ectx.eth_enum(tname, vals)
4549 return out
4551 def eth_type_default_pars(self, ectx, tname):
4552 pars = Type.eth_type_default_pars(self, ectx, tname)
4553 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4554 return pars
4556 def eth_type_default_table(self, ectx, tname):
4557 def out_item(val, e, ext, ectx):
4558 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
4559 if (has_enum):
4560 vval = ectx.eth_enum_item(tname, e.name)
4561 else:
4562 vval = val
4563 f = fname + '/' + e.name
4564 ef = ectx.field[f]['ethname']
4565 t = ectx.eth_hf[ef]['ethtype']
4566 if (ectx.Ber()):
4567 opt = ''
4568 if (not e.HasOwnTag()):
4569 opt = 'BER_FLAGS_NOOWNTAG'
4570 elif (e.HasImplicitTag(ectx)):
4571 if (opt): opt += '|'
4572 opt += 'BER_FLAGS_IMPLTAG'
4573 if (not opt): opt = '0'
4574 if (ectx.Ber()):
4575 (tc, tn) = e.GetTag(ectx)
4576 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4577 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
4578 elif (ectx.Per()):
4579 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4580 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
4581 else:
4582 out = ''
4583 return out
4584 # end out_item()
4585 #print "eth_type_default_table(tname='%s')" % (tname)
4586 fname = ectx.eth_type[tname]['ref'][0]
4587 tagval = self.detect_tagval(ectx)
4588 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4589 cnt = 0
4590 if hasattr(self, 'ext_list'):
4591 ext = 'ASN1_EXTENSION_ROOT'
4592 else:
4593 ext = 'ASN1_NO_EXTENSIONS'
4594 empty_ext_flag = '0'
4595 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0):
4596 empty_ext_flag = ext
4597 for e in (self.elt_list):
4598 if (tagval): val = e.GetTag(ectx)[1]
4599 else: val = str(cnt)
4600 table += out_item(val, e, ext, ectx)
4601 cnt += 1
4602 if hasattr(self, 'ext_list'):
4603 for e in (self.ext_list):
4604 if (tagval): val = e.GetTag(ectx)[1]
4605 else: val = str(cnt)
4606 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4607 cnt += 1
4608 if (ectx.Ber()):
4609 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4610 else:
4611 table += " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag)
4612 return table
4614 def eth_type_default_body(self, ectx, tname):
4615 if (ectx.Ber()):
4616 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4617 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4618 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4619 ('%(VAL_PTR)s',),))
4620 elif (ectx.Per()):
4621 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4622 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4623 ('%(ETT_INDEX)s', '%(TABLE)s',),
4624 ('%(VAL_PTR)s',),))
4625 else:
4626 body = '#error Can not decode %s' % (tname)
4627 return body
4629 #--- ChoiceValue ----------------------------------------------------
4630 class ChoiceValue (Value):
4631 def to_str(self, ectx):
4632 return self.val.to_str(ectx)
4634 def fld_obj_eq(self, other):
4635 return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
4637 #--- EnumeratedType -----------------------------------------------------------
4638 class EnumeratedType (Type):
4639 def to_python (self, ctx):
4640 def strify_one (named_num):
4641 return "%s=%s" % (named_num.ident, named_num.val)
4642 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
4644 def eth_ftype(self, ectx):
4645 return ('FT_UINT32', 'BASE_DEC')
4647 def eth_strings(self):
4648 return '$$'
4650 def eth_has_vals(self):
4651 return True
4653 def GetTTag(self, ectx):
4654 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4656 def get_vals_etc(self, ectx):
4657 vals = []
4658 lastv = 0
4659 used = {}
4660 maxv = 0
4661 root_num = 0
4662 ext_num = 0
4663 map_table = []
4664 for e in (self.val):
4665 if e.type == 'NamedNumber':
4666 used[int(e.val)] = True
4667 for e in (self.val):
4668 if e.type == 'NamedNumber':
4669 val = int(e.val)
4670 else:
4671 while lastv in used:
4672 lastv += 1
4673 val = lastv
4674 used[val] = True
4675 vals.append((val, e.ident))
4676 map_table.append(val)
4677 root_num += 1
4678 if val > maxv:
4679 maxv = val
4680 if self.ext is not None:
4681 for e in (self.ext):
4682 if e.type == 'NamedNumber':
4683 used[int(e.val)] = True
4684 for e in (self.ext):
4685 if e.type == 'NamedNumber':
4686 val = int(e.val)
4687 else:
4688 while lastv in used:
4689 lastv += 1
4690 val = lastv
4691 used[val] = True
4692 vals.append((val, e.ident))
4693 map_table.append(val)
4694 ext_num += 1
4695 if val > maxv:
4696 maxv = val
4697 need_map = False
4698 for i in range(len(map_table)):
4699 need_map = need_map or (map_table[i] != i)
4700 if (not need_map):
4701 map_table = None
4702 return (vals, root_num, ext_num, map_table)
4704 def eth_type_vals(self, tname, ectx):
4705 out = '\n'
4706 vals = self.get_vals_etc(ectx)[0]
4707 out += ectx.eth_vals(tname, vals)
4708 return out
4710 def reg_enum_vals(self, tname, ectx):
4711 vals = self.get_vals_etc(ectx)[0]
4712 for (val, id) in vals:
4713 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4715 def eth_type_enum(self, tname, ectx):
4716 out = '\n'
4717 vals = self.get_vals_etc(ectx)[0]
4718 out += ectx.eth_enum(tname, vals)
4719 return out
4721 def eth_type_default_pars(self, ectx, tname):
4722 pars = Type.eth_type_default_pars(self, ectx, tname)
4723 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
4724 if (self.ext != None):
4725 ext = 'TRUE'
4726 else:
4727 ext = 'FALSE'
4728 pars['ROOT_NUM'] = str(root_num)
4729 pars['EXT'] = ext
4730 pars['EXT_NUM'] = str(ext_num)
4731 if (map_table):
4732 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4733 else:
4734 pars['TABLE'] = 'NULL'
4735 return pars
4737 def eth_type_default_table(self, ectx, tname):
4738 if (not ectx.Per()): return ''
4739 map_table = self.get_vals_etc(ectx)[3]
4740 if (map_table == None): return ''
4741 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4742 table += ", ".join([str(v) for v in map_table])
4743 table += "};\n"
4744 return table
4746 def eth_type_default_body(self, ectx, tname):
4747 if (ectx.Ber()):
4748 if (ectx.constraints_check and self.HasValueConstraint()):
4749 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
4750 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4751 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4752 else:
4753 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4754 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4755 ('%(VAL_PTR)s',),))
4756 elif (ectx.Per()):
4757 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
4758 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4759 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4760 else:
4761 body = '#error Can not decode %s' % (tname)
4762 return body
4764 #--- EmbeddedPDVType -----------------------------------------------------------
4765 class EmbeddedPDVType (Type):
4766 def eth_tname(self):
4767 return 'EMBEDDED_PDV'
4769 def eth_ftype(self, ectx):
4770 return ('FT_NONE', 'BASE_NONE')
4772 def GetTTag(self, ectx):
4773 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4775 def eth_type_default_pars(self, ectx, tname):
4776 pars = Type.eth_type_default_pars(self, ectx, tname)
4777 if ectx.default_embedded_pdv_cb:
4778 pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb
4779 else:
4780 pars['TYPE_REF_FN'] = 'NULL'
4781 return pars
4783 def eth_type_default_body(self, ectx, tname):
4784 if (ectx.Ber()):
4785 body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset',
4786 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4787 elif (ectx.Per()):
4788 body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset',
4789 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4790 else:
4791 body = '#error Can not decode %s' % (tname)
4792 return body
4794 #--- ExternalType -----------------------------------------------------------
4795 class ExternalType (Type):
4796 def eth_tname(self):
4797 return 'EXTERNAL'
4799 def eth_ftype(self, ectx):
4800 return ('FT_NONE', 'BASE_NONE')
4802 def GetTTag(self, ectx):
4803 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4805 def eth_type_default_pars(self, ectx, tname):
4806 pars = Type.eth_type_default_pars(self, ectx, tname)
4807 if ectx.default_external_type_cb:
4808 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4809 else:
4810 pars['TYPE_REF_FN'] = 'NULL'
4811 return pars
4813 def eth_type_default_body(self, ectx, tname):
4814 if (ectx.Ber()):
4815 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4816 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4817 elif (ectx.Per()):
4818 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4819 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4820 else:
4821 body = '#error Can not decode %s' % (tname)
4822 return body
4824 #--- OpenType -----------------------------------------------------------
4825 class OpenType (Type):
4826 def to_python (self, ctx):
4827 return "asn1.ANY"
4829 def single_type(self):
4830 if (self.HasConstraint() and
4831 self.constr.type == 'Type' and
4832 self.constr.subtype.type == 'Type_Ref'):
4833 return self.constr.subtype.val
4834 return None
4836 def eth_reg_sub(self, ident, ectx):
4837 t = self.single_type()
4838 if t:
4839 ectx.eth_dep_add(ident, t)
4841 def eth_tname(self):
4842 t = self.single_type()
4843 if t:
4844 return 'OpenType_' + t
4845 else:
4846 return Type.eth_tname(self)
4848 def eth_ftype(self, ectx):
4849 return ('FT_NONE', 'BASE_NONE')
4851 def GetTTag(self, ectx):
4852 return ('BER_CLASS_ANY', '0')
4854 def eth_type_default_pars(self, ectx, tname):
4855 pars = Type.eth_type_default_pars(self, ectx, tname)
4856 pars['FN_VARIANT'] = ectx.default_opentype_variant
4857 t = self.single_type()
4858 if t:
4859 t = ectx.type[t]['ethname']
4860 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4861 pars['TYPE_REF_TNAME'] = t
4862 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4863 else:
4864 pars['TYPE_REF_FN'] = 'NULL'
4865 return pars
4867 def eth_type_default_body(self, ectx, tname):
4868 if (ectx.Per()):
4869 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
4870 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4871 else:
4872 body = '#error Can not decode %s' % (tname)
4873 return body
4875 #--- InstanceOfType -----------------------------------------------------------
4876 class InstanceOfType (Type):
4877 def eth_tname(self):
4878 return 'INSTANCE_OF'
4880 def eth_ftype(self, ectx):
4881 return ('FT_NONE', 'BASE_NONE')
4883 def GetTTag(self, ectx):
4884 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4886 def eth_type_default_pars(self, ectx, tname):
4887 pars = Type.eth_type_default_pars(self, ectx, tname)
4888 if ectx.default_external_type_cb:
4889 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4890 else:
4891 pars['TYPE_REF_FN'] = 'NULL'
4892 return pars
4894 def eth_type_default_body(self, ectx, tname):
4895 if (ectx.Ber()):
4896 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4897 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4898 elif (ectx.Per()):
4899 body = '#error Can not decode %s' % (tname)
4900 else:
4901 body = '#error Can not decode %s' % (tname)
4902 return body
4904 #--- AnyType -----------------------------------------------------------
4905 class AnyType (Type):
4906 def to_python (self, ctx):
4907 return "asn1.ANY"
4909 def eth_ftype(self, ectx):
4910 return ('FT_NONE', 'BASE_NONE')
4912 def GetTTag(self, ectx):
4913 return ('BER_CLASS_ANY', '0')
4915 def eth_type_default_body(self, ectx, tname):
4916 body = '#error Can not decode %s' % (tname)
4917 return body
4919 class Literal (Node):
4920 def to_python (self, ctx):
4921 return self.val
4923 #--- NullType -----------------------------------------------------------------
4924 class NullType (Type):
4925 def to_python (self, ctx):
4926 return 'asn1.NULL'
4928 def eth_tname(self):
4929 return 'NULL'
4931 def GetTTag(self, ectx):
4932 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
4934 def eth_type_default_body(self, ectx, tname):
4935 if (ectx.Ber()):
4936 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4937 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4938 elif (ectx.Per()):
4939 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4940 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4941 else:
4942 body = '#error Can not decode %s' % (tname)
4943 return body
4945 #--- NullValue ----------------------------------------------------
4946 class NullValue (Value):
4947 def to_str(self, ectx):
4948 return 'NULL'
4950 #--- RealType -----------------------------------------------------------------
4951 class RealType (Type):
4952 def to_python (self, ctx):
4953 return 'asn1.REAL'
4955 def eth_tname(self):
4956 return 'REAL'
4958 def GetTTag(self, ectx):
4959 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
4961 def eth_ftype(self, ectx):
4962 return ('FT_DOUBLE', 'BASE_NONE')
4964 def eth_type_default_body(self, ectx, tname):
4965 if (ectx.Ber()):
4966 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4967 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4968 ('%(VAL_PTR)s',),))
4969 elif (ectx.Per()):
4970 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4971 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4972 else:
4973 body = '#error Can not decode %s' % (tname)
4974 return body
4976 #--- BooleanType --------------------------------------------------------------
4977 class BooleanType (Type):
4978 def to_python (self, ctx):
4979 return 'asn1.BOOLEAN'
4981 def eth_tname(self):
4982 return 'BOOLEAN'
4984 def GetTTag(self, ectx):
4985 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
4987 def eth_ftype(self, ectx):
4988 return ('FT_BOOLEAN', 'BASE_NONE')
4990 def eth_type_default_body(self, ectx, tname):
4991 if (ectx.Ber()):
4992 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4993 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
4994 elif (ectx.Per()):
4995 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4996 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4997 else:
4998 body = '#error Can not decode %s' % (tname)
4999 return body
5001 #--- OctetStringType ----------------------------------------------------------
5002 class OctetStringType (Type):
5003 def to_python (self, ctx):
5004 return 'asn1.OCTSTRING'
5006 def eth_tname(self):
5007 if not self.HasConstraint():
5008 return 'OCTET_STRING'
5009 elif self.constr.type == 'Size':
5010 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
5011 else:
5012 return '#' + self.type + '_' + str(id(self))
5014 def eth_ftype(self, ectx):
5015 return ('FT_BYTES', 'BASE_NONE')
5017 def GetTTag(self, ectx):
5018 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
5020 def eth_need_pdu(self, ectx):
5021 pdu = None
5022 if self.HasContentsConstraint():
5023 t = self.constr.GetContents(ectx)
5024 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5025 pdu = { 'type' : t,
5026 'new' : ectx.default_containing_variant == '_pdu_new' }
5027 return pdu
5029 def eth_type_default_pars(self, ectx, tname):
5030 pars = Type.eth_type_default_pars(self, ectx, tname)
5031 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5032 if self.HasContentsConstraint():
5033 pars['FN_VARIANT'] = ectx.default_containing_variant
5034 t = self.constr.GetContents(ectx)
5035 if t:
5036 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5037 t = ectx.field[t]['ethname']
5038 pars['TYPE_REF_PROTO'] = ''
5039 pars['TYPE_REF_TNAME'] = t
5040 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5041 else:
5042 t = ectx.type[t]['ethname']
5043 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5044 pars['TYPE_REF_TNAME'] = t
5045 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5046 else:
5047 pars['TYPE_REF_FN'] = 'NULL'
5048 return pars
5050 def eth_type_default_body(self, ectx, tname):
5051 if (ectx.Ber()):
5052 if (ectx.constraints_check and self.HasSizeConstraint()):
5053 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret='offset',
5054 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5055 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5056 else:
5057 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5058 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5059 ('%(VAL_PTR)s',),))
5060 elif (ectx.Per()):
5061 if self.HasContentsConstraint():
5062 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
5063 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5064 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
5065 else:
5066 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5067 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5068 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
5069 else:
5070 body = '#error Can not decode %s' % (tname)
5071 return body
5073 #--- CharacterStringType ------------------------------------------------------
5074 class CharacterStringType (Type):
5075 def eth_tname(self):
5076 if not self.HasConstraint():
5077 return self.eth_tsname()
5078 elif self.constr.type == 'Size':
5079 return self.eth_tsname() + '_' + self.constr.eth_constrname()
5080 else:
5081 return '#' + self.type + '_' + str(id(self))
5083 def eth_ftype(self, ectx):
5084 return ('FT_STRING', 'BASE_NONE')
5086 class RestrictedCharacterStringType (CharacterStringType):
5087 def to_python (self, ctx):
5088 return 'asn1.' + self.eth_tsname()
5090 def GetTTag(self, ectx):
5091 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
5093 def eth_type_default_pars(self, ectx, tname):
5094 pars = Type.eth_type_default_pars(self, ectx, tname)
5095 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5096 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
5097 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
5098 return pars
5100 def eth_type_default_body(self, ectx, tname):
5101 if (ectx.Ber()):
5102 if (ectx.constraints_check and self.HasSizeConstraint()):
5103 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret='offset',
5104 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5105 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5106 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5107 else:
5108 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
5109 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5110 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5111 ('%(VAL_PTR)s',),))
5112 elif (ectx.Per() and self.HasPermAlph()):
5113 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
5114 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5115 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
5116 ('%(VAL_PTR)s',),))
5117 elif (ectx.Per()):
5118 if (self.eth_tsname() == 'GeneralString'):
5119 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5120 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5121 elif (self.eth_tsname() == 'GeneralizedTime'):
5122 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
5123 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5124 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5125 elif (self.eth_tsname() == 'UTCTime'):
5126 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
5127 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5128 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5129 else:
5130 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5131 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5132 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5133 else:
5134 body = '#error Can not decode %s' % (tname)
5135 return body
5137 class BMPStringType (RestrictedCharacterStringType):
5138 def eth_tsname(self):
5139 return 'BMPString'
5141 class GeneralStringType (RestrictedCharacterStringType):
5142 def eth_tsname(self):
5143 return 'GeneralString'
5145 class GraphicStringType (RestrictedCharacterStringType):
5146 def eth_tsname(self):
5147 return 'GraphicString'
5149 class IA5StringType (RestrictedCharacterStringType):
5150 def eth_tsname(self):
5151 return 'IA5String'
5153 class NumericStringType (RestrictedCharacterStringType):
5154 def eth_tsname(self):
5155 return 'NumericString'
5157 class PrintableStringType (RestrictedCharacterStringType):
5158 def eth_tsname(self):
5159 return 'PrintableString'
5161 class TeletexStringType (RestrictedCharacterStringType):
5162 def eth_tsname(self):
5163 return 'TeletexString'
5165 class T61StringType (RestrictedCharacterStringType):
5166 def eth_tsname(self):
5167 return 'T61String'
5168 def GetTTag(self, ectx):
5169 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
5171 class UniversalStringType (RestrictedCharacterStringType):
5172 def eth_tsname(self):
5173 return 'UniversalString'
5175 class UTF8StringType (RestrictedCharacterStringType):
5176 def eth_tsname(self):
5177 return 'UTF8String'
5179 class VideotexStringType (RestrictedCharacterStringType):
5180 def eth_tsname(self):
5181 return 'VideotexString'
5183 class VisibleStringType (RestrictedCharacterStringType):
5184 def eth_tsname(self):
5185 return 'VisibleString'
5187 class ISO646StringType (RestrictedCharacterStringType):
5188 def eth_tsname(self):
5189 return 'ISO646String'
5190 def GetTTag(self, ectx):
5191 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
5193 class UnrestrictedCharacterStringType (CharacterStringType):
5194 def to_python (self, ctx):
5195 return 'asn1.UnrestrictedCharacterString'
5196 def eth_tsname(self):
5197 return 'CHARACTER_STRING'
5199 #--- UsefulType ---------------------------------------------------------------
5200 class GeneralizedTime (RestrictedCharacterStringType):
5201 def eth_tsname(self):
5202 return 'GeneralizedTime'
5204 def eth_type_default_body(self, ectx, tname):
5205 if (ectx.Ber()):
5206 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5207 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5208 return body
5209 else:
5210 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5212 class UTCTime (RestrictedCharacterStringType):
5213 def eth_tsname(self):
5214 return 'UTCTime'
5216 def eth_type_default_body(self, ectx, tname):
5217 if (ectx.Ber()):
5218 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5219 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5220 return body
5221 else:
5222 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5224 class ObjectDescriptor (RestrictedCharacterStringType):
5225 def eth_tsname(self):
5226 return 'ObjectDescriptor'
5228 def eth_type_default_body(self, ectx, tname):
5229 if (ectx.Ber()):
5230 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5231 elif (ectx.Per()):
5232 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
5233 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5234 else:
5235 body = '#error Can not decode %s' % (tname)
5236 return body
5238 #--- ObjectIdentifierType -----------------------------------------------------
5239 class ObjectIdentifierType (Type):
5240 def to_python (self, ctx):
5241 return 'asn1.OBJECT_IDENTIFIER'
5243 def eth_tname(self):
5244 return 'OBJECT_IDENTIFIER'
5246 def eth_ftype(self, ectx):
5247 return ('FT_OID', 'BASE_NONE')
5249 def GetTTag(self, ectx):
5250 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
5252 def eth_type_default_pars(self, ectx, tname):
5253 pars = Type.eth_type_default_pars(self, ectx, tname)
5254 pars['FN_VARIANT'] = ectx.default_oid_variant
5255 return pars
5257 def eth_type_default_body(self, ectx, tname):
5258 if (ectx.Ber()):
5259 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5260 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5261 elif (ectx.Per()):
5262 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5263 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5264 else:
5265 body = '#error Can not decode %s' % (tname)
5266 return body
5268 #--- ObjectIdentifierValue ----------------------------------------------------
5269 class ObjectIdentifierValue (Value):
5270 def get_num(self, path, val):
5271 return str(oid_names.get(path + '/' + val, val))
5273 def to_str(self, ectx):
5274 out = ''
5275 path = ''
5276 first = True
5277 sep = ''
5278 for v in self.comp_list:
5279 if isinstance(v, Node) and (v.type == 'name_and_number'):
5280 vstr = v.number
5281 elif v.isdigit():
5282 vstr = v
5283 else:
5284 vstr = self.get_num(path, v)
5285 if not first and not vstr.isdigit():
5286 vstr = ectx.value_get_val(vstr)
5287 if first:
5288 if vstr.isdigit():
5289 out += '"' + vstr
5290 else:
5291 out += ectx.value_get_eth(vstr) + '"'
5292 else:
5293 out += sep + vstr
5294 path += sep + vstr
5295 first = False
5296 sep = '.'
5297 out += '"'
5298 return out
5300 def get_dep(self):
5301 v = self.comp_list[0]
5302 if isinstance(v, Node) and (v.type == 'name_and_number'):
5303 return None
5304 elif v.isdigit():
5305 return None
5306 else:
5307 vstr = self.get_num('', v)
5308 if vstr.isdigit():
5309 return None
5310 else:
5311 return vstr
5313 class NamedNumber(Node):
5314 def to_python (self, ctx):
5315 return "('%s',%s)" % (self.ident, self.val)
5317 class NamedNumListBase(Node):
5318 def to_python (self, ctx):
5319 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
5320 [x.to_python (ctx) for x in self.named_list]))
5322 #--- RelativeOIDType ----------------------------------------------------------
5323 class RelativeOIDType (Type):
5325 def eth_tname(self):
5326 return 'RELATIVE_OID'
5328 def eth_ftype(self, ectx):
5329 return ('FT_REL_OID', 'BASE_NONE')
5331 def GetTTag(self, ectx):
5332 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5334 def eth_type_default_pars(self, ectx, tname):
5335 pars = Type.eth_type_default_pars(self, ectx, tname)
5336 pars['FN_VARIANT'] = ectx.default_oid_variant
5337 return pars
5339 def eth_type_default_body(self, ectx, tname):
5340 if (ectx.Ber()):
5341 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5342 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5343 elif (ectx.Per()):
5344 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5345 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5346 else:
5347 body = '#error Can not decode %s' % (tname)
5348 return body
5351 #--- IntegerType --------------------------------------------------------------
5352 class IntegerType (Type):
5353 def to_python (self, ctx):
5354 return "asn1.INTEGER_class ([%s])" % (",".join (
5355 [x.to_python (ctx) for x in self.named_list]))
5357 def add_named_value(self, ident, val):
5358 e = NamedNumber(ident = ident, val = val)
5359 if not self.named_list:
5360 self.named_list = []
5361 self.named_list.append(e)
5363 def eth_tname(self):
5364 if self.named_list:
5365 return Type.eth_tname(self)
5366 if not self.HasConstraint():
5367 return 'INTEGER'
5368 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
5369 return 'INTEGER' + '_' + self.constr.eth_constrname()
5370 else:
5371 return 'INTEGER' + '_' + self.constr.eth_tname()
5373 def GetTTag(self, ectx):
5374 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5377 def eth_ftype(self, ectx):
5378 if self.HasConstraint():
5379 if not self.constr.IsNegativ():
5380 return ('FT_UINT32', 'BASE_DEC')
5381 return ('FT_INT32', 'BASE_DEC')
5383 def eth_strings(self):
5384 if (self.named_list):
5385 return '$$'
5386 else:
5387 return 'NULL'
5389 def eth_has_vals(self):
5390 if (self.named_list):
5391 return True
5392 else:
5393 return False
5395 def get_vals(self, ectx):
5396 vals = []
5397 for e in (self.named_list):
5398 vals.append((int(e.val), e.ident))
5399 return vals
5401 def eth_type_vals(self, tname, ectx):
5402 if not self.eth_has_vals(): return ''
5403 out = '\n'
5404 vals = self.get_vals(ectx)
5405 out += ectx.eth_vals(tname, vals)
5406 return out
5408 def reg_enum_vals(self, tname, ectx):
5409 vals = self.get_vals(ectx)
5410 for (val, id) in vals:
5411 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
5413 def eth_type_enum(self, tname, ectx):
5414 if not self.eth_has_enum(tname, ectx): return ''
5415 out = '\n'
5416 vals = self.get_vals(ectx)
5417 out += ectx.eth_enum(tname, vals)
5418 return out
5420 def eth_type_default_pars(self, ectx, tname):
5421 pars = Type.eth_type_default_pars(self, ectx, tname)
5422 if self.HasValueConstraint():
5423 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
5424 return pars
5426 def eth_type_default_body(self, ectx, tname):
5427 if (ectx.Ber()):
5428 if (ectx.constraints_check and self.HasValueConstraint()):
5429 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5430 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5431 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5432 else:
5433 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5434 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5435 ('%(VAL_PTR)s',),))
5436 elif (ectx.Per() and not self.HasValueConstraint()):
5437 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5438 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5439 elif (ectx.Per() and self.HasValueConstraint()):
5440 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5441 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5442 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5443 else:
5444 body = '#error Can not decode %s' % (tname)
5445 return body
5447 #--- BitStringType ------------------------------------------------------------
5448 class BitStringType (Type):
5449 def to_python (self, ctx):
5450 return "asn1.BITSTRING_class ([%s])" % (",".join (
5451 [x.to_python (ctx) for x in self.named_list]))
5453 def eth_tname(self):
5454 if self.named_list:
5455 return Type.eth_tname(self)
5456 elif not self.HasConstraint():
5457 return 'BIT_STRING'
5458 elif self.constr.IsSize():
5459 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
5460 else:
5461 return '#' + self.type + '_' + str(id(self))
5463 def GetTTag(self, ectx):
5464 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5466 def eth_ftype(self, ectx):
5467 return ('FT_BYTES', 'BASE_NONE')
5469 def eth_need_tree(self):
5470 return self.named_list
5472 def eth_need_pdu(self, ectx):
5473 pdu = None
5474 if self.HasContentsConstraint():
5475 t = self.constr.GetContents(ectx)
5476 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5477 pdu = { 'type' : t,
5478 'new' : ectx.default_containing_variant == '_pdu_new' }
5479 return pdu
5481 def eth_named_bits(self):
5482 bits = []
5483 if (self.named_list):
5484 for e in (self.named_list):
5485 bits.append((int(e.val), e.ident))
5486 return bits
5488 def eth_type_default_pars(self, ectx, tname):
5489 pars = Type.eth_type_default_pars(self, ectx, tname)
5490 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5491 if 'ETT_INDEX' not in pars:
5492 pars['ETT_INDEX'] = '-1'
5493 pars['TABLE'] = 'NULL'
5494 if self.eth_named_bits():
5495 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5496 if self.HasContentsConstraint():
5497 pars['FN_VARIANT'] = ectx.default_containing_variant
5498 t = self.constr.GetContents(ectx)
5499 if t:
5500 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5501 t = ectx.field[t]['ethname']
5502 pars['TYPE_REF_PROTO'] = ''
5503 pars['TYPE_REF_TNAME'] = t
5504 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5505 else:
5506 t = ectx.type[t]['ethname']
5507 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5508 pars['TYPE_REF_TNAME'] = t
5509 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5510 else:
5511 pars['TYPE_REF_FN'] = 'NULL'
5512 return pars
5514 def eth_type_default_table(self, ectx, tname):
5515 #print "eth_type_default_table(tname='%s')" % (tname)
5516 table = ''
5517 bits = self.eth_named_bits()
5518 if (bits and ectx.Ber()):
5519 table = ectx.eth_bits(tname, bits)
5520 return table
5522 def eth_type_default_body(self, ectx, tname):
5523 if (ectx.Ber()):
5524 if (ectx.constraints_check and self.HasSizeConstraint()):
5525 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret='offset',
5526 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5527 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5528 ('%(VAL_PTR)s',),))
5529 else:
5530 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
5531 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5532 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5533 ('%(VAL_PTR)s',),))
5534 elif (ectx.Per()):
5535 if self.HasContentsConstraint():
5536 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
5537 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5538 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5539 else:
5540 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
5541 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5542 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s'),))
5543 else:
5544 body = '#error Can not decode %s' % (tname)
5545 return body
5547 #--- BStringValue ------------------------------------------------------------
5548 bstring_tab = {
5549 '0000' : '0',
5550 '0001' : '1',
5551 '0010' : '2',
5552 '0011' : '3',
5553 '0100' : '4',
5554 '0101' : '5',
5555 '0110' : '6',
5556 '0111' : '7',
5557 '1000' : '8',
5558 '1001' : '9',
5559 '1010' : 'A',
5560 '1011' : 'B',
5561 '1100' : 'C',
5562 '1101' : 'D',
5563 '1110' : 'E',
5564 '1111' : 'F',
5566 class BStringValue (Value):
5567 def to_str(self, ectx):
5568 v = self.val[1:-2]
5569 if len(v) % 8:
5570 v += '0' * (8 - len(v) % 8)
5571 vv = '0x'
5572 for i in (list(range(0, len(v), 4))):
5573 vv += bstring_tab[v[i:i+4]]
5574 return vv
5576 #--- HStringValue ------------------------------------------------------------
5577 class HStringValue (Value):
5578 def to_str(self, ectx):
5579 vv = '0x'
5580 vv += self.val[1:-2]
5581 return vv
5582 def __int__(self):
5583 return int(self.val[1:-2], 16)
5585 #--- FieldSpec ----------------------------------------------------------------
5586 class FieldSpec (Node):
5587 def __init__(self,*args, **kw) :
5588 self.name = None
5589 Node.__init__ (self,*args, **kw)
5591 def SetName(self, name):
5592 self.name = name
5594 def get_repr(self):
5595 return ['#UNSUPPORTED_' + self.type]
5597 def fld_repr(self):
5598 repr = [self.name]
5599 repr.extend(self.get_repr())
5600 return repr
5602 class TypeFieldSpec (FieldSpec):
5603 def get_repr(self):
5604 return []
5606 class FixedTypeValueFieldSpec (FieldSpec):
5607 def get_repr(self):
5608 if isinstance(self.typ, Type_Ref):
5609 repr = ['TypeReference', self.typ.val]
5610 else:
5611 repr = [self.typ.type]
5612 return repr
5614 class VariableTypeValueFieldSpec (FieldSpec):
5615 def get_repr(self):
5616 return ['_' + self.type]
5618 class FixedTypeValueSetFieldSpec (FieldSpec):
5619 def get_repr(self):
5620 return ['_' + self.type]
5622 class ObjectFieldSpec (FieldSpec):
5623 def get_repr(self):
5624 return ['ClassReference', self.cls.val]
5626 class ObjectSetFieldSpec (FieldSpec):
5627 def get_repr(self):
5628 return ['ClassReference', self.cls.val]
5630 #==============================================================================
5632 def p_module_list_1 (t):
5633 'module_list : module_list ModuleDefinition'
5634 t[0] = t[1] + [t[2]]
5636 def p_module_list_2 (t):
5637 'module_list : ModuleDefinition'
5638 t[0] = [t[1]]
5641 #--- ITU-T Recommendation X.680 -----------------------------------------------
5644 # 11 ASN.1 lexical items --------------------------------------------------------
5646 # 11.2 Type references
5647 def p_type_ref (t):
5648 'type_ref : UCASE_IDENT'
5649 t[0] = Type_Ref(val=t[1])
5651 # 11.3 Identifiers
5652 def p_identifier (t):
5653 'identifier : LCASE_IDENT'
5654 t[0] = t[1]
5656 # 11.4 Value references
5657 # cause reduce/reduce conflict
5658 #def p_valuereference (t):
5659 # 'valuereference : LCASE_IDENT'
5660 # t[0] = Value_Ref(val=t[1])
5662 # 11.5 Module references
5663 def p_modulereference (t):
5664 'modulereference : UCASE_IDENT'
5665 t[0] = t[1]
5668 # 12 Module definition --------------------------------------------------------
5670 # 12.1
5671 def p_ModuleDefinition (t):
5672 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5673 t[0] = Module (ident = t[1], tag_def = t[3], body = t[7])
5675 def p_ModuleBegin (t):
5676 'ModuleBegin : '
5677 if t[-4].val == 'Remote-Operations-Information-Objects':
5678 x880_module_begin()
5680 def p_TagDefault_1 (t):
5681 '''TagDefault : EXPLICIT TAGS
5682 | IMPLICIT TAGS
5683 | AUTOMATIC TAGS '''
5684 t[0] = Default_Tags (dfl_tag = t[1])
5686 def p_TagDefault_2 (t):
5687 'TagDefault : '
5688 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5689 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
5691 def p_ModuleIdentifier_1 (t):
5692 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5693 t [0] = Node('module_ident', val = t[1], ident = t[2])
5695 def p_ModuleIdentifier_2 (t):
5696 'ModuleIdentifier : modulereference' # name, oid
5697 t [0] = Node('module_ident', val = t[1], ident = None)
5699 def p_DefinitiveIdentifier (t):
5700 'DefinitiveIdentifier : ObjectIdentifierValue'
5701 t[0] = t[1]
5703 #def p_module_ref (t):
5704 # 'module_ref : UCASE_IDENT'
5705 # t[0] = t[1]
5707 def p_ModuleBody_1 (t):
5708 'ModuleBody : Exports Imports AssignmentList'
5709 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
5711 def p_ModuleBody_2 (t):
5712 'ModuleBody : '
5713 t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
5715 def p_Exports_1 (t):
5716 'Exports : EXPORTS syms_exported SEMICOLON'
5717 t[0] = t[2]
5719 def p_Exports_2 (t):
5720 'Exports : EXPORTS ALL SEMICOLON'
5721 t[0] = [ 'ALL' ]
5723 def p_Exports_3 (t):
5724 'Exports : '
5725 t[0] = [ 'ALL' ]
5727 def p_syms_exported_1 (t):
5728 'syms_exported : exp_sym_list'
5729 t[0] = t[1]
5731 def p_syms_exported_2 (t):
5732 'syms_exported : '
5733 t[0] = []
5735 def p_exp_sym_list_1 (t):
5736 'exp_sym_list : Symbol'
5737 t[0] = [t[1]]
5739 def p_exp_sym_list_2 (t):
5740 'exp_sym_list : exp_sym_list COMMA Symbol'
5741 t[0] = t[1] + [t[3]]
5744 def p_Imports_1 (t):
5745 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5746 t[0] = t[3]
5747 global lcase_ident_assigned
5748 lcase_ident_assigned = {}
5750 def p_importsbegin (t):
5751 'importsbegin : '
5752 global lcase_ident_assigned
5753 global g_conform
5754 lcase_ident_assigned = {}
5755 lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5757 def p_Imports_2 (t):
5758 'Imports : '
5759 t[0] = []
5761 def p_SymbolsImported_1(t):
5762 'SymbolsImported : '
5763 t[0] = []
5765 def p_SymbolsImported_2 (t):
5766 'SymbolsImported : SymbolsFromModuleList'
5767 t[0] = t[1]
5769 def p_SymbolsFromModuleList_1 (t):
5770 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5771 t[0] = t[1] + [t[2]]
5773 def p_SymbolsFromModuleList_2 (t):
5774 'SymbolsFromModuleList : SymbolsFromModule'
5775 t[0] = [t[1]]
5777 def p_SymbolsFromModule (t):
5778 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
5779 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
5780 for s in (t[0].symbol_list):
5781 if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
5782 import_symbols_from_module(t[0].module, t[0].symbol_list)
5784 def import_symbols_from_module(module, symbol_list):
5785 if module.val == 'Remote-Operations-Information-Objects':
5786 for i in range(len(symbol_list)):
5787 s = symbol_list[i]
5788 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
5789 x880_import(s.val)
5790 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5791 symbol_list[i] = Class_Ref (val = s.val)
5792 return
5793 for i in range(len(symbol_list)):
5794 s = symbol_list[i]
5795 if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)):
5796 import_class_from_module(module.val, s.val)
5797 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5798 symbol_list[i] = Class_Ref (val = s.val)
5800 def p_GlobalModuleReference (t):
5801 'GlobalModuleReference : modulereference AssignedIdentifier'
5802 t [0] = Node('module_ident', val = t[1], ident = t[2])
5804 def p_AssignedIdentifier_1 (t):
5805 'AssignedIdentifier : ObjectIdentifierValue'
5806 t[0] = t[1]
5808 def p_AssignedIdentifier_2 (t):
5809 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5810 t[0] = t[1]
5812 def p_AssignedIdentifier_3 (t):
5813 'AssignedIdentifier : '
5814 pass
5816 def p_SymbolList_1 (t):
5817 'SymbolList : Symbol'
5818 t[0] = [t[1]]
5820 def p_SymbolList_2 (t):
5821 'SymbolList : SymbolList COMMA Symbol'
5822 t[0] = t[1] + [t[3]]
5824 def p_Symbol (t):
5825 '''Symbol : Reference
5826 | ParameterizedReference'''
5827 t[0] = t[1]
5829 def p_Reference_1 (t):
5830 '''Reference : type_ref
5831 | objectclassreference '''
5832 t[0] = t[1]
5834 def p_Reference_2 (t):
5835 '''Reference : LCASE_IDENT_ASSIGNED
5836 | identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5837 t[0] = Value_Ref(val=t[1])
5839 def p_AssignmentList_1 (t):
5840 'AssignmentList : AssignmentList Assignment'
5841 t[0] = t[1] + [t[2]]
5843 def p_AssignmentList_2 (t):
5844 'AssignmentList : Assignment SEMICOLON'
5845 t[0] = [t[1]]
5847 def p_AssignmentList_3 (t):
5848 'AssignmentList : Assignment'
5849 t[0] = [t[1]]
5851 def p_Assignment (t):
5852 '''Assignment : TypeAssignment
5853 | ValueAssignment
5854 | ValueSetTypeAssignment
5855 | ObjectClassAssignment
5856 | ObjectAssignment
5857 | ObjectSetAssignment
5858 | ParameterizedAssignment
5859 | pyquote '''
5860 t[0] = t[1]
5863 # 13 Referencing type and value definitions -----------------------------------
5865 # 13.1
5866 def p_DefinedType (t):
5867 '''DefinedType : ExternalTypeReference
5868 | type_ref
5869 | ParameterizedType'''
5870 t[0] = t[1]
5872 def p_DefinedValue_1(t):
5873 '''DefinedValue : ExternalValueReference'''
5874 t[0] = t[1]
5876 def p_DefinedValue_2(t):
5877 '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5878 t[0] = Value_Ref(val=t[1])
5880 # 13.6
5881 def p_ExternalTypeReference (t):
5882 'ExternalTypeReference : modulereference DOT type_ref'
5883 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
5885 def p_ExternalValueReference (t):
5886 'ExternalValueReference : modulereference DOT identifier'
5887 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
5890 # 15 Assigning types and values -----------------------------------------------
5892 # 15.1
5893 def p_TypeAssignment (t):
5894 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
5895 t[0] = t[3]
5896 t[0].SetName(t[1])
5898 # 15.2
5899 def p_ValueAssignment (t):
5900 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
5901 t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
5903 # only "simple" types are supported to simplify grammer
5904 def p_ValueType (t):
5905 '''ValueType : type_ref
5906 | BooleanType
5907 | IntegerType
5908 | ObjectIdentifierType
5909 | OctetStringType
5910 | RealType '''
5912 t[0] = t[1]
5914 # 15.6
5915 def p_ValueSetTypeAssignment (t):
5916 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
5917 t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4])
5919 # 15.7
5920 def p_ValueSet (t):
5921 'ValueSet : lbraceignore rbraceignore'
5922 t[0] = None
5925 # 16 Definition of types and values -------------------------------------------
5927 # 16.1
5928 def p_Type (t):
5929 '''Type : BuiltinType
5930 | ReferencedType
5931 | ConstrainedType'''
5932 t[0] = t[1]
5934 # 16.2
5935 def p_BuiltinType (t):
5936 '''BuiltinType : AnyType
5937 | BitStringType
5938 | BooleanType
5939 | CharacterStringType
5940 | ChoiceType
5941 | EmbeddedPDVType
5942 | EnumeratedType
5943 | ExternalType
5944 | InstanceOfType
5945 | IntegerType
5946 | NullType
5947 | ObjectClassFieldType
5948 | ObjectIdentifierType
5949 | OctetStringType
5950 | RealType
5951 | RelativeOIDType
5952 | SequenceType
5953 | SequenceOfType
5954 | SetType
5955 | SetOfType
5956 | TaggedType'''
5957 t[0] = t[1]
5959 # 16.3
5960 def p_ReferencedType (t):
5961 '''ReferencedType : DefinedType
5962 | UsefulType
5963 | SelectionType'''
5964 t[0] = t[1]
5966 # 16.5
5967 def p_NamedType (t):
5968 'NamedType : identifier Type'
5969 t[0] = t[2]
5970 t[0].SetName (t[1])
5972 # 16.7
5973 def p_Value (t):
5974 '''Value : BuiltinValue
5975 | ReferencedValue
5976 | ObjectClassFieldValue'''
5977 t[0] = t[1]
5979 # 16.9
5980 def p_BuiltinValue (t):
5981 '''BuiltinValue : BooleanValue
5982 | ChoiceValue
5983 | IntegerValue
5984 | ObjectIdentifierValue
5985 | RealValue
5986 | SequenceValue
5987 | hex_string
5988 | binary_string
5989 | char_string''' # XXX we don't support {data} here
5990 t[0] = t[1]
5992 # 16.11
5993 def p_ReferencedValue (t):
5994 '''ReferencedValue : DefinedValue
5995 | ValueFromObject'''
5996 t[0] = t[1]
5998 # 16.13
5999 #def p_NamedValue (t):
6000 # 'NamedValue : identifier Value'
6001 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
6004 # 17 Notation for the boolean type --------------------------------------------
6006 # 17.1
6007 def p_BooleanType (t):
6008 'BooleanType : BOOLEAN'
6009 t[0] = BooleanType ()
6011 # 17.2
6012 def p_BooleanValue (t):
6013 '''BooleanValue : TRUE
6014 | FALSE'''
6015 t[0] = t[1]
6018 # 18 Notation for the integer type --------------------------------------------
6020 # 18.1
6021 def p_IntegerType_1 (t):
6022 'IntegerType : INTEGER'
6023 t[0] = IntegerType (named_list = None)
6025 def p_IntegerType_2 (t):
6026 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
6027 t[0] = IntegerType(named_list = t[3])
6029 def p_NamedNumberList_1 (t):
6030 'NamedNumberList : NamedNumber'
6031 t[0] = [t[1]]
6033 def p_NamedNumberList_2 (t):
6034 'NamedNumberList : NamedNumberList COMMA NamedNumber'
6035 t[0] = t[1] + [t[3]]
6037 def p_NamedNumber (t):
6038 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
6039 | identifier LPAREN DefinedValue RPAREN'''
6040 t[0] = NamedNumber(ident = t[1], val = t[3])
6042 def p_SignedNumber_1 (t):
6043 'SignedNumber : NUMBER'
6044 t[0] = t [1]
6046 def p_SignedNumber_2 (t):
6047 'SignedNumber : MINUS NUMBER'
6048 t[0] = '-' + t[2]
6050 # 18.9
6051 def p_IntegerValue (t):
6052 'IntegerValue : SignedNumber'
6053 t[0] = t [1]
6055 # 19 Notation for the enumerated type -----------------------------------------
6057 # 19.1
6058 def p_EnumeratedType (t):
6059 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
6060 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
6062 def p_Enumerations_1 (t):
6063 'Enumerations : Enumeration'
6064 t[0] = { 'val' : t[1], 'ext' : None }
6066 def p_Enumerations_2 (t):
6067 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
6068 t[0] = { 'val' : t[1], 'ext' : [] }
6070 def p_Enumerations_3 (t):
6071 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
6072 t[0] = { 'val' : t[1], 'ext' : t[6] }
6074 def p_Enumeration_1 (t):
6075 'Enumeration : EnumerationItem'
6076 t[0] = [t[1]]
6078 def p_Enumeration_2 (t):
6079 'Enumeration : Enumeration COMMA EnumerationItem'
6080 t[0] = t[1] + [t[3]]
6082 def p_EnumerationItem (t):
6083 '''EnumerationItem : Identifier
6084 | NamedNumber'''
6085 t[0] = t[1]
6087 def p_Identifier (t):
6088 'Identifier : identifier'
6089 t[0] = Node ('Identifier', ident = t[1])
6092 # 20 Notation for the real type -----------------------------------------------
6094 # 20.1
6095 def p_RealType (t):
6096 'RealType : REAL'
6097 t[0] = RealType ()
6099 # 20.6
6100 def p_RealValue (t):
6101 '''RealValue : REAL_NUMBER
6102 | SpecialRealValue'''
6103 t[0] = t [1]
6105 def p_SpecialRealValue (t):
6106 '''SpecialRealValue : PLUS_INFINITY
6107 | MINUS_INFINITY'''
6108 t[0] = t[1]
6111 # 21 Notation for the bitstring type ------------------------------------------
6113 # 21.1
6114 def p_BitStringType_1 (t):
6115 'BitStringType : BIT STRING'
6116 t[0] = BitStringType (named_list = None)
6118 def p_BitStringType_2 (t):
6119 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
6120 t[0] = BitStringType (named_list = t[4])
6122 def p_NamedBitList_1 (t):
6123 'NamedBitList : NamedBit'
6124 t[0] = [t[1]]
6126 def p_NamedBitList_2 (t):
6127 'NamedBitList : NamedBitList COMMA NamedBit'
6128 t[0] = t[1] + [t[3]]
6130 def p_NamedBit (t):
6131 '''NamedBit : identifier LPAREN NUMBER RPAREN
6132 | identifier LPAREN DefinedValue RPAREN'''
6133 t[0] = NamedNumber (ident = t[1], val = t[3])
6136 # 22 Notation for the octetstring type ----------------------------------------
6138 # 22.1
6139 def p_OctetStringType (t):
6140 'OctetStringType : OCTET STRING'
6141 t[0] = OctetStringType ()
6144 # 23 Notation for the null type -----------------------------------------------
6146 # 23.1
6147 def p_NullType (t):
6148 'NullType : NULL'
6149 t[0] = NullType ()
6151 # 23.3
6152 def p_NullValue (t):
6153 'NullValue : NULL'
6154 t[0] = NullValue ()
6157 # 24 Notation for sequence types ----------------------------------------------
6159 # 24.1
6160 def p_SequenceType_1 (t):
6161 'SequenceType : SEQUENCE LBRACE RBRACE'
6162 t[0] = SequenceType (elt_list = [])
6164 def p_SequenceType_2 (t):
6165 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
6166 t[0] = SequenceType (elt_list = t[3]['elt_list'])
6167 if 'ext_list' in t[3]:
6168 t[0].ext_list = t[3]['ext_list']
6169 if 'elt_list2' in t[3]:
6170 t[0].elt_list2 = t[3]['elt_list2']
6172 def p_ExtensionAndException_1 (t):
6173 'ExtensionAndException : ELLIPSIS'
6174 t[0] = []
6176 def p_OptionalExtensionMarker_1 (t):
6177 'OptionalExtensionMarker : COMMA ELLIPSIS'
6178 t[0] = True
6180 def p_OptionalExtensionMarker_2 (t):
6181 'OptionalExtensionMarker : '
6182 t[0] = False
6184 def p_ComponentTypeLists_1 (t):
6185 'ComponentTypeLists : ComponentTypeList'
6186 t[0] = {'elt_list' : t[1]}
6188 def p_ComponentTypeLists_2 (t):
6189 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
6190 t[0] = {'elt_list' : t[1], 'ext_list' : []}
6192 def p_ComponentTypeLists_3 (t):
6193 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6194 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6196 def p_ComponentTypeLists_4 (t):
6197 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
6198 t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]}
6200 def p_ComponentTypeLists_5 (t):
6201 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
6202 t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]}
6204 def p_ComponentTypeLists_6 (t):
6205 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
6206 t[0] = {'elt_list' : [], 'ext_list' : []}
6208 def p_ComponentTypeLists_7 (t):
6209 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6210 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
6212 def p_ExtensionEndMarker (t):
6213 'ExtensionEndMarker : COMMA ELLIPSIS'
6214 pass
6216 def p_ExtensionAdditionList_1 (t):
6217 'ExtensionAdditionList : COMMA ExtensionAddition'
6218 t[0] = [t[2]]
6220 def p_ExtensionAdditionList_2 (t):
6221 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition'
6222 t[0] = t[1] + [t[3]]
6224 def p_ExtensionAddition_1 (t):
6225 'ExtensionAddition : ExtensionAdditionGroup'
6226 t[0] = Node ('elt_type', val = t[1], optional = 0)
6228 def p_ExtensionAddition_2 (t):
6229 'ExtensionAddition : ComponentType'
6230 t[0] = t[1]
6232 def p_ExtensionAdditionGroup (t):
6233 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK'
6234 t[0] = ExtensionAdditionGroup (ver = t[2], elt_list = t[3])
6236 def p_VersionNumber_1 (t):
6237 'VersionNumber : '
6239 def p_VersionNumber_2 (t):
6240 'VersionNumber : NUMBER COLON'
6241 t[0] = t[1]
6243 def p_ComponentTypeList_1 (t):
6244 'ComponentTypeList : ComponentType'
6245 t[0] = [t[1]]
6247 def p_ComponentTypeList_2 (t):
6248 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
6249 t[0] = t[1] + [t[3]]
6251 def p_ComponentType_1 (t):
6252 'ComponentType : NamedType'
6253 t[0] = Node ('elt_type', val = t[1], optional = 0)
6255 def p_ComponentType_2 (t):
6256 'ComponentType : NamedType OPTIONAL'
6257 t[0] = Node ('elt_type', val = t[1], optional = 1)
6259 def p_ComponentType_3 (t):
6260 'ComponentType : NamedType DEFAULT DefaultValue'
6261 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
6263 def p_ComponentType_4 (t):
6264 'ComponentType : COMPONENTS OF Type'
6265 t[0] = Node ('components_of', typ = t[3])
6267 def p_DefaultValue_1 (t):
6268 '''DefaultValue : ReferencedValue
6269 | BooleanValue
6270 | ChoiceValue
6271 | IntegerValue
6272 | RealValue
6273 | hex_string
6274 | binary_string
6275 | char_string
6276 | ObjectClassFieldValue'''
6277 t[0] = t[1]
6279 def p_DefaultValue_2 (t):
6280 'DefaultValue : lbraceignore rbraceignore'
6281 t[0] = ''
6283 # 24.17
6284 def p_SequenceValue_1 (t):
6285 'SequenceValue : LBRACE RBRACE'
6286 t[0] = []
6289 #def p_SequenceValue_2 (t):
6290 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
6291 # t[0] = t[2]
6293 #def p_ComponentValueList_1 (t):
6294 # 'ComponentValueList : NamedValue'
6295 # t[0] = [t[1]]
6297 #def p_ComponentValueList_2 (t):
6298 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
6299 # t[0] = t[1] + [t[3]]
6302 # 25 Notation for sequence-of types -------------------------------------------
6304 # 25.1
6305 def p_SequenceOfType (t):
6306 '''SequenceOfType : SEQUENCE OF Type
6307 | SEQUENCE OF NamedType'''
6308 t[0] = SequenceOfType (val = t[3], size_constr = None)
6311 # 26 Notation for set types ---------------------------------------------------
6313 # 26.1
6314 def p_SetType_1 (t):
6315 'SetType : SET LBRACE RBRACE'
6316 t[0] = SetType (elt_list = [])
6318 def p_SetType_2 (t):
6319 'SetType : SET LBRACE ComponentTypeLists RBRACE'
6320 t[0] = SetType (elt_list = t[3]['elt_list'])
6321 if 'ext_list' in t[3]:
6322 t[0].ext_list = t[3]['ext_list']
6323 if 'elt_list2' in t[3]:
6324 t[0].elt_list2 = t[3]['elt_list2']
6327 # 27 Notation for set-of types ------------------------------------------------
6329 # 27.1
6330 def p_SetOfType (t):
6331 '''SetOfType : SET OF Type
6332 | SET OF NamedType'''
6333 t[0] = SetOfType (val = t[3])
6335 # 28 Notation for choice types ------------------------------------------------
6337 # 28.1
6338 def p_ChoiceType (t):
6339 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE'
6340 if 'ext_list' in t[3]:
6341 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
6342 else:
6343 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
6345 def p_AlternativeTypeLists_1 (t):
6346 'AlternativeTypeLists : AlternativeTypeList'
6347 t[0] = {'elt_list' : t[1]}
6349 def p_AlternativeTypeLists_2 (t):
6350 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker'
6351 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6353 def p_ExtensionAdditionAlternatives_1 (t):
6354 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList'
6355 t[0] = t[1]
6357 def p_ExtensionAdditionAlternatives_2 (t):
6358 'ExtensionAdditionAlternatives : '
6359 t[0] = []
6361 def p_ExtensionAdditionAlternativesList_1 (t):
6362 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative'
6363 t[0] = t[2]
6365 def p_ExtensionAdditionAlternativesList_2 (t):
6366 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative'
6367 t[0] = t[1] + t[3]
6369 def p_ExtensionAdditionAlternative_1 (t):
6370 'ExtensionAdditionAlternative : NamedType'
6371 t[0] = [t[1]]
6373 def p_ExtensionAdditionAlternative_2 (t):
6374 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup'
6375 t[0] = t[1]
6377 def p_ExtensionAdditionAlternativesGroup (t):
6378 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK'
6379 t[0] = t[3]
6381 def p_AlternativeTypeList_1 (t):
6382 'AlternativeTypeList : NamedType'
6383 t[0] = [t[1]]
6385 def p_AlternativeTypeList_2 (t):
6386 'AlternativeTypeList : AlternativeTypeList COMMA NamedType'
6387 t[0] = t[1] + [t[3]]
6389 # 28.10
6390 def p_ChoiceValue_1 (t):
6391 '''ChoiceValue : identifier COLON Value
6392 | identifier COLON NullValue '''
6393 val = t[3]
6394 if not isinstance(val, Value):
6395 val = Value(val=val)
6396 t[0] = ChoiceValue (choice = t[1], val = val)
6398 # 29 Notation for selection types
6400 # 29.1
6401 def p_SelectionType (t): #
6402 'SelectionType : identifier LT Type'
6403 t[0] = SelectionType (typ = t[3], sel = t[1])
6405 # 30 Notation for tagged types ------------------------------------------------
6407 # 30.1
6408 def p_TaggedType_1 (t):
6409 'TaggedType : Tag Type'
6410 t[1].mode = 'default'
6411 t[0] = t[2]
6412 t[0].AddTag(t[1])
6414 def p_TaggedType_2 (t):
6415 '''TaggedType : Tag IMPLICIT Type
6416 | Tag EXPLICIT Type'''
6417 t[1].mode = t[2]
6418 t[0] = t[3]
6419 t[0].AddTag(t[1])
6421 def p_Tag (t):
6422 'Tag : LBRACK Class ClassNumber RBRACK'
6423 t[0] = Tag(cls = t[2], num = t[3])
6425 def p_ClassNumber_1 (t):
6426 'ClassNumber : number'
6427 t[0] = t[1]
6429 def p_ClassNumber_2 (t):
6430 'ClassNumber : DefinedValue'
6431 t[0] = t[1]
6433 def p_Class_1 (t):
6434 '''Class : UNIVERSAL
6435 | APPLICATION
6436 | PRIVATE'''
6437 t[0] = t[1]
6439 def p_Class_2 (t):
6440 'Class :'
6441 t[0] = 'CONTEXT'
6444 # 31 Notation for the object identifier type ----------------------------------
6446 # 31.1
6447 def p_ObjectIdentifierType (t):
6448 'ObjectIdentifierType : OBJECT IDENTIFIER'
6449 t[0] = ObjectIdentifierType()
6451 # 31.3
6452 def p_ObjectIdentifierValue (t):
6453 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6454 t[0] = ObjectIdentifierValue (comp_list=t[2])
6456 def p_oid_comp_list_1 (t):
6457 'oid_comp_list : oid_comp_list ObjIdComponents'
6458 t[0] = t[1] + [t[2]]
6460 def p_oid_comp_list_2 (t):
6461 'oid_comp_list : ObjIdComponents'
6462 t[0] = [t[1]]
6464 def p_ObjIdComponents (t):
6465 '''ObjIdComponents : NameForm
6466 | NumberForm
6467 | NameAndNumberForm'''
6468 t[0] = t[1]
6470 def p_NameForm (t):
6471 '''NameForm : LCASE_IDENT
6472 | LCASE_IDENT_ASSIGNED'''
6473 t [0] = t[1]
6475 def p_NumberForm (t):
6476 '''NumberForm : NUMBER'''
6477 # | DefinedValue'''
6478 t [0] = t[1]
6480 def p_NameAndNumberForm (t):
6481 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6482 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6483 t[0] = Node('name_and_number', ident = t[1], number = t[3])
6485 # 32 Notation for the relative object identifier type -------------------------
6487 # 32.1
6488 def p_RelativeOIDType (t):
6489 'RelativeOIDType : RELATIVE_OID'
6490 t[0] = RelativeOIDType()
6492 # 33 Notation for the embedded-pdv type ---------------------------------------
6494 # 33.1
6495 def p_EmbeddedPDVType (t):
6496 'EmbeddedPDVType : EMBEDDED PDV'
6497 t[0] = EmbeddedPDVType()
6499 # 34 Notation for the external type -------------------------------------------
6501 # 34.1
6502 def p_ExternalType (t):
6503 'ExternalType : EXTERNAL'
6504 t[0] = ExternalType()
6506 # 36 Notation for character string types --------------------------------------
6508 # 36.1
6509 def p_CharacterStringType (t):
6510 '''CharacterStringType : RestrictedCharacterStringType
6511 | UnrestrictedCharacterStringType'''
6512 t[0] = t[1]
6515 # 37 Definition of restricted character string types --------------------------
6517 def p_RestrictedCharacterStringType_1 (t):
6518 'RestrictedCharacterStringType : BMPString'
6519 t[0] = BMPStringType ()
6520 def p_RestrictedCharacterStringType_2 (t):
6521 'RestrictedCharacterStringType : GeneralString'
6522 t[0] = GeneralStringType ()
6523 def p_RestrictedCharacterStringType_3 (t):
6524 'RestrictedCharacterStringType : GraphicString'
6525 t[0] = GraphicStringType ()
6526 def p_RestrictedCharacterStringType_4 (t):
6527 'RestrictedCharacterStringType : IA5String'
6528 t[0] = IA5StringType ()
6529 def p_RestrictedCharacterStringType_5 (t):
6530 'RestrictedCharacterStringType : ISO646String'
6531 t[0] = ISO646StringType ()
6532 def p_RestrictedCharacterStringType_6 (t):
6533 'RestrictedCharacterStringType : NumericString'
6534 t[0] = NumericStringType ()
6535 def p_RestrictedCharacterStringType_7 (t):
6536 'RestrictedCharacterStringType : PrintableString'
6537 t[0] = PrintableStringType ()
6538 def p_RestrictedCharacterStringType_8 (t):
6539 'RestrictedCharacterStringType : TeletexString'
6540 t[0] = TeletexStringType ()
6541 def p_RestrictedCharacterStringType_9 (t):
6542 'RestrictedCharacterStringType : T61String'
6543 t[0] = T61StringType ()
6544 def p_RestrictedCharacterStringType_10 (t):
6545 'RestrictedCharacterStringType : UniversalString'
6546 t[0] = UniversalStringType ()
6547 def p_RestrictedCharacterStringType_11 (t):
6548 'RestrictedCharacterStringType : UTF8String'
6549 t[0] = UTF8StringType ()
6550 def p_RestrictedCharacterStringType_12 (t):
6551 'RestrictedCharacterStringType : VideotexString'
6552 t[0] = VideotexStringType ()
6553 def p_RestrictedCharacterStringType_13 (t):
6554 'RestrictedCharacterStringType : VisibleString'
6555 t[0] = VisibleStringType ()
6558 # 40 Definition of unrestricted character string types ------------------------
6560 # 40.1
6561 def p_UnrestrictedCharacterStringType (t):
6562 'UnrestrictedCharacterStringType : CHARACTER STRING'
6563 t[0] = UnrestrictedCharacterStringType ()
6566 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6568 # 42 Generalized time ---------------------------------------------------------
6570 def p_UsefulType_1 (t):
6571 'UsefulType : GeneralizedTime'
6572 t[0] = GeneralizedTime()
6574 # 43 Universal time -----------------------------------------------------------
6576 def p_UsefulType_2 (t):
6577 'UsefulType : UTCTime'
6578 t[0] = UTCTime()
6580 # 44 The object descriptor type -----------------------------------------------
6582 def p_UsefulType_3 (t):
6583 'UsefulType : ObjectDescriptor'
6584 t[0] = ObjectDescriptor()
6587 # 45 Constrained types --------------------------------------------------------
6589 # 45.1
6590 def p_ConstrainedType_1 (t):
6591 'ConstrainedType : Type Constraint'
6592 t[0] = t[1]
6593 t[0].AddConstraint(t[2])
6595 def p_ConstrainedType_2 (t):
6596 'ConstrainedType : TypeWithConstraint'
6597 t[0] = t[1]
6599 # 45.5
6600 def p_TypeWithConstraint_1 (t):
6601 '''TypeWithConstraint : SET Constraint OF Type
6602 | SET SizeConstraint OF Type'''
6603 t[0] = SetOfType (val = t[4], constr = t[2])
6605 def p_TypeWithConstraint_2 (t):
6606 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6607 | SEQUENCE SizeConstraint OF Type'''
6608 t[0] = SequenceOfType (val = t[4], constr = t[2])
6610 def p_TypeWithConstraint_3 (t):
6611 '''TypeWithConstraint : SET Constraint OF NamedType
6612 | SET SizeConstraint OF NamedType'''
6613 t[0] = SetOfType (val = t[4], constr = t[2])
6615 def p_TypeWithConstraint_4 (t):
6616 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6617 | SEQUENCE SizeConstraint OF NamedType'''
6618 t[0] = SequenceOfType (val = t[4], constr = t[2])
6620 # 45.6
6621 # 45.7
6622 def p_Constraint (t):
6623 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6624 t[0] = t[2]
6626 def p_ConstraintSpec (t):
6627 '''ConstraintSpec : ElementSetSpecs
6628 | GeneralConstraint'''
6629 t[0] = t[1]
6631 # 46 Element set specification ------------------------------------------------
6633 # 46.1
6634 def p_ElementSetSpecs_1 (t):
6635 'ElementSetSpecs : RootElementSetSpec'
6636 t[0] = t[1]
6638 def p_ElementSetSpecs_2 (t):
6639 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6640 t[0] = t[1]
6641 t[0].ext = True
6643 def p_ElementSetSpecs_3 (t):
6644 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6645 t[0] = t[1]
6646 t[0].ext = True
6648 def p_RootElementSetSpec (t):
6649 'RootElementSetSpec : ElementSetSpec'
6650 t[0] = t[1]
6652 def p_AdditionalElementSetSpec (t):
6653 'AdditionalElementSetSpec : ElementSetSpec'
6654 t[0] = t[1]
6656 def p_ElementSetSpec (t):
6657 'ElementSetSpec : Unions'
6658 t[0] = t[1]
6660 def p_Unions_1 (t):
6661 'Unions : Intersections'
6662 t[0] = t[1]
6664 def p_Unions_2 (t):
6665 'Unions : UElems UnionMark Intersections'
6666 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
6668 def p_UElems (t):
6669 'UElems : Unions'
6670 t[0] = t[1]
6672 def p_Intersections_1 (t):
6673 'Intersections : IntersectionElements'
6674 t[0] = t[1]
6676 def p_Intersections_2 (t):
6677 'Intersections : IElems IntersectionMark IntersectionElements'
6678 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
6680 def p_IElems (t):
6681 'IElems : Intersections'
6682 t[0] = t[1]
6684 def p_IntersectionElements (t):
6685 'IntersectionElements : Elements'
6686 t[0] = t[1]
6688 def p_UnionMark (t):
6689 '''UnionMark : BAR
6690 | UNION'''
6692 def p_IntersectionMark (t):
6693 '''IntersectionMark : CIRCUMFLEX
6694 | INTERSECTION'''
6696 # 46.5
6697 def p_Elements_1 (t):
6698 'Elements : SubtypeElements'
6699 t[0] = t[1]
6701 def p_Elements_2 (t):
6702 'Elements : LPAREN ElementSetSpec RPAREN'
6703 t[0] = t[2]
6705 # 47 Subtype elements ---------------------------------------------------------
6707 # 47.1 General
6708 def p_SubtypeElements (t):
6709 '''SubtypeElements : SingleValue
6710 | ContainedSubtype
6711 | ValueRange
6712 | PermittedAlphabet
6713 | SizeConstraint
6714 | TypeConstraint
6715 | InnerTypeConstraints
6716 | PatternConstraint'''
6717 t[0] = t[1]
6719 # 47.2 Single value
6720 # 47.2.1
6721 def p_SingleValue (t):
6722 'SingleValue : Value'
6723 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
6725 # 47.3 Contained subtype
6726 # 47.3.1
6727 def p_ContainedSubtype (t):
6728 'ContainedSubtype : Includes Type'
6729 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
6731 def p_Includes (t):
6732 '''Includes : INCLUDES
6733 | '''
6735 # 47.4 Value range
6736 # 47.4.1
6737 def p_ValueRange (t):
6738 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6739 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
6741 # 47.4.3
6742 def p_LowerEndpoint_1 (t):
6743 'LowerEndpoint : LowerEndValue'
6744 t[0] = t[1]
6746 def p_LowerEndpoint_2 (t):
6747 'LowerEndpoint : LowerEndValue LT'
6748 t[0] = t[1] # but not inclusive range
6750 def p_UpperEndpoint_1 (t):
6751 'UpperEndpoint : UpperEndValue'
6752 t[0] = t[1]
6754 def p_UpperEndpoint_2 (t):
6755 'UpperEndpoint : LT UpperEndValue'
6756 t[0] = t[1] # but not inclusive range
6758 # 47.4.4
6759 def p_LowerEndValue (t):
6760 '''LowerEndValue : Value
6761 | MIN'''
6762 t[0] = t[1] # XXX
6764 def p_UpperEndValue (t):
6765 '''UpperEndValue : Value
6766 | MAX'''
6767 t[0] = t[1]
6769 # 47.5 Size constraint
6770 # 47.5.1
6771 def p_SizeConstraint (t):
6772 'SizeConstraint : SIZE Constraint'
6773 t[0] = Constraint (type = 'Size', subtype = t[2])
6775 # 47.6 Type constraint
6776 # 47.6.1
6777 def p_TypeConstraint (t):
6778 'TypeConstraint : Type'
6779 t[0] = Constraint (type = 'Type', subtype = t[1])
6781 # 47.7 Permitted alphabet
6782 # 47.7.1
6783 def p_PermittedAlphabet (t):
6784 'PermittedAlphabet : FROM Constraint'
6785 t[0] = Constraint (type = 'From', subtype = t[2])
6787 # 47.8 Inner subtyping
6788 # 47.8.1
6789 def p_InnerTypeConstraints (t):
6790 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6791 | WITH COMPONENTS MultipleTypeConstraints'''
6792 pass # ignore PER invisible constraint
6794 # 47.8.3
6795 def p_SingleTypeConstraint (t):
6796 'SingleTypeConstraint : Constraint'
6797 t[0] = t[1]
6799 # 47.8.4
6800 def p_MultipleTypeConstraints (t):
6801 '''MultipleTypeConstraints : FullSpecification
6802 | PartialSpecification'''
6803 t[0] = t[1]
6805 def p_FullSpecification (t):
6806 'FullSpecification : LBRACE TypeConstraints RBRACE'
6807 t[0] = t[2]
6809 def p_PartialSpecification (t):
6810 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6811 t[0] = t[4]
6813 def p_TypeConstraints_1 (t):
6814 'TypeConstraints : named_constraint'
6815 t [0] = [t[1]]
6817 def p_TypeConstraints_2 (t):
6818 'TypeConstraints : TypeConstraints COMMA named_constraint'
6819 t[0] = t[1] + [t[3]]
6821 def p_named_constraint_1 (t):
6822 'named_constraint : identifier constraint'
6823 return Node ('named_constraint', ident = t[1], constr = t[2])
6825 def p_named_constraint_2 (t):
6826 'named_constraint : constraint'
6827 return Node ('named_constraint', constr = t[1])
6829 def p_constraint (t):
6830 'constraint : value_constraint presence_constraint'
6831 t[0] = Node ('constraint', value = t[1], presence = t[2])
6833 def p_value_constraint_1 (t):
6834 'value_constraint : Constraint'
6835 t[0] = t[1]
6837 def p_value_constraint_2 (t):
6838 'value_constraint : '
6839 pass
6841 def p_presence_constraint_1 (t):
6842 '''presence_constraint : PRESENT
6843 | ABSENT
6844 | OPTIONAL'''
6845 t[0] = t[1]
6847 def p_presence_constraint_2 (t):
6848 '''presence_constraint : '''
6849 pass
6851 # 47.9 Pattern constraint
6852 # 47.9.1
6853 def p_PatternConstraint (t):
6854 'PatternConstraint : PATTERN Value'
6855 t[0] = Constraint (type = 'Pattern', subtype = t[2])
6857 # 49 The exception identifier
6859 # 49.4
6860 def p_ExceptionSpec_1 (t):
6861 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
6862 pass
6864 def p_ExceptionSpec_2 (t):
6865 'ExceptionSpec : '
6866 pass
6868 def p_ExceptionIdentification (t):
6869 '''ExceptionIdentification : SignedNumber
6870 | DefinedValue
6871 | Type COLON Value '''
6872 pass
6874 # /*-----------------------------------------------------------------------*/
6875 # /* Value Notation Productions */
6876 # /*-----------------------------------------------------------------------*/
6880 def p_binary_string (t):
6881 'binary_string : BSTRING'
6882 t[0] = BStringValue(val = t[1])
6884 def p_hex_string (t):
6885 'hex_string : HSTRING'
6886 t[0] = HStringValue(val = t[1])
6888 def p_char_string (t):
6889 'char_string : QSTRING'
6890 t[0] = t[1]
6892 def p_number (t):
6893 'number : NUMBER'
6894 t[0] = t[1]
6897 #--- ITU-T Recommendation X.208 -----------------------------------------------
6899 # 27 Notation for the any type ------------------------------------------------
6901 # 27.1
6902 def p_AnyType (t):
6903 '''AnyType : ANY
6904 | ANY DEFINED BY identifier'''
6905 t[0] = AnyType()
6907 #--- ITU-T Recommendation X.681 -----------------------------------------------
6909 # 7 ASN.1 lexical items -------------------------------------------------------
6911 # 7.1 Information object class references
6913 def p_objectclassreference (t):
6914 'objectclassreference : CLASS_IDENT'
6915 t[0] = Class_Ref(val=t[1])
6917 # 7.2 Information object references
6919 def p_objectreference (t):
6920 'objectreference : LCASE_IDENT'
6921 t[0] = t[1]
6923 # 7.3 Information object set references
6925 #def p_objectsetreference (t):
6926 # 'objectsetreference : UCASE_IDENT'
6927 # t[0] = t[1]
6929 # 7.4 Type field references
6930 # ucasefieldreference
6931 # 7.5 Value field references
6932 # lcasefieldreference
6933 # 7.6 Value set field references
6934 # ucasefieldreference
6935 # 7.7 Object field references
6936 # lcasefieldreference
6937 # 7.8 Object set field references
6938 # ucasefieldreference
6940 def p_ucasefieldreference (t):
6941 'ucasefieldreference : AMPERSAND UCASE_IDENT'
6942 t[0] = '&' + t[2]
6944 def p_lcasefieldreference (t):
6945 'lcasefieldreference : AMPERSAND LCASE_IDENT'
6946 t[0] = '&' + t[2]
6948 # 8 Referencing definitions
6950 # 8.1
6951 def p_DefinedObjectClass (t):
6952 '''DefinedObjectClass : objectclassreference
6953 | UsefulObjectClassReference'''
6954 t[0] = t[1]
6955 global obj_class
6956 obj_class = t[0].val
6958 def p_DefinedObject (t):
6959 '''DefinedObject : objectreference'''
6960 t[0] = t[1]
6962 # 8.4
6963 def p_UsefulObjectClassReference (t):
6964 '''UsefulObjectClassReference : TYPE_IDENTIFIER
6965 | ABSTRACT_SYNTAX'''
6966 t[0] = Class_Ref(val=t[1])
6968 # 9 Information object class definition and assignment
6970 # 9.1
6971 def p_ObjectClassAssignment (t):
6972 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
6973 | UCASE_IDENT ASSIGNMENT ObjectClass'''
6974 t[0] = t[3]
6975 t[0].SetName(t[1])
6976 if isinstance(t[0], ObjectClassDefn):
6977 t[0].reg_types()
6979 # 9.2
6980 def p_ObjectClass (t):
6981 '''ObjectClass : DefinedObjectClass
6982 | ObjectClassDefn
6983 | ParameterizedObjectClass '''
6984 t[0] = t[1]
6986 # 9.3
6987 def p_ObjectClassDefn (t):
6988 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
6989 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
6990 t[0] = ObjectClassDefn(fields = t[3])
6992 def p_FieldSpecs_1 (t):
6993 'FieldSpecs : FieldSpec'
6994 t[0] = [t[1]]
6996 def p_FieldSpecs_2 (t):
6997 'FieldSpecs : FieldSpecs COMMA FieldSpec'
6998 t[0] = t[1] + [t[3]]
7000 def p_WithSyntaxSpec (t):
7001 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
7002 t[0] = None
7004 # 9.4
7005 def p_FieldSpec (t):
7006 '''FieldSpec : TypeFieldSpec
7007 | FixedTypeValueFieldSpec
7008 | VariableTypeValueFieldSpec
7009 | FixedTypeValueSetFieldSpec
7010 | ObjectFieldSpec
7011 | ObjectSetFieldSpec '''
7012 t[0] = t[1]
7014 # 9.5
7015 def p_TypeFieldSpec (t):
7016 '''TypeFieldSpec : ucasefieldreference
7017 | ucasefieldreference TypeOptionalitySpec '''
7018 t[0] = TypeFieldSpec()
7019 t[0].SetName(t[1])
7021 def p_TypeOptionalitySpec_1 (t):
7022 'TypeOptionalitySpec ::= OPTIONAL'
7023 pass
7025 def p_TypeOptionalitySpec_2 (t):
7026 'TypeOptionalitySpec ::= DEFAULT Type'
7027 pass
7029 # 9.6
7030 def p_FixedTypeValueFieldSpec (t):
7031 '''FixedTypeValueFieldSpec : lcasefieldreference Type
7032 | lcasefieldreference Type UNIQUE
7033 | lcasefieldreference Type ValueOptionalitySpec
7034 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
7035 t[0] = FixedTypeValueFieldSpec(typ = t[2])
7036 t[0].SetName(t[1])
7038 def p_ValueOptionalitySpec_1 (t):
7039 'ValueOptionalitySpec ::= OPTIONAL'
7040 pass
7042 def p_ValueOptionalitySpec_2 (t):
7043 'ValueOptionalitySpec ::= DEFAULT Value'
7044 pass
7046 # 9.8
7048 def p_VariableTypeValueFieldSpec (t):
7049 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
7050 | lcasefieldreference FieldName ValueOptionalitySpec '''
7051 t[0] = VariableTypeValueFieldSpec()
7052 t[0].SetName(t[1])
7054 # 9.9
7055 def p_FixedTypeValueSetFieldSpec (t):
7056 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
7057 | ucasefieldreference Type ValueSetOptionalitySpec '''
7058 t[0] = FixedTypeValueSetFieldSpec()
7059 t[0].SetName(t[1])
7061 def p_ValueSetOptionalitySpec_1 (t):
7062 'ValueSetOptionalitySpec ::= OPTIONAL'
7063 pass
7065 def p_ValueSetOptionalitySpec_2 (t):
7066 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
7067 pass
7069 # 9.11
7070 def p_ObjectFieldSpec (t):
7071 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
7072 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
7073 t[0] = ObjectFieldSpec(cls=t[2])
7074 t[0].SetName(t[1])
7075 global obj_class
7076 obj_class = None
7078 def p_ObjectOptionalitySpec_1 (t):
7079 'ObjectOptionalitySpec ::= OPTIONAL'
7080 pass
7082 def p_ObjectOptionalitySpec_2 (t):
7083 'ObjectOptionalitySpec ::= DEFAULT Object'
7084 pass
7086 # 9.12
7087 def p_ObjectSetFieldSpec (t):
7088 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
7089 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
7090 t[0] = ObjectSetFieldSpec(cls=t[2])
7091 t[0].SetName(t[1])
7093 def p_ObjectSetOptionalitySpec_1 (t):
7094 'ObjectSetOptionalitySpec ::= OPTIONAL'
7095 pass
7097 def p_ObjectSetOptionalitySpec_2 (t):
7098 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
7099 pass
7101 # 9.13
7102 def p_PrimitiveFieldName (t):
7103 '''PrimitiveFieldName : ucasefieldreference
7104 | lcasefieldreference '''
7105 t[0] = t[1]
7107 # 9.13
7108 def p_FieldName_1 (t):
7109 'FieldName : PrimitiveFieldName'
7110 t[0] = t[1]
7112 def p_FieldName_2 (t):
7113 'FieldName : FieldName DOT PrimitiveFieldName'
7114 t[0] = t[1] + '.' + t[3]
7116 # 11 Information object definition and assignment
7118 # 11.1
7119 def p_ObjectAssignment (t):
7120 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
7121 t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4])
7122 global obj_class
7123 obj_class = None
7125 # 11.3
7126 def p_Object (t):
7127 '''Object : DefinedObject
7128 | ObjectDefn
7129 | ParameterizedObject'''
7130 t[0] = t[1]
7132 # 11.4
7133 def p_ObjectDefn (t):
7134 'ObjectDefn : lbraceobject bodyobject rbraceobject'
7135 t[0] = t[2]
7137 # {...} block of object definition
7138 def p_lbraceobject(t):
7139 'lbraceobject : braceobjectbegin LBRACE'
7140 t[0] = t[1]
7142 def p_braceobjectbegin(t):
7143 'braceobjectbegin : '
7144 global lexer
7145 global obj_class
7146 if set_class_syntax(obj_class):
7147 state = 'INITIAL'
7148 else:
7149 lexer.level = 1
7150 state = 'braceignore'
7151 lexer.push_state(state)
7153 def p_rbraceobject(t):
7154 'rbraceobject : braceobjectend RBRACE'
7155 t[0] = t[2]
7157 def p_braceobjectend(t):
7158 'braceobjectend : '
7159 global lexer
7160 lexer.pop_state()
7161 set_class_syntax(None)
7163 def p_bodyobject_1 (t):
7164 'bodyobject : '
7165 t[0] = { }
7167 def p_bodyobject_2 (t):
7168 'bodyobject : cls_syntax_list'
7169 t[0] = t[1]
7171 def p_cls_syntax_list_1 (t):
7172 'cls_syntax_list : cls_syntax_list cls_syntax'
7173 t[0] = t[1]
7174 t[0].update(t[2])
7176 def p_cls_syntax_list_2 (t):
7177 'cls_syntax_list : cls_syntax'
7178 t[0] = t[1]
7180 # X.681
7181 def p_cls_syntax_1 (t):
7182 'cls_syntax : Type IDENTIFIED BY Value'
7183 t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
7185 def p_cls_syntax_2 (t):
7186 'cls_syntax : HAS PROPERTY Value'
7187 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7189 # X.880
7190 def p_cls_syntax_3 (t):
7191 '''cls_syntax : ERRORS ObjectSet
7192 | LINKED ObjectSet
7193 | RETURN RESULT BooleanValue
7194 | SYNCHRONOUS BooleanValue
7195 | INVOKE PRIORITY Value
7196 | RESULT_PRIORITY Value
7197 | PRIORITY Value
7198 | ALWAYS RESPONDS BooleanValue
7199 | IDEMPOTENT BooleanValue '''
7200 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7202 def p_cls_syntax_4 (t):
7203 '''cls_syntax : ARGUMENT Type
7204 | RESULT Type
7205 | PARAMETER Type '''
7206 t[0] = { get_class_fieled(t[1]) : t[2] }
7208 def p_cls_syntax_5 (t):
7209 'cls_syntax : CODE Value'
7210 fld = get_class_fieled(t[1]);
7211 t[0] = { fld : t[2] }
7212 if isinstance(t[2], ChoiceValue):
7213 fldt = fld + '.' + t[2].choice
7214 t[0][fldt] = t[2]
7216 def p_cls_syntax_6 (t):
7217 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
7218 | RESULT Type OPTIONAL BooleanValue
7219 | PARAMETER Type OPTIONAL BooleanValue '''
7220 t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
7222 # 12 Information object set definition and assignment
7224 # 12.1
7225 def p_ObjectSetAssignment (t):
7226 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
7227 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
7229 # 12.3
7230 def p_ObjectSet (t):
7231 'ObjectSet : lbraceignore rbraceignore'
7232 t[0] = None
7234 # 14 Notation for the object class field type ---------------------------------
7236 # 14.1
7237 def p_ObjectClassFieldType (t):
7238 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
7239 t[0] = get_type_from_class(t[1], t[3])
7241 # 14.6
7242 def p_ObjectClassFieldValue (t):
7243 '''ObjectClassFieldValue : OpenTypeFieldVal'''
7244 t[0] = t[1]
7246 def p_OpenTypeFieldVal (t):
7247 '''OpenTypeFieldVal : Type COLON Value
7248 | NullType COLON NullValue'''
7249 t[0] = t[3]
7252 # 15 Information from objects -------------------------------------------------
7254 # 15.1
7256 def p_ValueFromObject (t):
7257 'ValueFromObject : LCASE_IDENT DOT FieldName'
7258 t[0] = t[1] + '.' + t[3]
7261 # Annex C - The instance-of type ----------------------------------------------
7263 # C.2
7264 def p_InstanceOfType (t):
7265 'InstanceOfType : INSTANCE OF DefinedObjectClass'
7266 t[0] = InstanceOfType()
7269 # --- tables ---
7271 useful_object_class_types = {
7272 # Annex A
7273 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
7274 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
7275 # Annex B
7276 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
7277 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
7278 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
7281 object_class_types = { }
7283 object_class_typerefs = { }
7285 object_class_classrefs = { }
7287 # dummy types
7288 class _VariableTypeValueFieldSpec (AnyType):
7289 pass
7291 class _FixedTypeValueSetFieldSpec (AnyType):
7292 pass
7294 class_types_creator = {
7295 'BooleanType' : lambda : BooleanType(),
7296 'IntegerType' : lambda : IntegerType(),
7297 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
7298 'OpenType' : lambda : OpenType(),
7299 # dummy types
7300 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
7301 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
7304 class_names = { }
7306 x681_syntaxes = {
7307 'TYPE-IDENTIFIER' : {
7308 ' ' : '&Type',
7309 'IDENTIFIED' : 'IDENTIFIED',
7310 #'BY' : 'BY',
7311 'IDENTIFIED BY' : '&id',
7313 'ABSTRACT-SYNTAX' : {
7314 ' ' : '&Type',
7315 'IDENTIFIED' : 'IDENTIFIED',
7316 #'BY' : 'BY',
7317 'IDENTIFIED BY' : '&id',
7318 'HAS' : 'HAS',
7319 'PROPERTY' : 'PROPERTY',
7320 'HAS PROPERTY' : '&property',
7324 class_syntaxes_enabled = {
7325 'TYPE-IDENTIFIER' : True,
7326 'ABSTRACT-SYNTAX' : True,
7329 class_syntaxes = {
7330 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
7331 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
7334 class_current_syntax = None
7336 def get_syntax_tokens(syntaxes):
7337 tokens = { }
7338 for s in (syntaxes):
7339 for k in (list(syntaxes[s].keys())):
7340 if k.find(' ') < 0:
7341 tokens[k] = k
7342 tokens[k] = tokens[k].replace('-', '_')
7343 return list(tokens.values())
7345 tokens = tokens + get_syntax_tokens(x681_syntaxes)
7347 def set_class_syntax(syntax):
7348 global class_syntaxes_enabled
7349 global class_current_syntax
7350 #print "set_class_syntax", syntax, class_current_syntax
7351 if class_syntaxes_enabled.get(syntax, False):
7352 class_current_syntax = syntax
7353 return True
7354 else:
7355 class_current_syntax = None
7356 return False
7358 def is_class_syntax(name):
7359 global class_syntaxes
7360 global class_current_syntax
7361 #print "is_class_syntax", name, class_current_syntax
7362 if not class_current_syntax:
7363 return False
7364 return name in class_syntaxes[class_current_syntax]
7366 def get_class_fieled(name):
7367 if not class_current_syntax:
7368 return None
7369 return class_syntaxes[class_current_syntax][name]
7371 def is_class_ident(name):
7372 return name in class_names
7374 def add_class_ident(name):
7375 #print "add_class_ident", name
7376 class_names[name] = name
7378 def get_type_from_class(cls, fld):
7379 flds = fld.split('.')
7380 if (isinstance(cls, Class_Ref)):
7381 key = cls.val + '.' + flds[0]
7382 else:
7383 key = cls + '.' + flds[0]
7385 if key in object_class_classrefs:
7386 return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:]))
7388 if key in object_class_typerefs:
7389 return Type_Ref(val=object_class_typerefs[key])
7391 creator = lambda : AnyType()
7392 creator = useful_object_class_types.get(key, creator)
7393 creator = object_class_types.get(key, creator)
7394 return creator()
7396 def set_type_to_class(cls, fld, pars):
7397 #print "set_type_to_class", cls, fld, pars
7398 key = cls + '.' + fld
7399 typename = 'OpenType'
7400 if (len(pars) > 0):
7401 typename = pars[0]
7402 else:
7403 pars.append(typename)
7404 typeref = None
7405 if (len(pars) > 1):
7406 if (isinstance(pars[1], Class_Ref)):
7407 pars[1] = pars[1].val
7408 typeref = pars[1]
7410 msg = None
7411 if key in object_class_types:
7412 msg = object_class_types[key]().type
7413 if key in object_class_typerefs:
7414 msg = "TypeReference " + object_class_typerefs[key]
7415 if key in object_class_classrefs:
7416 msg = "ClassReference " + object_class_classrefs[key]
7418 if msg == ' '.join(pars):
7419 msg = None
7421 if msg:
7422 msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars))
7423 msg1 = "Already defined as '%s'" % (msg)
7424 raise CompError(msg0 + msg1)
7426 if (typename == 'ClassReference'):
7427 if not typeref: return False
7428 object_class_classrefs[key] = typeref
7429 return True
7431 if (typename == 'TypeReference'):
7432 if not typeref: return False
7433 object_class_typerefs[key] = typeref
7434 return True
7436 creator = class_types_creator.get(typename)
7437 if creator:
7438 object_class_types[key] = creator
7439 return True
7440 else:
7441 return False
7443 def import_class_from_module(mod, cls):
7444 add_class_ident(cls)
7445 mcls = "$%s$%s" % (mod, cls)
7446 for k in list(object_class_classrefs.keys()):
7447 kk = k.split('.', 1)
7448 if kk[0] == mcls:
7449 object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k]
7450 for k in list(object_class_typerefs.keys()):
7451 kk = k.split('.', 1)
7452 if kk[0] == mcls:
7453 object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k]
7454 for k in list(object_class_types.keys()):
7455 kk = k.split('.', 1)
7456 if kk[0] == mcls:
7457 object_class_types[cls + '.' + kk[0]] = object_class_types[k]
7459 #--- ITU-T Recommendation X.682 -----------------------------------------------
7461 # 8 General constraint specification ------------------------------------------
7463 # 8.1
7464 def p_GeneralConstraint (t):
7465 '''GeneralConstraint : UserDefinedConstraint
7466 | TableConstraint
7467 | ContentsConstraint'''
7468 t[0] = t[1]
7470 # 9 User-defined constraints --------------------------------------------------
7472 # 9.1
7473 def p_UserDefinedConstraint (t):
7474 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7475 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
7477 def p_UserDefinedConstraintParameterList_1 (t):
7478 'UserDefinedConstraintParameterList : '
7479 t[0] = []
7481 def p_UserDefinedConstraintParameterList_2 (t):
7482 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7483 t[0] = [t[1]]
7485 def p_UserDefinedConstraintParameterList_3 (t):
7486 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7487 t[0] = t[1] + [t[3]]
7489 # 9.3
7490 def p_UserDefinedConstraintParameter (t):
7491 'UserDefinedConstraintParameter : Type'
7492 t[0] = t[1]
7494 # 10 Table constraints, including component relation constraints --------------
7496 # 10.3
7497 def p_TableConstraint (t):
7498 '''TableConstraint : SimpleTableConstraint
7499 | ComponentRelationConstraint'''
7500 t[0] = Constraint(type = 'Table', subtype = t[1])
7502 def p_SimpleTableConstraint (t):
7503 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7504 t[0] = t[2]
7506 # 10.7
7507 def p_ComponentRelationConstraint (t):
7508 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7509 t[0] = t[2] + str(t[5])
7511 def p_AtNotations_1 (t):
7512 'AtNotations : AtNotation'
7513 t[0] = [t[1]]
7515 def p_AtNotations_2 (t):
7516 'AtNotations : AtNotations COMMA AtNotation'
7517 t[0] = t[1] + [t[3]]
7519 def p_AtNotation_1 (t):
7520 'AtNotation : AT ComponentIdList'
7521 t[0] = '@' + t[2]
7523 def p_AtNotation_2 (t):
7524 'AtNotation : AT DOT Level ComponentIdList'
7525 t[0] = '@.' + t[3] + t[4]
7527 def p_Level_1 (t):
7528 'Level : DOT Level'
7529 t[0] = '.' + t[2]
7531 def p_Level_2 (t):
7532 'Level : '
7533 t[0] = ''
7535 def p_ComponentIdList_1 (t):
7536 'ComponentIdList : LCASE_IDENT'
7537 t[0] = t[1]
7539 def p_ComponentIdList_2 (t):
7540 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7541 t[0] = t[1] + '.' + t[3]
7543 # 11 Contents constraints -----------------------------------------------------
7545 # 11.1
7546 def p_ContentsConstraint (t):
7547 'ContentsConstraint : CONTAINING type_ref'
7548 t[0] = Constraint(type = 'Contents', subtype = t[2])
7551 #--- ITU-T Recommendation X.683 -----------------------------------------------
7553 # 8 Parameterized assignments -------------------------------------------------
7555 # 8.1
7556 def p_ParameterizedAssignment (t):
7557 '''ParameterizedAssignment : ParameterizedTypeAssignment
7558 | ParameterizedObjectClassAssignment
7559 | ParameterizedObjectAssignment
7560 | ParameterizedObjectSetAssignment'''
7561 t[0] = t[1]
7563 # 8.2
7564 def p_ParameterizedTypeAssignment (t):
7565 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7566 t[0] = t[4]
7567 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
7569 def p_ParameterizedObjectClassAssignment (t):
7570 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7571 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7572 t[0] = t[4]
7573 t[0].SetName(t[1])
7574 if isinstance(t[0], ObjectClassDefn):
7575 t[0].reg_types()
7577 def p_ParameterizedObjectAssignment (t):
7578 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7579 t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
7580 global obj_class
7581 obj_class = None
7583 def p_ParameterizedObjectSetAssignment (t):
7584 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7585 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
7587 # 8.3
7588 def p_ParameterList (t):
7589 'ParameterList : lbraceignore rbraceignore'
7591 #def p_ParameterList (t):
7592 # 'ParameterList : LBRACE Parameters RBRACE'
7593 # t[0] = t[2]
7595 #def p_Parameters_1 (t):
7596 # 'Parameters : Parameter'
7597 # t[0] = [t[1]]
7599 #def p_Parameters_2 (t):
7600 # 'Parameters : Parameters COMMA Parameter'
7601 # t[0] = t[1] + [t[3]]
7603 #def p_Parameter_1 (t):
7604 # 'Parameter : Type COLON Reference'
7605 # t[0] = [t[1], t[3]]
7607 #def p_Parameter_2 (t):
7608 # 'Parameter : Reference'
7609 # t[0] = t[1]
7612 # 9 Referencing parameterized definitions -------------------------------------
7614 # 9.1
7615 def p_ParameterizedReference (t):
7616 'ParameterizedReference : Reference LBRACE RBRACE'
7617 t[0] = t[1]
7618 #t[0].val += 'xxx'
7620 # 9.2
7621 def p_ParameterizedType (t):
7622 'ParameterizedType : type_ref ActualParameterList'
7623 t[0] = t[1]
7624 #t[0].val += 'xxx'
7627 def p_ParameterizedObjectClass (t):
7628 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7629 t[0] = t[1]
7630 #t[0].val += 'xxx'
7632 def p_ParameterizedObject (t):
7633 'ParameterizedObject : DefinedObject ActualParameterList'
7634 t[0] = t[1]
7635 #t[0].val += 'xxx'
7637 # 9.5
7638 def p_ActualParameterList (t):
7639 'ActualParameterList : lbraceignore rbraceignore'
7641 #def p_ActualParameterList (t):
7642 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7643 # t[0] = t[2]
7645 #def p_ActualParameters_1 (t):
7646 # 'ActualParameters : ActualParameter'
7647 # t[0] = [t[1]]
7649 #def p_ActualParameters_2 (t):
7650 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7651 # t[0] = t[1] + [t[3]]
7653 #def p_ActualParameter (t):
7654 # '''ActualParameter : Type
7655 # | Value'''
7656 # t[0] = t[1]
7659 #--- ITU-T Recommendation X.880 -----------------------------------------------
7661 x880_classes = {
7662 'OPERATION' : {
7663 '&ArgumentType' : [],
7664 '&argumentTypeOptional' : [ 'BooleanType' ],
7665 '&returnResult' : [ 'BooleanType' ],
7666 '&ResultType' : [],
7667 '&resultTypeOptional' : [ 'BooleanType' ],
7668 '&Errors' : [ 'ClassReference', 'ERROR' ],
7669 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7670 '&synchronous' : [ 'BooleanType' ],
7671 '&idempotent' : [ 'BooleanType' ],
7672 '&alwaysReturns' : [ 'BooleanType' ],
7673 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7674 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7675 '&operationCode' : [ 'TypeReference', 'Code' ],
7677 'ERROR' : {
7678 '&ParameterType' : [],
7679 '&parameterTypeOptional' : [ 'BooleanType' ],
7680 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7681 '&errorCode' : [ 'TypeReference', 'Code' ],
7683 'OPERATION-PACKAGE' : {
7684 '&Both' : [ 'ClassReference', 'OPERATION' ],
7685 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7686 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7687 '&id' : [ 'ObjectIdentifierType' ],
7689 'CONNECTION-PACKAGE' : {
7690 '&bind' : [ 'ClassReference', 'OPERATION' ],
7691 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7692 '&responderCanUnbind' : [ 'BooleanType' ],
7693 '&unbindCanFail' : [ 'BooleanType' ],
7694 '&id' : [ 'ObjectIdentifierType' ],
7696 'CONTRACT' : {
7697 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7698 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7699 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7700 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7701 '&id' : [ 'ObjectIdentifierType' ],
7703 'ROS-OBJECT-CLASS' : {
7704 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7705 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7706 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7707 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7708 '&id' : [ 'ObjectIdentifierType' ],
7712 x880_syntaxes = {
7713 'OPERATION' : {
7714 'ARGUMENT' : '&ArgumentType',
7715 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7716 'RESULT' : '&ResultType',
7717 'RESULT OPTIONAL' : '&resultTypeOptional',
7718 'RETURN' : 'RETURN',
7719 'RETURN RESULT' : '&returnResult',
7720 'ERRORS' : '&Errors',
7721 'LINKED' : '&Linked',
7722 'SYNCHRONOUS' : '&synchronous',
7723 'IDEMPOTENT' : '&idempotent',
7724 'ALWAYS' : 'ALWAYS',
7725 'RESPONDS' : 'RESPONDS',
7726 'ALWAYS RESPONDS' : '&alwaysReturns',
7727 'INVOKE' : 'INVOKE',
7728 'PRIORITY' : 'PRIORITY',
7729 'INVOKE PRIORITY' : '&InvokePriority',
7730 'RESULT-PRIORITY': '&ResultPriority',
7731 'CODE' : '&operationCode',
7733 'ERROR' : {
7734 'PARAMETER' : '&ParameterType',
7735 'PARAMETER OPTIONAL' : '&parameterTypeOptional',
7736 'PRIORITY' : '&ErrorPriority',
7737 'CODE' : '&errorCode',
7739 # 'OPERATION-PACKAGE' : {
7740 # },
7741 # 'CONNECTION-PACKAGE' : {
7742 # },
7743 # 'CONTRACT' : {
7744 # },
7745 # 'ROS-OBJECT-CLASS' : {
7746 # },
7749 def x880_module_begin():
7750 #print "x880_module_begin()"
7751 for name in list(x880_classes.keys()):
7752 add_class_ident(name)
7754 def x880_import(name):
7755 if name in x880_syntaxes:
7756 class_syntaxes_enabled[name] = True
7757 class_syntaxes[name] = x880_syntaxes[name]
7758 if name in x880_classes:
7759 add_class_ident(name)
7760 for f in (list(x880_classes[name].keys())):
7761 set_type_to_class(name, f, x880_classes[name][f])
7763 tokens = tokens + get_syntax_tokens(x880_syntaxes)
7765 # {...} OID value
7766 #def p_lbrace_oid(t):
7767 # 'lbrace_oid : brace_oid_begin LBRACE'
7768 # t[0] = t[1]
7770 #def p_brace_oid_begin(t):
7771 # 'brace_oid_begin : '
7772 # global in_oid
7773 # in_oid = True
7775 #def p_rbrace_oid(t):
7776 # 'rbrace_oid : brace_oid_end RBRACE'
7777 # t[0] = t[2]
7779 #def p_brace_oid_end(t):
7780 # 'brace_oid_end : '
7781 # global in_oid
7782 # in_oid = False
7784 # {...} block to be ignored
7785 def p_lbraceignore(t):
7786 'lbraceignore : braceignorebegin LBRACE'
7787 t[0] = t[1]
7789 def p_braceignorebegin(t):
7790 'braceignorebegin : '
7791 global lexer
7792 lexer.level = 1
7793 lexer.push_state('braceignore')
7795 def p_rbraceignore(t):
7796 'rbraceignore : braceignoreend RBRACE'
7797 t[0] = t[2]
7799 def p_braceignoreend(t):
7800 'braceignoreend : '
7801 global lexer
7802 lexer.pop_state()
7804 def p_error(t):
7805 global input_file
7806 raise ParseError(t, input_file)
7808 def p_pyquote (t):
7809 '''pyquote : PYQUOTE'''
7810 t[0] = PyQuote (val = t[1])
7813 def testlex (s):
7814 lexer.input (s)
7815 while True:
7816 token = lexer.token ()
7817 if not token:
7818 break
7819 print(token)
7822 def do_module (ast, defined_dict):
7823 assert (ast.type == 'Module')
7824 ctx = Ctx (defined_dict)
7825 print(ast.to_python (ctx))
7826 print(ctx.output_assignments ())
7827 print(ctx.output_pyquotes ())
7829 def eth_do_module (ast, ectx):
7830 assert (ast.type == 'Module')
7831 if ectx.dbg('s'): print(ast.str_depth(0))
7832 ast.to_eth(ectx)
7834 def testyacc(s, fn, defined_dict):
7835 ast = yacc.parse(s, debug=0)
7836 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
7837 print("""#!/usr/bin/env python
7838 # Auto-generated from %s at %s
7839 from PyZ3950 import asn1""" % (fn, time_str))
7840 for module in ast:
7841 eth_do_module (module, defined_dict)
7844 # Wireshark compiler
7845 def eth_usage():
7846 print("""
7847 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
7848 -h|? : Usage
7849 -b : BER (default is PER)
7850 -u : Unaligned (default is aligned)
7851 -p proto : Protocol name (implies -S). Default is module-name
7852 from input_file (renamed by #.MODULE if present)
7853 -o name : Output files name core (default is <proto>)
7854 -O dir : Output directory for dissector
7855 -c cnf_file : Conformance file
7856 -I path : Path for conformance file includes
7857 -e : Create conformance file for exported types
7858 -E : Just create conformance file for exported types
7859 -S : Single output for multiple modules
7860 -s template : Single file output (template is input file
7861 without .c/.h extension)
7862 -k : Keep intermediate files though single file output is used
7863 -L : Suppress #line directive from .cnf file
7864 -D dir : Directory for input_file(s) (default: '.')
7865 -C : Add check for SIZE constraints
7866 -r prefix : Remove the prefix from type names
7868 input_file(s) : Input ASN.1 file(s)
7870 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
7871 l - lex
7872 y - yacc
7873 p - parsing
7874 s - internal ASN.1 structure
7875 a - list of assignments
7876 t - tables
7877 c - conformance values
7878 m - list of compiled modules with dependency
7879 o - list of output files
7880 """)
7882 def eth_main():
7883 global input_file
7884 global g_conform
7885 global lexer
7886 print("ASN.1 to Wireshark dissector compiler");
7887 try:
7888 opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLCr:");
7889 except getopt.GetoptError:
7890 eth_usage(); sys.exit(2)
7891 if len(args) < 1:
7892 eth_usage(); sys.exit(2)
7894 conform = EthCnf()
7895 conf_to_read = None
7896 output = EthOut()
7897 ectx = EthCtx(conform, output)
7898 ectx.encoding = 'per'
7899 ectx.proto_opt = None
7900 ectx.fld_opt = {}
7901 ectx.tag_opt = False
7902 ectx.outnm_opt = None
7903 ectx.aligned = True
7904 ectx.dbgopt = ''
7905 ectx.new = True
7906 ectx.expcnf = False
7907 ectx.justexpcnf = False
7908 ectx.merge_modules = False
7909 ectx.group_by_prot = False
7910 ectx.conform.last_group = 0
7911 ectx.conform.suppress_line = False;
7912 ectx.output.outnm = None
7913 ectx.output.single_file = None
7914 ectx.constraints_check = False;
7915 for o, a in opts:
7916 if o in ("-h", "-?"):
7917 eth_usage(); sys.exit(2)
7918 if o in ("-c",):
7919 conf_to_read = a
7920 if o in ("-I",):
7921 ectx.conform.include_path.append(a)
7922 if o in ("-E",):
7923 ectx.expcnf = True
7924 ectx.justexpcnf = True
7925 if o in ("-D",):
7926 ectx.srcdir = a
7927 if o in ("-C",):
7928 ectx.constraints_check = True
7929 if o in ("-X",):
7930 warnings.warn("Command line option -X is obsolete and can be removed")
7931 if o in ("-T",):
7932 warnings.warn("Command line option -T is obsolete and can be removed")
7934 if conf_to_read:
7935 ectx.conform.read(conf_to_read)
7937 for o, a in opts:
7938 if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-X", "-T"):
7939 pass # already processed
7940 else:
7941 par = []
7942 if a: par.append(a)
7943 ectx.conform.set_opt(o, par, "commandline", 0)
7945 (ld, yd, pd) = (0, 0, 0);
7946 if ectx.dbg('l'): ld = 1
7947 if ectx.dbg('y'): yd = 1
7948 if ectx.dbg('p'): pd = 2
7949 lexer = lex.lex(debug=ld)
7950 yacc.yacc(method='LALR', debug=yd)
7951 g_conform = ectx.conform
7952 ast = []
7953 for fn in args:
7954 input_file = fn
7955 lexer.lineno = 1
7956 if (ectx.srcdir): fn = ectx.srcdir + '/' + fn
7957 f = open (fn, "r")
7958 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
7959 f.close ()
7960 ectx.eth_clean()
7961 if (ectx.merge_modules): # common output for all module
7962 ectx.eth_clean()
7963 for module in ast:
7964 eth_do_module(module, ectx)
7965 ectx.eth_prepare()
7966 ectx.eth_do_output()
7967 elif (ectx.groups()): # group by protocols/group
7968 groups = []
7969 pr2gr = {}
7970 if (ectx.group_by_prot): # group by protocols
7971 for module in ast:
7972 prot = module.get_proto(ectx)
7973 if prot not in pr2gr:
7974 pr2gr[prot] = len(groups)
7975 groups.append([])
7976 groups[pr2gr[prot]].append(module)
7977 else: # group by groups
7978 pass
7979 for gm in (groups):
7980 ectx.eth_clean()
7981 for module in gm:
7982 eth_do_module(module, ectx)
7983 ectx.eth_prepare()
7984 ectx.eth_do_output()
7985 else: # output for each module
7986 for module in ast:
7987 ectx.eth_clean()
7988 eth_do_module(module, ectx)
7989 ectx.eth_prepare()
7990 ectx.eth_do_output()
7992 if ectx.dbg('m'):
7993 ectx.dbg_modules()
7995 if ectx.dbg('c'):
7996 ectx.conform.dbg_print()
7997 if not ectx.justexpcnf:
7998 ectx.conform.unused_report()
8000 if ectx.dbg('o'):
8001 ectx.output.dbg_print()
8002 ectx.output.make_single_file()
8005 # Python compiler
8006 def main():
8007 testfn = testyacc
8008 if len (sys.argv) == 1:
8009 while True:
8010 s = input ('Query: ')
8011 if len (s) == 0:
8012 break
8013 testfn (s, 'console', {})
8014 else:
8015 defined_dict = {}
8016 for fn in sys.argv [1:]:
8017 f = open (fn, "r")
8018 testfn (f.read (), fn, defined_dict)
8019 f.close ()
8020 lexer.lineno = 1
8023 #--- BODY ---------------------------------------------------------------------
8025 if __name__ == '__main__':
8026 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
8027 eth_main()
8028 else:
8029 main()
8031 #------------------------------------------------------------------------------
8033 # Editor modelines - http://www.wireshark.org/tools/modelines.html
8035 # c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil
8036 # vi: set shiftwidth=4 tabstop=8 expandtab:
8037 # :indentSize=4:tabSize=8:noTabs=true: