5 # ASN.1 to Wireshark dissector compiler
6 # Copyright 2004 Tomas Kukosa
8 # Permission is hereby granted, free of charge, to any person obtaining a
9 # copy of this software and associated documentation files (the
10 # "Software"), to deal in the Software without restriction, including
11 # without limitation the rights to use, copy, modify, merge, publish,
12 # distribute, and/or sell copies of the Software, and to permit persons
13 # to whom the Software is furnished to do so, provided that the above
14 # copyright notice(s) and this permission notice appear in all copies of
15 # the Software and that both the above copyright notice(s) and this
16 # permission notice appear in supporting documentation.
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
21 # OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 # HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
23 # INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
24 # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
25 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
26 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 # Except as contained in this notice, the name of a copyright holder
29 # shall not be used in advertising or otherwise to promote the sale, use
30 # or other dealings in this Software without prior written authorization
31 # of the copyright holder.
34 """ASN.1 to Wireshark dissector compiler"""
37 # Compiler from ASN.1 specification to the Wireshark dissector
39 # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license
40 # http://www.pobox.com/~asl2/software/PyZ3950/
41 # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
43 # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
44 # http://www.dabeaz.com/ply/
47 # ITU-T Recommendation X.680 (07/2002),
48 # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
50 # ITU-T Recommendation X.681 (07/2002),
51 # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
53 # ITU-T Recommendation X.682 (07/2002),
54 # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
56 # ITU-T Recommendation X.683 (07/2002),
57 # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
59 # ITU-T Recommendation X.880 (07/1994),
60 # Information technology - Remote Operations: Concepts, model and notation
76 if sys.version_info[0] < 3:
77 from string import maketrans
80 # OID name -> number conversion table
86 '0/recommendation' : 0,
115 '0/administration' : 2,
116 '0/network-operator' : 3,
117 '0/identified-organization' : 4,
118 '0/r-recommendation' : 5,
122 '1/registration-authority' : 1,
124 '1/identified-organization' : 3,
125 '/joint-iso-itu-t' : 2,
126 '/joint-iso-ccitt' : 2,
127 '2/presentation' : 0,
129 '2/association-control' : 2,
130 '2/reliable-transfer' : 3,
131 '2/remote-operations' : 4,
139 '2/osi-management' : 9,
140 '2/transaction-processing' : 10,
142 '2/distinguished-object-reference' : 11,
143 '2/reference-data-transfe' : 12,
144 '2/network-layer' : 13,
145 '2/network-layer-management' : 13,
146 '2/transport-layer' : 14,
147 '2/transport-layer-management' : 14,
148 '2/datalink-layer' : 15,
149 '2/datalink-layer-managemen' : 15,
150 '2/datalink-layer-management-information' : 15,
152 '2/registration-procedures' : 17,
153 '2/registration-procedure' : 17,
154 '2/physical-layer' : 18,
155 '2/physical-layer-management' : 18,
158 '2/generic-upper-layers-security' : 20,
160 '2/transport-layer-security-protocol' : 21,
161 '2/network-layer-security-protocol' : 22,
162 '2/international-organizations' : 23,
163 '2/internationalRA' : 23,
170 ITEM_FIELD_NAME = '_item'
171 UNTAG_TYPE_NAME = '_untag'
174 return id.replace('-', '_').replace('.', '_').replace('&', '_')
181 class LexError(Exception):
182 def __init__(self, tok, filename=None):
184 self.filename = filename
185 self.msg = "Unexpected character %r" % (self.tok.value[0])
186 Exception.__init__(self, self.msg)
188 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
192 class ParseError(Exception):
193 def __init__(self, tok, filename=None):
195 self.filename = filename
196 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
197 Exception.__init__(self, self.msg)
199 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
203 class DuplicateError(Exception):
204 def __init__(self, type, ident):
207 self.msg = "Duplicate %s for %s" % (self.type, self.ident)
208 Exception.__init__(self, self.msg)
213 class CompError(Exception):
214 def __init__(self, msg):
216 Exception.__init__(self, self.msg)
223 ('braceignore','exclusive'),
227 ('left', 'UNION', 'BAR'),
228 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
230 # 11 ASN.1 lexical items
233 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
234 r'\.\.' : 'RANGE', # 11.17 Range separator
235 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
236 r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
237 r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
238 # 11.26 Single character lexical items
253 #r"'" : 'APOSTROPHE',
256 r'\!' : 'EXCLAMATION',
257 r'\^' : 'CIRCUMFLEX',
262 # 11.27 Reserved words
264 # all keys in reserved_words must start w/ upper case
267 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
269 'APPLICATION' : 'APPLICATION',
270 'AUTOMATIC' : 'AUTOMATIC',
273 'BOOLEAN' : 'BOOLEAN',
275 'CHARACTER' : 'CHARACTER',
278 'COMPONENT' : 'COMPONENT',
279 'COMPONENTS' : 'COMPONENTS',
280 'CONSTRAINED' : 'CONSTRAINED',
281 'CONTAINING' : 'CONTAINING',
282 'DEFAULT' : 'DEFAULT',
283 'DEFINITIONS' : 'DEFINITIONS',
284 'EMBEDDED' : 'EMBEDDED',
285 # 'ENCODED' : 'ENCODED',
287 'ENUMERATED' : 'ENUMERATED',
288 # 'EXCEPT' : 'EXCEPT',
289 'EXPLICIT' : 'EXPLICIT',
290 'EXPORTS' : 'EXPORTS',
291 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
292 'EXTERNAL' : 'EXTERNAL',
295 'GeneralizedTime' : 'GeneralizedTime',
296 'IDENTIFIER' : 'IDENTIFIER',
297 'IMPLICIT' : 'IMPLICIT',
298 # 'IMPLIED' : 'IMPLIED',
299 'IMPORTS' : 'IMPORTS',
300 'INCLUDES' : 'INCLUDES',
301 'INSTANCE' : 'INSTANCE',
302 'INTEGER' : 'INTEGER',
303 'INTERSECTION' : 'INTERSECTION',
306 'MINUS-INFINITY' : 'MINUS_INFINITY',
309 'ObjectDescriptor' : 'ObjectDescriptor',
312 'OPTIONAL' : 'OPTIONAL',
313 'PATTERN' : 'PATTERN',
315 'PLUS-INFINITY' : 'PLUS_INFINITY',
316 'PRESENT' : 'PRESENT',
317 'PRIVATE' : 'PRIVATE',
319 'RELATIVE-OID' : 'RELATIVE_OID',
320 'SEQUENCE' : 'SEQUENCE',
327 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
330 'UNIVERSAL' : 'UNIVERSAL',
331 'UTCTime' : 'UTCTime',
333 # X.208 obsolete but still used
335 'DEFINED' : 'DEFINED',
338 for k in list(static_tokens.keys()):
339 if static_tokens [k] == None:
340 static_tokens [k] = k
342 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
343 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
346 for s in StringTypes:
347 reserved_words[s + 'String'] = s + 'String'
349 tokens = list(static_tokens.values()) \
350 + list(reserved_words.values()) \
351 + ['BSTRING', 'HSTRING', 'QSTRING',
352 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
353 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
356 cur_mod = __import__ (__name__) # XXX blech!
358 for (k, v) in list(static_tokens.items ()):
359 cur_mod.__dict__['t_' + v] = k
361 # 11.10 Binary strings
366 # 11.12 Hexadecimal strings
375 def t_UCASE_IDENT (t):
376 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
377 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
378 if (is_class_syntax(t.value)): t.type = t.value
379 t.type = reserved_words.get(t.value, t.type)
382 lcase_ident_assigned = {}
383 def t_LCASE_IDENT (t):
384 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
385 if (not in_oid and (t.value in lcase_ident_assigned)): t.type = 'LCASE_IDENT_ASSIGNED'
389 def t_REAL_NUMBER (t):
390 r"[0-9]+\.[0-9]*(?!\.)"
399 pyquote_str = 'PYQUOTE'
401 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
402 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
403 if t.value[2:2+len (pyquote_str)] == pyquote_str:
404 t.value = t.value[2+len(pyquote_str):]
405 t.value = t.value.lstrip ()
414 t.lexer.lineno += t.value.count("\n")
418 raise LexError(t, input_file)
420 # state 'braceignore'
422 def t_braceignore_lbrace(t):
426 def t_braceignore_rbrace(t):
429 # If closing brace, return token
430 if t.lexer.level == 0:
434 def t_braceignore_QSTRING (t):
436 t.lexer.lineno += t.value.count("\n")
438 def t_braceignore_COMMENT(t):
439 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
440 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
442 def t_braceignore_nonspace(t):
443 r'[^\s\{\}\"-]+|-(?!-)'
445 t_braceignore_ignore = " \t\r"
447 def t_braceignore_NEWLINE(t):
449 t.lexer.lineno += t.value.count("\n")
451 def t_braceignore_error(t):
455 def __init__ (self, defined_dict, indent = 0):
456 self.tags_def = 'EXPLICIT' # default = explicit
458 self.assignments = {}
459 self.dependencies = {}
461 self.defined_dict = defined_dict
464 return " " * (4 * self.indent_lev)
469 assert (self.indent_lev >= 0)
470 def register_assignment (self, ident, val, dependencies):
471 if ident in self.assignments:
472 raise DuplicateError("assignment", ident)
473 if ident in self.defined_dict:
474 raise Exception("cross-module duplicates for %s" % ident)
475 self.defined_dict [ident] = 1
476 self.assignments[ident] = val
477 self.dependencies [ident] = dependencies
479 # return "#%s depends on %s" % (ident, str (dependencies))
480 def register_pyquote (self, val):
481 self.pyquotes.append (val)
483 def output_assignments (self):
486 assign_keys = list(self.assignments.keys())
487 to_output_count = len (assign_keys)
490 for (ident, val) in list(self.assignments.items ()):
491 if ident in already_output:
494 for d in self.dependencies [ident]:
495 if ((d not in already_output) and
499 text_list.append ("%s=%s" % (ident,
500 self.assignments [ident]))
501 already_output [ident] = 1
504 assert (to_output_count >= 0)
506 if to_output_count == 0:
508 # OK, we detected a cycle
510 for ident in list(self.assignments.keys ()):
511 if ident not in already_output:
512 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
513 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
515 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
516 for (ident, val) in list(self.assignments.items ()):
517 if ident not in already_output:
518 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
521 return "\n".join (text_list)
522 def output_pyquotes (self):
523 return "\n".join (self.pyquotes)
524 def make_new_name (self):
526 return "_compiler_generated_name_%d" % (self.name_ctr,)
528 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
532 EF_WS_DLL = 0x0010 # exported from shared library
541 #--- common dependency computation ---
542 # Input : list of items
543 # dictionary with lists of dependency
546 # Output : list of two outputs:
547 # [0] list of items in dependency
548 # [1] list of cycle dependency cycles
549 def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False):
552 x = {} # already emitted
553 #print '# Dependency computation'
556 #print 'Continue: %s : %s' % (t, (map_fn(t))
559 stackx = {t : dependency.get(t, [])[:]}
560 #print 'Push: %s : %s' % (t, str(stackx[t]))
562 if stackx[stack[-1]]: # has dependencies
563 d = stackx[stack[-1]].pop(0)
564 if map_fn(d) in x or ignore_fn(d):
566 if d in stackx: # cyclic dependency
569 c = [d] + c[0:c.index(d)+1]
572 #print 'Cyclic: %s ' % (' -> '.join(c))
575 stackx[d] = dependency.get(d, [])[:]
576 #print 'Push: %s : %s' % (d, str(stackx[d]))
578 #print 'Pop: %s' % (stack[-1])
579 del stackx[stack[-1]]
580 e = map_fn(stack.pop())
583 #print 'Add: %s' % (e)
586 return (item_ord, item_cyc)
588 # Given a filename, return a relative path from epan/dissectors
589 def rel_dissector_path(filename):
590 path_parts = os.path.abspath(filename).split(os.sep)
591 while (len(path_parts) > 3 and path_parts[0] != 'asn1'):
593 path_parts.insert(0, '..')
594 path_parts.insert(0, '..')
595 return '/'.join(path_parts)
598 #--- EthCtx -------------------------------------------------------------------
600 def __init__(self, conform, output, indent = 0):
601 self.conform = conform
603 self.conform.ectx = self
604 self.output.ectx = self
605 self.encoding = 'per'
607 self.default_oid_variant = ''
608 self.default_opentype_variant = ''
609 self.default_containing_variant = '_pdu_new'
610 self.default_embedded_pdv_cb = None
611 self.default_external_type_cb = None
612 self.remove_prefix = None
614 self.emitted_pdu = {}
617 self.all_type_attr = {}
621 def encp(self): # encoding protocol
626 def Per(self): return self.encoding == 'per'
627 def Ber(self): return self.encoding == 'ber'
628 def Aligned(self): return self.aligned
629 def Unaligned(self): return not self.aligned
630 def NeedTags(self): return self.tag_opt or self.Ber()
631 def NAPI(self): return False # disable planned features
633 def Module(self): # current module name
634 return self.modules[-1][0]
637 return self.group_by_prot or (self.conform.last_group > 0)
640 if (self.dbgopt.find(d) >= 0):
645 def value_max(self, a, b):
646 if (a == 'MAX') or (b == 'MAX'): return 'MAX';
647 if a == 'MIN': return b;
648 if b == 'MIN': return a;
650 if (int(a) > int(b)):
654 except (ValueError, TypeError):
656 return "MAX((%s),(%s))" % (a, b)
658 def value_min(self, a, b):
659 if (a == 'MIN') or (b == 'MIN'): return 'MIN';
660 if a == 'MAX': return b;
661 if b == 'MAX': return a;
663 if (int(a) < int(b)):
667 except (ValueError, TypeError):
669 return "MIN((%s),(%s))" % (a, b)
671 def value_get_eth(self, val):
672 if isinstance(val, Value):
673 return val.to_str(self)
675 if val in self.value:
676 ethname = self.value[val]['ethname']
679 def value_get_val(self, nm):
682 if self.value[nm]['import']:
683 v = self.get_val_from_all(nm, self.value[nm]['import'])
685 msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto'])
686 warnings.warn_explicit(msg, UserWarning, '', 0)
690 val = self.value[nm]['value']
691 if isinstance (val, Value):
692 val = val.to_str(self)
694 msg = 'Need value of unknown value identifier %s' % (nm)
695 warnings.warn_explicit(msg, UserWarning, '', 0)
698 def eth_get_type_attr(self, type):
699 #print "eth_get_type_attr(%s)" % (type)
701 while (not self.type[type]['import']):
702 val = self.type[type]['val']
705 while (val.type == 'TaggedType'):
707 ttype += '/' + UNTAG_TYPE_NAME
708 if (val.type != 'Type_Ref'):
718 if (self.type[t]['import']):
719 attr.update(self.type[t]['attr'])
720 attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import']))
721 elif (self.type[t]['val'].type == 'SelectionType'):
722 val = self.type[t]['val']
723 (ftype, display) = val.eth_ftype(self)
724 attr.update({ 'TYPE' : ftype, 'DISPLAY' : display,
725 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' });
727 attr.update(self.type[t]['attr'])
728 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
732 def eth_get_type_attr_from_all(self, type, module):
734 if module in self.all_type_attr and type in self.all_type_attr[module]:
735 attr = self.all_type_attr[module][type]
738 def get_ttag_from_all(self, type, module):
740 if module in self.all_tags and type in self.all_tags[module]:
741 ttag = self.all_tags[module][type]
744 def get_val_from_all(self, nm, module):
746 if module in self.all_vals and nm in self.all_vals[module]:
747 val = self.all_vals[module][nm]
750 def get_obj_repr(self, ident, flds=[], not_flds=[]):
751 def set_type_fn(cls, field, fnfield):
752 obj[fnfield + '_fn'] = 'NULL'
753 obj[fnfield + '_pdu'] = 'NULL'
754 if field in val and isinstance(val[field], Type_Ref):
755 p = val[field].eth_type_default_pars(self, '')
756 obj[fnfield + '_fn'] = p['TYPE_REF_FN']
757 obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration
758 if (self.conform.check_item('PDU', cls + '.' + field)):
759 obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname']
761 # end of get_type_fn()
762 obj = { '_name' : ident, '_ident' : asn2c(ident)}
763 obj['_class'] = self.oassign[ident].cls
764 obj['_module'] = self.oassign[ident].module
765 val = self.oassign[ident].val
772 for f in list(val.keys()):
773 if isinstance(val[f], Node):
774 obj[f] = val[f].fld_obj_repr(self)
777 if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'):
778 set_type_fn(obj['_class'], '&Type', '_type')
779 if (obj['_class'] == 'OPERATION'):
780 set_type_fn(obj['_class'], '&ArgumentType', '_argument')
781 set_type_fn(obj['_class'], '&ResultType', '_result')
782 if (obj['_class'] == 'ERROR'):
783 set_type_fn(obj['_class'], '&ParameterType', '_parameter')
786 #--- eth_reg_module -----------------------------------------------------------
787 def eth_reg_module(self, module):
788 #print "eth_reg_module(module='%s')" % (module)
789 name = module.get_name()
790 self.modules.append([name, module.get_proto(self)])
791 if name in self.module:
792 raise DuplicateError("module", name)
793 self.module[name] = []
794 self.module_ord.append(name)
796 #--- eth_module_dep_add ------------------------------------------------------------
797 def eth_module_dep_add(self, module, dep):
798 self.module[module].append(dep)
800 #--- eth_exports ------------------------------------------------------------
801 def eth_exports(self, exports):
802 self.exports_all = False
803 if ((len(exports) == 1) and (exports[0] == 'ALL')):
804 self.exports_all = True
807 if isinstance(e, Type_Ref):
808 self.exports.append(e.val)
809 elif isinstance(e, Class_Ref):
810 self.cexports.append(e.val)
812 self.vexports.append(e)
814 #--- eth_reg_assign ---------------------------------------------------------
815 def eth_reg_assign(self, ident, val, virt=False):
816 #print "eth_reg_assign(ident='%s')" % (ident)
817 if ident in self.assign:
818 raise DuplicateError("assignment", ident)
819 self.assign[ident] = { 'val' : val , 'virt' : virt }
820 self.assign_ord.append(ident)
821 if (self.exports_all):
822 self.exports.append(ident)
824 #--- eth_reg_vassign --------------------------------------------------------
825 def eth_reg_vassign(self, vassign):
826 ident = vassign.ident
827 #print "eth_reg_vassign(ident='%s')" % (ident)
828 if ident in self.vassign:
829 raise DuplicateError("value assignment", ident)
830 self.vassign[ident] = vassign
831 self.vassign_ord.append(ident)
832 if (self.exports_all):
833 self.vexports.append(ident)
835 #--- eth_reg_oassign --------------------------------------------------------
836 def eth_reg_oassign(self, oassign):
837 ident = oassign.ident
838 #print "eth_reg_oassign(ident='%s')" % (ident)
839 if ident in self.oassign:
840 if self.oassign[ident] == oassign:
841 return # OK - already defined
843 raise DuplicateError("information object assignment", ident)
844 self.oassign[ident] = oassign
845 self.oassign_ord.append(ident)
846 self.oassign_cls.setdefault(oassign.cls, []).append(ident)
848 #--- eth_import_type --------------------------------------------------------
849 def eth_import_type(self, ident, mod, proto):
850 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
851 if ident in self.type:
852 #print "already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-'))
853 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
854 return # OK - already defined
855 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
856 return # OK - already imported
858 raise DuplicateError("type", ident)
859 self.type[ident] = {'import' : mod, 'proto' : proto,
861 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
862 'STRINGS' : 'NULL', 'BITMASK' : '0' }
863 mident = "$%s$%s" % (mod, ident)
864 if (self.conform.check_item('TYPE_ATTR', mident)):
865 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', mident))
867 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
868 if (self.conform.check_item('IMPORT_TAG', mident)):
869 self.conform.copy_item('IMPORT_TAG', ident, mident)
870 self.type_imp.append(ident)
872 #--- dummy_import_type --------------------------------------------------------
873 def dummy_import_type(self, ident):
875 if ident in self.type:
876 raise Exception("Try to dummy import for existing type :%s" % ident)
877 ethtype = asn2c(ident)
878 self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
879 'ethname' : ethtype }
880 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
881 'STRINGS' : 'NULL', 'BITMASK' : '0' }
882 self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
883 print("Dummy imported: %s (%s)" % (ident, ethtype))
886 #--- eth_import_class --------------------------------------------------------
887 def eth_import_class(self, ident, mod, proto):
888 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
889 if ident in self.objectclass:
890 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
891 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
892 return # OK - already defined
893 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
894 return # OK - already imported
896 raise DuplicateError("object class", ident)
897 self.objectclass[ident] = {'import' : mod, 'proto' : proto,
899 self.objectclass_imp.append(ident)
901 #--- eth_import_value -------------------------------------------------------
902 def eth_import_value(self, ident, mod, proto):
903 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
904 if ident in self.value:
905 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
906 if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) :
907 return # OK - already defined
908 elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) :
909 return # OK - already imported
911 raise DuplicateError("value", ident)
912 self.value[ident] = {'import' : mod, 'proto' : proto,
914 self.value_imp.append(ident)
916 #--- eth_sel_req ------------------------------------------------------------
917 def eth_sel_req(self, typ, sel):
918 key = typ + '.' + sel
919 if key not in self.sel_req:
920 self.sel_req[key] = { 'typ' : typ , 'sel' : sel}
921 self.sel_req_ord.append(key)
924 #--- eth_comp_req ------------------------------------------------------------
925 def eth_comp_req(self, type):
926 self.comp_req_ord.append(type)
928 #--- eth_dep_add ------------------------------------------------------------
929 def eth_dep_add(self, type, dep):
930 if type not in self.type_dep:
931 self.type_dep[type] = []
932 self.type_dep[type].append(dep)
934 #--- eth_reg_type -----------------------------------------------------------
935 def eth_reg_type(self, ident, val):
936 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
937 if ident in self.type:
938 if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) :
939 # replace imported type
941 self.type_imp.remove(ident)
943 raise DuplicateError("type", ident)
945 self.type[ident] = { 'val' : val, 'import' : None }
946 self.type[ident]['module'] = self.Module()
947 self.type[ident]['proto'] = self.proto
948 if len(ident.split('/')) > 1:
949 self.type[ident]['tname'] = val.eth_tname()
951 self.type[ident]['tname'] = asn2c(ident)
952 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
953 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
954 self.type[ident]['vals_ext'] = self.conform.use_item('USE_VALS_EXT', ident)
955 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
956 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
957 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
958 self.type[ident]['ethname'] = ''
959 if (val.type == 'Type_Ref') or (val.type == 'TaggedType') or (val.type == 'SelectionType') :
960 self.type[ident]['attr'] = {}
962 (ftype, display) = val.eth_ftype(self)
963 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
964 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
965 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
966 self.type_ord.append(ident)
968 if (self.conform.check_item('PDU', ident)):
969 self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident))
971 #--- eth_reg_objectclass ----------------------------------------------------------
972 def eth_reg_objectclass(self, ident, val):
973 #print "eth_reg_objectclass(ident='%s')" % (ident)
974 if ident in self.objectclass:
975 if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) :
976 # replace imported object class
977 del self.objectclass[ident]
978 self.objectclass_imp.remove(ident)
979 elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \
980 isinstance(val, Class_Ref) and \
981 (self.objectclass[ident]['val'].val == val.val):
982 pass # ignore duplicated CLASS1 ::= CLASS2
984 raise DuplicateError("object class", ident)
985 self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto }
986 self.objectclass[ident]['val'] = val
987 self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident)
988 self.objectclass_ord.append(ident)
990 #--- eth_reg_value ----------------------------------------------------------
991 def eth_reg_value(self, ident, type, value, ethname=None):
992 #print "eth_reg_value(ident='%s')" % (ident)
993 if ident in self.value:
994 if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) :
995 # replace imported value
996 del self.value[ident]
997 self.value_imp.remove(ident)
999 self.value[ident]['ethname'] = ethname
1002 raise DuplicateError("value", ident)
1003 self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto,
1004 'type' : type, 'value' : value,
1006 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
1007 self.value[ident]['ethname'] = ''
1008 if (ethname): self.value[ident]['ethname'] = ethname
1009 self.value_ord.append(ident)
1011 #--- eth_reg_field ----------------------------------------------------------
1012 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
1013 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
1014 if ident in self.field:
1015 if pdu and (type == self.field[ident]['type']):
1016 pass # OK already created PDU
1018 raise DuplicateError("field", ident)
1019 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
1020 'modified' : '', 'attr' : {} }
1021 name = ident.split('/')[-1]
1022 if self.remove_prefix and name.startswith(self.remove_prefix):
1023 name = name[len(self.remove_prefix):]
1025 if len(ident.split('/')) > 1 and name == ITEM_FIELD_NAME: # Sequence/Set of type
1026 if len(self.field[ident]['type'].split('/')) > 1:
1027 self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2]
1028 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
1030 self.field[ident]['attr']['NAME'] = '"%s"' % self.field[ident]['type']
1031 self.field[ident]['attr']['ABBREV'] = asn2c(self.field[ident]['type'])
1033 self.field[ident]['attr']['NAME'] = '"%s"' % name
1034 self.field[ident]['attr']['ABBREV'] = asn2c(name)
1035 if self.conform.check_item('FIELD_ATTR', ident):
1036 self.field[ident]['modified'] = '#' + str(id(self))
1037 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
1039 self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0)
1040 self.pdu_ord.append(ident)
1042 self.field_ord.append(ident)
1044 self.eth_dep_add(parent, type)
1046 def eth_dummy_eag_field_required(self):
1047 if (not self.dummy_eag_field):
1048 self.dummy_eag_field = 'eag_field'
1050 #--- eth_clean --------------------------------------------------------------
1051 def eth_clean(self):
1052 self.proto = self.proto_opt;
1053 #--- ASN.1 tables ----------------
1055 self.assign_ord = []
1064 self.sel_req_ord = []
1065 self.comp_req_ord = []
1067 self.vassign_ord = []
1071 self.objectclass = {}
1072 self.objectclass_ord = []
1073 self.objectclass_imp = []
1075 self.oassign_ord = []
1076 self.oassign_cls = {}
1077 #--- Modules ------------
1079 self.exports_all = False
1083 #--- types -------------------
1085 self.eth_type_ord = []
1086 self.eth_export_ord = []
1087 self.eth_type_dupl = {}
1089 #--- value dependencies -------------------
1091 #--- values -------------------
1093 self.eth_value_ord = []
1094 #--- fields -------------------------
1096 self.eth_hf_ord = []
1097 self.eth_hfpdu_ord = []
1098 self.eth_hf_dupl = {}
1099 self.dummy_eag_field = None
1100 #--- type dependencies -------------------
1101 self.eth_type_ord1 = []
1102 self.eth_dep_cycle = []
1103 self.dep_cycle_eth_type = {}
1104 #--- value dependencies and export -------------------
1105 self.eth_value_ord1 = []
1106 self.eth_vexport_ord = []
1108 #--- eth_prepare ------------------------------------------------------------
1109 def eth_prepare(self):
1110 self.eproto = asn2c(self.proto)
1112 #--- dummy types/fields for PDU registration ---
1114 if (self.conform.check_item('PDU', nm)):
1115 self.eth_reg_type('_dummy/'+nm, NullType())
1116 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
1118 #--- required PDUs ----------------------------
1119 for t in self.type_ord:
1120 pdu = self.type[t]['val'].eth_need_pdu(self)
1121 if not pdu: continue
1124 pdu['hidden'] = False
1125 pdu['need_decl'] = True
1126 if f not in self.field:
1127 self.eth_reg_field(f, f, pdu=pdu)
1129 #--- values -> named values -------------------
1131 for v in self.value_ord:
1132 if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1133 if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1134 tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v)
1136 tnm = self.value[v]['type'].val
1137 if tnm in self.type \
1138 and not self.type[tnm]['import'] \
1139 and (self.type[tnm]['val'].type == 'IntegerType'):
1140 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
1141 self.value[v]['no_emit'] = True
1142 t_for_update[tnm] = True
1143 for t in list(t_for_update.keys()):
1144 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
1145 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
1147 #--- required components of ---------------------------
1148 #print "self.comp_req_ord = ", self.comp_req_ord
1149 for t in self.comp_req_ord:
1150 self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
1152 #--- required selection types ---------------------------
1153 #print "self.sel_req_ord = ", self.sel_req_ord
1154 for t in self.sel_req_ord:
1155 tt = self.sel_req[t]['typ']
1156 if tt not in self.type:
1157 self.dummy_import_type(t)
1158 elif self.type[tt]['import']:
1159 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
1161 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
1163 #--- types -------------------
1164 for t in self.type_imp: # imported types
1166 self.eth_type[nm] = { 'import' : self.type[t]['import'],
1167 'proto' : asn2c(self.type[t]['proto']),
1168 'attr' : {}, 'ref' : []}
1169 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1170 self.type[t]['ethname'] = nm
1171 for t in self.type_ord: # dummy import for missing type reference
1172 tp = self.type[t]['val']
1173 #print "X : %s %s " % (t, tp.type)
1174 if isinstance(tp, TaggedType):
1175 #print "%s : %s " % (tp.type, t)
1177 if isinstance(tp, Type_Ref):
1178 #print "%s : %s ::= %s " % (tp.type, t, tp.val)
1179 if tp.val not in self.type:
1180 self.dummy_import_type(tp.val)
1181 for t in self.type_ord:
1182 nm = self.type[t]['tname']
1183 if ((nm.find('#') >= 0) or
1184 ((len(t.split('/'))>1) and
1185 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or
1186 self.conform.get_fn_presence('/'.join((t,ITEM_FIELD_NAME))) or self.conform.check_item('FN_PARS', '/'.join((t,ITEM_FIELD_NAME)))) and
1187 not self.conform.check_item('TYPE_RENAME', t))):
1188 if len(t.split('/')) == 2 and t.split('/')[1] == ITEM_FIELD_NAME: # Sequence of type at the 1st level
1189 nm = t.split('/')[0] + t.split('/')[1]
1190 elif t.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type at next levels
1191 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
1192 elif t.split('/')[-1] == UNTAG_TYPE_NAME: # Untagged type
1193 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
1195 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
1197 if nm in self.eth_type:
1198 if nm in self.eth_type_dupl:
1199 self.eth_type_dupl[nm].append(t)
1201 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
1202 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
1203 if nm in self.eth_type:
1204 self.eth_type[nm]['ref'].append(t)
1206 self.eth_type_ord.append(nm)
1207 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0, 'vals_ext' : 0,
1208 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
1209 'val' : self.type[t]['val'],
1210 'attr' : {}, 'ref' : [t]}
1211 self.type[t]['ethname'] = nm
1212 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
1213 self.eth_export_ord.append(nm)
1214 self.eth_type[nm]['export'] |= self.type[t]['export']
1215 self.eth_type[nm]['enum'] |= self.type[t]['enum']
1216 self.eth_type[nm]['vals_ext'] |= self.type[t]['vals_ext']
1217 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
1218 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
1219 if self.type[t]['attr'].get('STRINGS') == '$$':
1220 use_ext = self.type[t]['vals_ext']
1222 self.eth_type[nm]['attr']['STRINGS'] = '&%s_ext' % (self.eth_vals_nm(nm))
1224 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
1225 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1226 for t in self.eth_type_ord:
1227 bits = self.eth_type[t]['val'].eth_named_bits()
1229 for (val, id) in bits:
1230 self.named_bit.append({'name' : id, 'val' : val,
1231 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
1232 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1234 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
1235 if self.eth_type[t]['val'].eth_need_tree():
1236 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
1238 self.eth_type[t]['tree'] = None
1240 #--- register values from enums ------------
1241 for t in self.eth_type_ord:
1242 if (self.eth_type[t]['val'].eth_has_enum(t, self)):
1243 self.eth_type[t]['val'].reg_enum_vals(t, self)
1245 #--- value dependencies -------------------
1246 for v in self.value_ord:
1247 if isinstance (self.value[v]['value'], Value):
1248 dep = self.value[v]['value'].get_dep()
1250 dep = self.value[v]['value']
1251 if dep and dep in self.value:
1252 self.value_dep.setdefault(v, []).append(dep)
1254 #--- exports all necessary values
1255 for v in self.value_ord:
1256 if not self.value[v]['export']: continue
1257 deparr = self.value_dep.get(v, [])
1260 if not self.value[d]['import']:
1261 if not self.value[d]['export']:
1262 self.value[d]['export'] = EF_TYPE
1263 deparr.extend(self.value_dep.get(d, []))
1265 #--- values -------------------
1266 for v in self.value_imp:
1268 self.eth_value[nm] = { 'import' : self.value[v]['import'],
1269 'proto' : asn2c(self.value[v]['proto']),
1271 self.value[v]['ethname'] = nm
1272 for v in self.value_ord:
1273 if (self.value[v]['ethname']):
1275 if (self.value[v]['no_emit']):
1278 self.eth_value[nm] = { 'import' : None,
1279 'proto' : asn2c(self.value[v]['proto']),
1280 'export' : self.value[v]['export'], 'ref' : [v] }
1281 self.eth_value[nm]['value'] = self.value[v]['value']
1282 self.eth_value_ord.append(nm)
1283 self.value[v]['ethname'] = nm
1285 #--- fields -------------------------
1286 for f in (self.pdu_ord + self.field_ord):
1287 if len(f.split('/')) > 1 and f.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type
1288 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
1290 nm = f.split('/')[-1]
1291 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
1293 if (self.field[f]['pdu']):
1295 if (not self.merge_modules or self.field[f]['pdu']['export']):
1296 nm = self.eproto + '_' + nm
1297 t = self.field[f]['type']
1299 ethtype = self.type[t]['ethname']
1300 else: # undefined type
1301 ethtype = self.dummy_import_type(t)
1302 ethtypemod = ethtype + self.field[f]['modified']
1303 if nm in self.eth_hf:
1304 if nm in self.eth_hf_dupl:
1305 if ethtypemod in self.eth_hf_dupl[nm]:
1306 nm = self.eth_hf_dupl[nm][ethtypemod]
1307 self.eth_hf[nm]['ref'].append(f)
1308 self.field[f]['ethname'] = nm
1311 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
1312 self.eth_hf_dupl[nm][ethtype] = nmx
1315 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
1316 self.eth_hf[nm]['ref'].append(f)
1317 self.field[f]['ethname'] = nm
1321 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
1324 if (self.field[f]['pdu']):
1325 self.eth_hfpdu_ord.append(nm)
1327 self.eth_hf_ord.append(nm)
1328 fullname = 'hf_%s_%s' % (self.eproto, nm)
1329 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
1330 attr.update(self.field[f]['attr'])
1331 if (self.NAPI() and 'NAME' in attr):
1332 attr['NAME'] += self.field[f]['idx']
1333 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
1334 use_vals_ext = self.eth_type[ethtype].get('vals_ext')
1336 attr['DISPLAY'] += '|BASE_EXT_STRING'
1337 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
1338 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
1339 'attr' : attr.copy(),
1341 self.field[f]['ethname'] = nm
1342 if (self.dummy_eag_field):
1343 # Prepending "dummy_" avoids matching checkhf.pl.
1344 self.dummy_eag_field = 'dummy_hf_%s_%s' % (self.eproto, self.dummy_eag_field)
1345 #--- type dependencies -------------------
1346 (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'])
1348 while i < len(self.eth_dep_cycle):
1349 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1350 self.dep_cycle_eth_type.setdefault(t, []).append(i)
1353 #--- value dependencies and export -------------------
1354 for v in self.eth_value_ord:
1355 if self.eth_value[v]['export']:
1356 self.eth_vexport_ord.append(v)
1358 self.eth_value_ord1.append(v)
1360 #--- export tags, values, ... ---
1361 for t in self.exports:
1362 if t not in self.type:
1364 if self.type[t]['import']:
1366 m = self.type[t]['module']
1368 if m not in self.all_tags:
1369 self.all_tags[m] = {}
1370 self.all_tags[m][t] = self.type[t]['val'].GetTTag(self)
1371 if m not in self.all_type_attr:
1372 self.all_type_attr[m] = {}
1373 self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy()
1374 for v in self.vexports:
1375 if v not in self.value:
1377 if self.value[v]['import']:
1379 m = self.value[v]['module']
1380 if m not in self.all_vals:
1381 self.all_vals[m] = {}
1382 vv = self.value[v]['value']
1383 if isinstance (vv, Value):
1384 vv = vv.to_str(self)
1385 self.all_vals[m][v] = vv
1387 #--- eth_vals_nm ------------------------------------------------------------
1388 def eth_vals_nm(self, tname):
1390 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
1391 out += "%s_" % (self.eproto)
1392 out += "%s_vals" % (tname)
1395 #--- eth_vals ---------------------------------------------------------------
1396 def eth_vals(self, tname, vals):
1398 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
1399 use_ext = self.eth_type[tname]['vals_ext']
1401 vals.sort(key=lambda vals_entry: int(vals_entry[0]))
1402 if (not self.eth_type[tname]['export'] & EF_VALS):
1404 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
1406 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
1407 for (val, id) in vals:
1409 vval = self.eth_enum_item(tname, id)
1412 out += ' { %3s, "%s" },\n' % (vval, id)
1413 out += " { 0, NULL }\n};\n"
1415 out += "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self.eth_vals_nm(tname), self.eth_vals_nm(tname))
1418 #--- eth_enum_prefix ------------------------------------------------------------
1419 def eth_enum_prefix(self, tname, type=False):
1421 if (self.eth_type[tname]['export'] & EF_ENUM):
1422 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
1424 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
1427 if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type):
1428 if (out): out += '_'
1430 if (self.eth_type[tname]['enum'] & EF_UCASE):
1432 if (out): out += '_'
1435 #--- eth_enum_nm ------------------------------------------------------------
1436 def eth_enum_nm(self, tname):
1437 out = self.eth_enum_prefix(tname, type=True)
1441 #--- eth_enum_item ---------------------------------------------------------------
1442 def eth_enum_item(self, tname, ident):
1443 out = self.eth_enum_prefix(tname)
1445 if (self.eth_type[tname]['enum'] & EF_UCASE):
1449 #--- eth_enum ---------------------------------------------------------------
1450 def eth_enum(self, tname, vals):
1452 if (self.eth_type[tname]['enum'] & EF_DEFINE):
1453 out += "/* enumerated values for %s */\n" % (tname)
1454 for (val, id) in vals:
1455 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
1457 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
1459 for (val, id) in vals:
1460 if (first_line == 1):
1464 out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val)
1465 out += "\n} %s;\n" % (self.eth_enum_nm(tname))
1468 #--- eth_bits ---------------------------------------------------------------
1469 def eth_bits(self, tname, bits):
1471 out += "static const "
1472 out += "asn_namedbit %(TABLE)s[] = {\n"
1473 for (val, id) in bits:
1474 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
1475 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
1478 #--- eth_type_fn_h ----------------------------------------------------------
1479 def eth_type_fn_h(self, tname):
1481 if (not self.eth_type[tname]['export'] & EF_TYPE):
1485 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)
1487 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 #--- eth_fn_call ------------------------------------------------------------
1492 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
1495 if (ret == 'return'):
1501 for i in range(len(par)):
1502 if (i>0): out += ind * ' '
1503 out += ', '.join(par[i])
1504 if (i<(len(par)-1)): out += ',\n'
1508 #--- eth_type_fn_hdr --------------------------------------------------------
1509 def eth_type_fn_hdr(self, tname):
1511 if (not self.eth_type[tname]['export'] & EF_TYPE):
1515 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)
1517 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)
1518 #if self.conform.get_fn_presence(tname):
1519 # out += self.conform.get_fn_text(tname, 'FN_HDR')
1521 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1522 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1525 #--- eth_type_fn_ftr --------------------------------------------------------
1526 def eth_type_fn_ftr(self, tname):
1528 #if self.conform.get_fn_presence(tname):
1529 # out += self.conform.get_fn_text(tname, 'FN_FTR')
1531 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1532 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1533 out += " return offset;\n"
1537 #--- eth_type_fn_body -------------------------------------------------------
1538 def eth_type_fn_body(self, tname, body, pars=None):
1540 #if self.conform.get_fn_body_presence(tname):
1541 # out = self.conform.get_fn_text(tname, 'FN_BODY')
1543 if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1544 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1552 #--- eth_out_pdu_decl ----------------------------------------------------------
1553 def eth_out_pdu_decl(self, f):
1554 t = self.eth_hf[f]['ethtype']
1555 is_new = self.eth_hf[f]['pdu']['new']
1557 if (not self.eth_hf[f]['pdu']['export']):
1561 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n'
1564 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);\n'
1567 #--- eth_output_hf ----------------------------------------------------------
1568 def eth_output_hf (self):
1569 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1570 fx = self.output.file_open('hf')
1571 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1572 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1573 if (self.named_bit):
1574 fx.write('/* named bits */\n')
1575 for nb in self.named_bit:
1576 fx.write("static int %s = -1;\n" % (nb['ethname']))
1577 if (self.dummy_eag_field):
1578 fx.write("static int %s = -1; /* never registered */\n" % (self.dummy_eag_field))
1579 self.output.file_close(fx)
1581 #--- eth_output_hf_arr ------------------------------------------------------
1582 def eth_output_hf_arr (self):
1583 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1584 fx = self.output.file_open('hfarr')
1585 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1586 t = self.eth_hf[f]['ethtype']
1587 if self.remove_prefix and t.startswith(self.remove_prefix):
1588 t = t[len(self.remove_prefix):]
1589 name=self.eth_hf[f]['attr']['NAME']
1591 trantab = maketrans("- ", "__")
1593 trantab = str.maketrans("- ", "__")
1594 name = name.translate(trantab)
1595 namelower = name.lower()
1596 tquoted_lower = '"' + t.lower() + '"'
1597 # Try to avoid giving blurbs that give no more info than the name
1598 if tquoted_lower == namelower or \
1600 tquoted_lower.replace("t_", "") == namelower:
1603 blurb = '"%s"' % (t)
1604 attr = self.eth_hf[f]['attr'].copy()
1605 if attr['TYPE'] == 'FT_NONE':
1606 attr['ABBREV'] = '"%s.%s_element"' % (self.proto, attr['ABBREV'])
1608 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1609 if 'BLURB' not in attr:
1610 attr['BLURB'] = blurb
1611 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1612 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1613 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1614 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1615 for nb in self.named_bit:
1616 fx.write(' { &%s,\n' % (nb['ethname']))
1617 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1618 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1619 fx.write(' NULL, HFILL }},\n')
1620 self.output.file_close(fx)
1622 #--- eth_output_ett ---------------------------------------------------------
1623 def eth_output_ett (self):
1624 fx = self.output.file_open('ett')
1626 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1627 for t in self.eth_type_ord:
1628 if self.eth_type[t]['tree']:
1629 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1631 self.output.file_close(fx, discard=fempty)
1633 #--- eth_output_ett_arr -----------------------------------------------------
1634 def eth_output_ett_arr(self):
1635 fx = self.output.file_open('ettarr')
1637 #fx.write(" &ett_%s,\n" % (self.eproto))
1638 for t in self.eth_type_ord:
1639 if self.eth_type[t]['tree']:
1640 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1642 self.output.file_close(fx, discard=fempty)
1644 #--- eth_output_export ------------------------------------------------------
1645 def eth_output_export(self):
1646 fx = self.output.file_open('exp', ext='h')
1647 for t in self.eth_export_ord: # vals
1648 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1649 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1650 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1651 if not self.eth_type[t]['export'] & EF_TABLE:
1652 if self.eth_type[t]['export'] & EF_WS_DLL:
1653 fx.write("WS_DLL_PUBLIC ")
1656 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1658 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1659 for t in self.eth_export_ord: # functions
1660 if (self.eth_type[t]['export'] & EF_TYPE):
1661 if self.eth_type[t]['export'] & EF_EXTERN:
1662 if self.eth_type[t]['export'] & EF_WS_DLL:
1663 fx.write("WS_DLL_PUBLIC ")
1666 fx.write(self.eth_type_fn_h(t))
1667 for f in self.eth_hfpdu_ord: # PDUs
1668 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']):
1669 fx.write(self.eth_out_pdu_decl(f))
1670 self.output.file_close(fx)
1672 #--- eth_output_expcnf ------------------------------------------------------
1673 def eth_output_expcnf(self):
1674 fx = self.output.file_open('exp', ext='cnf')
1675 fx.write('#.MODULE\n')
1677 for (m, p) in self.modules:
1678 if (len(m) > maxw): maxw = len(m)
1679 for (m, p) in self.modules:
1680 fx.write("%-*s %s\n" % (maxw, m, p))
1681 fx.write('#.END\n\n')
1682 for cls in self.objectclass_ord:
1683 if self.objectclass[cls]['export']:
1685 if self.objectclass[cls]['export'] & EF_MODULE:
1686 cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm)
1687 fx.write('#.CLASS %s\n' % (cnm))
1689 for fld in self.objectclass[cls]['val'].fields:
1690 w = len(fld.fld_repr()[0])
1691 if (w > maxw): maxw = w
1692 for fld in self.objectclass[cls]['val'].fields:
1693 repr = fld.fld_repr()
1694 fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:])))
1695 fx.write('#.END\n\n')
1697 fx.write('#.IMPORT_TAG\n')
1698 for t in self.eth_export_ord: # tags
1699 if (self.eth_type[t]['export'] & EF_TYPE):
1700 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1701 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1702 fx.write('#.END\n\n')
1703 fx.write('#.TYPE_ATTR\n')
1704 for t in self.eth_export_ord: # attributes
1705 if (self.eth_type[t]['export'] & EF_TYPE):
1706 tnm = self.eth_type[t]['ref'][0]
1707 if self.eth_type[t]['export'] & EF_MODULE:
1708 tnm = "$%s$%s" % (self.type[tnm]['module'], tnm)
1709 fx.write('%-24s ' % tnm)
1710 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1711 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1712 fx.write('#.END\n\n')
1713 self.output.file_close(fx, keep_anyway=True)
1715 #--- eth_output_val ------------------------------------------------------
1716 def eth_output_val(self):
1717 fx = self.output.file_open('val', ext='h')
1718 for v in self.eth_value_ord1:
1719 vv = self.eth_value[v]['value']
1720 if isinstance (vv, Value):
1721 vv = vv.to_str(self)
1722 fx.write("#define %-30s %s\n" % (v, vv))
1723 for t in self.eth_type_ord1:
1724 if self.eth_type[t]['import']:
1726 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1727 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1728 self.output.file_close(fx)
1730 #--- eth_output_valexp ------------------------------------------------------
1731 def eth_output_valexp(self):
1732 if (not len(self.eth_vexport_ord)): return
1733 fx = self.output.file_open('valexp', ext='h')
1734 for v in self.eth_vexport_ord:
1735 vv = self.eth_value[v]['value']
1736 if isinstance (vv, Value):
1737 vv = vv.to_str(self)
1738 fx.write("#define %-30s %s\n" % (v, vv))
1739 self.output.file_close(fx)
1741 #--- eth_output_types -------------------------------------------------------
1742 def eth_output_types(self):
1744 t = self.eth_hf[f]['ethtype']
1745 is_new = self.eth_hf[f]['pdu']['new']
1748 if (not self.eth_hf[f]['pdu']['export']):
1752 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n'
1755 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1757 out += ' int offset = 0;\n'
1764 if (self.Aligned()):
1768 out += " asn1_ctx_t asn1_ctx;\n"
1769 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1771 out += " asn1_ctx_t asn1_ctx;\n"
1772 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
1773 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1775 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1778 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1779 if (self.Per() and is_new):
1780 out += ' offset += 7; offset >>= 3;\n'
1782 out += ' return offset;\n'
1786 fx = self.output.file_open('fn')
1788 if (len(self.eth_hfpdu_ord)):
1790 for f in self.eth_hfpdu_ord:
1791 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
1793 fx.write('/*--- PDUs declarations ---*/\n')
1795 fx.write(self.eth_out_pdu_decl(f))
1798 if self.eth_dep_cycle:
1799 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1801 while i < len(self.eth_dep_cycle):
1802 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1803 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1804 fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]]))
1805 fx.write(self.eth_type_fn_h(t))
1809 for t in self.eth_type_ord1:
1810 if self.eth_type[t]['import']:
1812 if self.eth_type[t]['val'].eth_has_vals():
1813 if self.eth_type[t]['no_emit'] & EF_VALS:
1815 elif self.eth_type[t]['user_def'] & EF_VALS:
1816 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1817 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1820 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1821 if self.eth_type[t]['no_emit'] & EF_TYPE:
1823 elif self.eth_type[t]['user_def'] & EF_TYPE:
1824 fx.write(self.eth_type_fn_h(t))
1826 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1828 if (len(self.eth_hfpdu_ord)):
1829 fx.write('/*--- PDUs ---*/\n\n')
1830 for f in self.eth_hfpdu_ord:
1831 if (self.eth_hf[f]['pdu']):
1832 if (f in self.emitted_pdu):
1833 fx.write(" /* %s already emitted */\n" % (f))
1835 fx.write(out_pdu(f))
1836 self.emitted_pdu[f] = True
1838 fempty = pos == fx.tell()
1839 self.output.file_close(fx, discard=fempty)
1841 #--- eth_output_dis_hnd -----------------------------------------------------
1842 def eth_output_dis_hnd(self):
1843 fx = self.output.file_open('dis-hnd')
1845 for f in self.eth_hfpdu_ord:
1846 pdu = self.eth_hf[f]['pdu']
1847 if (pdu and pdu['reg'] and not pdu['hidden']):
1849 if (pdu['reg'] != '.'):
1850 dis += '.' + pdu['reg']
1851 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1854 self.output.file_close(fx, discard=fempty)
1856 #--- eth_output_dis_reg -----------------------------------------------------
1857 def eth_output_dis_reg(self):
1858 fx = self.output.file_open('dis-reg')
1860 for f in self.eth_hfpdu_ord:
1861 pdu = self.eth_hf[f]['pdu']
1862 if (pdu and pdu['reg']):
1864 if (pdu['new']): new_prefix = 'new_'
1866 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1867 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1868 if (not pdu['hidden']):
1869 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1872 self.output.file_close(fx, discard=fempty)
1874 #--- eth_output_dis_tab -----------------------------------------------------
1875 def eth_output_dis_tab(self):
1876 fx = self.output.file_open('dis-tab')
1878 for k in self.conform.get_order('REGISTER'):
1879 reg = self.conform.use_item('REGISTER', k)
1880 if reg['pdu'] not in self.field: continue
1881 f = self.field[reg['pdu']]['ethname']
1882 pdu = self.eth_hf[f]['pdu']
1884 if (pdu['new']): new_prefix = 'new_'
1885 if (reg['rtype'] in ('NUM', 'STR')):
1887 if (reg['rtype'] == 'STR'):
1893 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1894 if (not pdu['hidden']):
1895 hnd = '%s_handle' % (asn2c(dis))
1897 hnd = 'find_dissector("%s")' % (dis)
1899 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1900 rport = self.value_get_eth(reg['rport'])
1901 fx.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
1902 elif (reg['rtype'] in ('BER', 'PER')):
1903 roid = self.value_get_eth(reg['roid'])
1904 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
1907 self.output.file_close(fx, discard=fempty)
1909 #--- eth_output_syn_reg -----------------------------------------------------
1910 def eth_output_syn_reg(self):
1911 fx = self.output.file_open('syn-reg')
1914 for k in self.conform.get_order('SYNTAX'):
1915 reg = self.conform.use_item('SYNTAX', k)
1916 if reg['pdu'] not in self.field: continue
1917 f = self.field[reg['pdu']]['ethname']
1918 pdu = self.eth_hf[f]['pdu']
1920 if (pdu['new']): new_prefix = 'new_'
1922 fx.write(' /*--- Syntax registrations ---*/\n')
1924 fx.write(' %sregister_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (new_prefix, k, self.eproto, reg['pdu']));
1926 self.output.file_close(fx, discard=fempty)
1928 #--- eth_output_tables -----------------------------------------------------
1929 def eth_output_tables(self):
1930 for num in list(self.conform.report.keys()):
1931 fx = self.output.file_open('table' + num)
1932 for rep in self.conform.report[num]:
1933 self.eth_output_table(fx, rep)
1934 self.output.file_close(fx)
1936 #--- eth_output_table -----------------------------------------------------
1937 def eth_output_table(self, fx, rep):
1938 if rep['type'] == 'HDR':
1942 var_list = var.split('.', 1)
1950 not_flds.append(f[1:])
1958 sort_flds.append(f[1:])
1963 if (cls in self.oassign_cls):
1964 for ident in self.oassign_cls[cls]:
1965 obj = self.get_obj_repr(ident, flds, not_flds)
1969 obj['_DICT'] = str(obj)
1971 objs_ord.append(ident)
1973 # Sort identifiers according to the matching object in objs.
1974 # The order is determined by sort_flds, keys prefixed by a
1975 # '#' are compared numerically.
1976 def obj_key_fn(name):
1979 int(obj[f[1:]]) if f[0] == '#' else obj[f]
1982 objs_ord.sort(key=obj_key_fn)
1983 for ident in objs_ord:
1986 text = rep['text'] % obj
1988 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("/* Unknown or empty loop list %s */\n" % (var))
1993 fx.write(rep['text'])
1994 if rep['type'] == 'FTR':
1997 #--- dupl_report -----------------------------------------------------
1998 def dupl_report(self):
2000 tmplist = sorted(self.eth_type_dupl.keys())
2002 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
2004 for tt in self.eth_type_dupl[t]:
2005 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
2006 warnings.warn_explicit(msg, UserWarning, '', 0)
2008 tmplist = list(self.eth_hf_dupl.keys())
2011 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
2013 for tt in list(self.eth_hf_dupl[f].keys()):
2014 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
2015 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
2017 warnings.warn_explicit(msg, UserWarning, '', 0)
2019 #--- eth_do_output ------------------------------------------------------------
2020 def eth_do_output(self):
2022 print("\n# Assignments")
2023 for a in self.assign_ord:
2025 if (self.assign[a]['virt']): v = '*'
2027 print("\n# Value assignments")
2028 for a in self.vassign_ord:
2030 print("\n# Information object assignments")
2031 for a in self.oassign_ord:
2032 print(" %-12s (%s)" % (a, self.oassign[a].cls))
2034 print("\n# Imported Types")
2035 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2037 for t in self.type_imp:
2038 print("%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto']))
2039 print("\n# Imported Values")
2040 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2042 for t in self.value_imp:
2043 print("%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto']))
2044 print("\n# Imported Object Classes")
2045 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2047 for t in self.objectclass_imp:
2048 print("%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto']))
2049 print("\n# Exported Types")
2050 print("%-31s %s" % ("Wireshark type", "Export Flag"))
2052 for t in self.eth_export_ord:
2053 print("%-31s 0x%02X" % (t, self.eth_type[t]['export']))
2054 print("\n# Exported Values")
2055 print("%-40s %s" % ("Wireshark name", "Value"))
2057 for v in self.eth_vexport_ord:
2058 vv = self.eth_value[v]['value']
2059 if isinstance (vv, Value):
2060 vv = vv.to_str(self)
2061 print("%-40s %s" % (v, vv))
2062 print("\n# ASN.1 Object Classes")
2063 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2065 for t in self.objectclass_ord:
2066 print("%-40s " % (t))
2067 print("\n# ASN.1 Types")
2068 print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type"))
2070 for t in self.type_ord:
2071 print("%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname']))
2072 print("\n# Wireshark Types")
2073 print("Wireshark type References (ASN.1 types)")
2075 for t in self.eth_type_ord:
2076 sys.stdout.write("%-31s %d" % (t, len(self.eth_type[t]['ref'])))
2077 print(', '.join(self.eth_type[t]['ref']))
2078 print("\n# ASN.1 Values")
2079 print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value"))
2081 for v in self.value_ord:
2082 vv = self.value[v]['value']
2083 if isinstance (vv, Value):
2084 vv = vv.to_str(self)
2085 print("%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname']))
2086 #print "\n# Wireshark Values"
2087 #print "%-40s %s" % ("Wireshark name", "Value")
2089 #for v in self.eth_value_ord:
2090 # vv = self.eth_value[v]['value']
2091 # if isinstance (vv, Value):
2092 # vv = vv.to_str(self)
2093 # print "%-40s %s" % (v, vv)
2094 print("\n# ASN.1 Fields")
2095 print("ASN.1 unique name Wireshark name ASN.1 type")
2097 for f in (self.pdu_ord + self.field_ord):
2098 print("%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type']))
2099 print("\n# Wireshark Fields")
2100 print("Wireshark name Wireshark type References (ASN.1 fields)")
2102 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
2103 sys.stdout.write("%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])))
2104 print(', '.join(self.eth_hf[f]['ref']))
2105 #print "\n# Order after dependencies"
2106 #print '\n'.join(self.eth_type_ord1)
2107 print("\n# Cyclic dependencies")
2108 for c in self.eth_dep_cycle:
2109 print(' -> '.join(c))
2111 self.output.outnm = self.outnm_opt
2112 if (not self.output.outnm):
2113 self.output.outnm = self.proto
2114 self.output.outnm = self.output.outnm.replace('.', '-')
2115 if not self.justexpcnf:
2116 self.eth_output_hf()
2117 self.eth_output_ett()
2118 self.eth_output_types()
2119 self.eth_output_hf_arr()
2120 self.eth_output_ett_arr()
2121 self.eth_output_export()
2122 self.eth_output_val()
2123 self.eth_output_valexp()
2124 self.eth_output_dis_hnd()
2125 self.eth_output_dis_reg()
2126 self.eth_output_dis_tab()
2127 self.eth_output_syn_reg()
2128 self.eth_output_tables()
2130 self.eth_output_expcnf()
2132 def dbg_modules(self):
2134 sys.stdout.write("%-30s " % (m))
2135 dep = self.module[m][:]
2136 for i in range(len(dep)):
2137 if dep[i] not in self.module:
2138 dep[i] = '*' + dep[i]
2139 print(', '.join(dep))
2140 # end of print_mod()
2141 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module)
2142 print("\n# ASN.1 Moudules")
2143 print("Module name Dependency")
2146 for m in (self.module_ord):
2148 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
2150 print("\n# ASN.1 Moudules - in dependency order")
2151 print("Module name Dependency")
2156 print("\nCyclic dependencies:")
2157 for i in (list(range(len(mod_cyc)))):
2158 print("%02d: %s" % (i + 1, str(mod_cyc[i])))
2161 #--- EthCnf -------------------------------------------------------------------
2170 self.suppress_line = False
2171 self.include_path = []
2172 # Value name Default value Duplicity check Usage check
2173 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2174 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2175 self.tblcfg['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2176 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2177 self.tblcfg['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2178 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2179 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2180 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2181 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2182 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2183 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2184 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2185 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2186 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2187 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2188 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2189 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2190 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2191 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2192 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2193 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2194 self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2195 self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2197 for k in list(self.tblcfg.keys()) :
2201 def add_item(self, table, key, fn, lineno, **kw):
2202 if self.tblcfg[table]['chk_dup'] and key in self.table[table]:
2203 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2204 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
2205 UserWarning, fn, lineno)
2207 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2208 self.table[table][key].update(kw)
2209 self.order[table].append(key)
2211 def update_item(self, table, key, fn, lineno, **kw):
2212 if key not in self.table[table]:
2213 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2214 self.order[table].append(key)
2215 self.table[table][key][self.tblcfg[table]['val_nm']] = {}
2216 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
2218 def get_order(self, table):
2219 return self.order[table]
2221 def check_item(self, table, key):
2222 return key in self.table[table]
2224 def copy_item(self, table, dst_key, src_key):
2225 if (src_key in self.table[table]):
2226 self.table[table][dst_key] = self.table[table][src_key]
2228 def check_item_value(self, table, key, **kw):
2229 return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key]
2231 def use_item(self, table, key, **kw):
2232 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
2233 if key not in self.table[table]: return vdflt
2234 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
2235 #print "use_item() - set used for %s %s" % (table, key)
2236 self.table[table][key]['used'] = True
2237 return self.table[table][key].get(vname, vdflt)
2239 def omit_assignment(self, type, ident, module):
2240 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
2242 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
2243 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2244 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
2245 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
2246 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
2249 def add_fn_line(self, name, ctx, line, fn, lineno):
2250 if name not in self.fn:
2251 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2252 if (self.fn[name][ctx]):
2253 self.fn[name][ctx]['text'] += line
2255 self.fn[name][ctx] = {'text' : line, 'used' : False,
2256 'fn' : fn, 'lineno' : lineno}
2257 def get_fn_presence(self, name):
2258 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2259 #if self.fn.has_key(name): print self.fn[name]
2260 return name in self.fn
2261 def get_fn_body_presence(self, name):
2262 return name in self.fn and self.fn[name]['FN_BODY']
2263 def get_fn_text(self, name, ctx):
2264 if (name not in self.fn):
2266 if (not self.fn[name][ctx]):
2268 self.fn[name][ctx]['used'] = True
2269 out = self.fn[name][ctx]['text']
2270 if (not self.suppress_line):
2271 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], rel_dissector_path(self.fn[name][ctx]['fn']), out);
2274 def add_pdu(self, par, is_new, fn, lineno):
2275 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2276 (reg, hidden) = (None, False)
2277 if (len(par) > 1): reg = par[1]
2278 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
2279 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False}
2280 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
2283 def add_syntax(self, par, fn, lineno):
2284 #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno)
2285 if( (len(par) >=2)):
2288 name = '"'+par[0]+'"'
2289 attr = { 'pdu' : par[0] }
2290 self.add_item('SYNTAX', name, attr=attr, fn=fn, lineno=lineno)
2293 def add_register(self, pdu, par, fn, lineno):
2294 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2295 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
2296 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
2297 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
2298 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
2299 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
2300 if ((len(par)-1) < pmin):
2301 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
2303 if ((len(par)-1) > pmax):
2304 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
2305 attr = {'pdu' : pdu, 'rtype' : rtype}
2306 if (rtype in ('NUM', 'STR')):
2307 attr['rtable'] = par[1]
2308 attr['rport'] = par[2]
2309 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
2310 elif (rtype in ('BER', 'PER')):
2311 attr['roid'] = par[1]
2312 attr['roidname'] = '""'
2314 attr['roidname'] = par[2]
2315 elif attr['roid'][0] != '"':
2316 attr['roidname'] = '"' + attr['roid'] + '"'
2317 rkey = '/'.join([rtype, attr['roid']])
2318 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
2320 def check_par(self, par, pmin, pmax, fn, lineno):
2321 for i in range(len(par)):
2325 if par[i][0] == '#':
2329 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2331 if (pmax >= 0) and (len(par) > pmax):
2332 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
2337 def get_par(line, pmin, pmax, fn, lineno):
2338 par = line.split(None, pmax)
2339 par = self.check_par(par, pmin, pmax, fn, lineno)
2342 def get_par_nm(line, pmin, pmax, fn, lineno):
2344 par = line.split(None, pmax)
2347 for i in range(len(par)):
2348 if par[i][0] == '#':
2352 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2359 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2360 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2361 nmpar_end = re.compile(r'\s*$')
2362 result = nmpar_first.search(nmpar)
2365 k = result.group('attr')
2367 result = nmpar_next.search(nmpar, pos)
2372 p2 = nmpar_end.search(nmpar, pos).start()
2382 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2383 cdirective = re.compile(r'^\s*##')
2384 report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2385 comment = re.compile(r'^\s*#[^.#]')
2386 empty = re.compile(r'^\s*$')
2389 default_flags = 0x00
2402 fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import']
2406 if comment.search(line): continue
2407 result = directive.search(line)
2408 if result: # directive
2409 rep_result = report.search(result.group('name'))
2410 if result.group('name') == 'END_OF_CNF':
2412 elif result.group('name') == 'OPT':
2413 ctx = result.group('name')
2414 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
2415 if not par: continue
2416 self.set_opt(par[0], par[1:], fn, lineno)
2418 elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
2419 'MODULE', 'MODULE_IMPORT',
2420 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2421 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2422 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2423 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR',
2424 'SYNTAX', 'SYNTAX_NEW'):
2425 ctx = result.group('name')
2426 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2427 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2428 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2429 ctx = result.group('name')
2431 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2433 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2435 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2438 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
2439 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2440 ctx = 'NO_OMIT_ASSGN'
2443 elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2444 ctx = result.group('name')
2445 default_flags = EF_TYPE|EF_VALS
2446 if ctx == 'MODULE_EXPORTS':
2448 default_flags |= EF_MODULE
2449 if ctx == 'EXPORTS':
2450 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
2452 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2453 if not par: continue
2455 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
2456 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
2457 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
2458 elif (ctx == 'EXPORTS'): p = 0
2459 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
2460 for i in range(p, len(par)):
2461 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
2462 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
2463 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
2464 elif (par[i] == 'WS_DLL'): default_flags |= EF_WS_DLL
2465 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
2466 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2467 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2468 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2469 ctx = result.group('name')
2470 default_flags = EF_ENUM
2471 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
2472 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2473 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
2474 for i in range(0, len(par)):
2475 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2476 elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT
2477 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
2478 elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE
2479 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
2480 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
2481 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2482 elif result.group('name') == 'USE_VALS_EXT':
2483 ctx = result.group('name')
2484 default_flags = 0xFF
2485 elif result.group('name') == 'FN_HDR':
2487 if (ctx in ('FN_PARS',)) and name: minp = 0
2488 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2489 if (not par) and (minp > 0): continue
2490 ctx = result.group('name')
2491 if par: name = par[0]
2492 elif result.group('name') == 'FN_FTR':
2494 if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0
2495 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2496 if (not par) and (minp > 0): continue
2497 ctx = result.group('name')
2498 if par: name = par[0]
2499 elif result.group('name') == 'FN_BODY':
2500 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2501 if not par: continue
2502 ctx = result.group('name')
2505 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
2506 elif result.group('name') == 'FN_PARS':
2507 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2508 ctx = result.group('name')
2513 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
2515 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2517 elif result.group('name') == 'CLASS':
2518 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2519 if not par: continue
2520 ctx = result.group('name')
2522 add_class_ident(name)
2523 if not name.split('$')[-1].isupper():
2524 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
2525 UserWarning, fn, lineno)
2526 elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2527 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2528 if not par: continue
2529 self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno)
2530 elif rep_result: # Reports
2531 num = rep_result.group('num')
2532 type = rep_result.group('type')
2534 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2535 if not par: continue
2537 par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno)
2538 rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno }
2541 self.report.setdefault(num, []).append(rep)
2544 elif result.group('name') in ('INCLUDE', 'IMPORT') :
2545 is_imp = result.group('name') == 'IMPORT'
2546 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2548 warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno)
2551 #print "Try include: %s" % (fname)
2552 if (not os.path.exists(fname)):
2553 fname = os.path.join(os.path.split(fn)[0], par[0])
2554 #print "Try include: %s" % (fname)
2556 while not os.path.exists(fname) and (i < len(self.include_path)):
2557 fname = os.path.join(self.include_path[i], par[0])
2558 #print "Try include: %s" % (fname)
2560 if (not os.path.exists(fname)):
2562 continue # just ignore
2564 fname = par[0] # report error
2565 fnew = open(fname, "r")
2566 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import})
2567 fn, f, lineno, is_import = par[0], fnew, 0, is_imp
2568 elif result.group('name') == 'END':
2571 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
2574 if not empty.match(line):
2575 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
2577 if empty.match(line): continue
2578 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
2579 if not par: continue
2580 self.set_opt(par[0], par[1:], fn, lineno)
2581 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2582 if empty.match(line): continue
2583 if ctx == 'EXPORTS':
2584 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
2586 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2587 if not par: continue
2588 flags = default_flags
2591 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
2592 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
2593 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
2594 elif (ctx == 'EXPORTS'): p = 1
2595 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
2596 for i in range(p, len(par)):
2597 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
2598 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
2599 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
2600 elif (par[i] == 'WS_DLL'): flags |= EF_WS_DLL
2601 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
2602 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2603 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2604 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
2605 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
2606 if empty.match(line): continue
2607 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
2608 if not par: continue
2609 flags = default_flags
2610 for i in range(1, len(par)):
2611 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2612 elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT
2613 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
2614 elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE
2615 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
2616 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
2617 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2618 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
2619 elif ctx == 'USE_VALS_EXT':
2620 if empty.match(line): continue
2621 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2622 if not par: continue
2623 flags = default_flags
2624 self.add_item('USE_VALS_EXT', par[0], flag=flags, fn=fn, lineno=lineno)
2625 elif ctx in ('PDU', 'PDU_NEW'):
2626 if empty.match(line): continue
2627 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
2628 if not par: continue
2630 if (ctx == 'PDU_NEW'): is_new = True
2631 self.add_pdu(par[0:2], is_new, fn, lineno)
2633 self.add_register(par[0], par[2:5], fn, lineno)
2634 elif ctx in ('SYNTAX', 'SYNTAX_NEW'):
2635 if empty.match(line): continue
2636 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2637 if not par: continue
2638 if not self.check_item('PDU', par[0]):
2640 if (ctx == 'SYNTAX_NEW'): is_new = True
2641 self.add_pdu(par[0:1], is_new, fn, lineno)
2642 self.add_syntax(par, fn, lineno)
2643 elif ctx in ('REGISTER', 'REGISTER_NEW'):
2644 if empty.match(line): continue
2645 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
2646 if not par: continue
2647 if not self.check_item('PDU', par[0]):
2649 if (ctx == 'REGISTER_NEW'): is_new = True
2650 self.add_pdu(par[0:1], is_new, fn, lineno)
2651 self.add_register(par[0], par[1:4], fn, lineno)
2652 elif ctx in ('MODULE', 'MODULE_IMPORT'):
2653 if empty.match(line): continue
2654 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2655 if not par: continue
2656 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
2657 elif ctx == 'IMPORT_TAG':
2658 if empty.match(line): continue
2659 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
2660 if not par: continue
2661 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
2662 elif ctx == 'OMIT_ASSIGNMENT':
2663 if empty.match(line): continue
2664 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2665 if not par: continue
2666 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
2667 elif ctx == 'NO_OMIT_ASSGN':
2668 if empty.match(line): continue
2669 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2670 if not par: continue
2671 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
2672 elif ctx == 'VIRTUAL_ASSGN':
2673 if empty.match(line): continue
2674 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
2675 if not par: continue
2676 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
2677 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
2678 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
2680 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
2681 if not par[0][0].isupper():
2682 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
2683 UserWarning, fn, lineno)
2684 elif ctx == 'SET_TYPE':
2685 if empty.match(line): continue
2686 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2687 if not par: continue
2688 if not self.check_item('VIRTUAL_ASSGN', par[0]):
2689 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
2690 if not par[1][0].isupper():
2691 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
2692 UserWarning, fn, lineno)
2693 elif ctx == 'ASSIGN_VALUE_TO_TYPE':
2694 if empty.match(line): continue
2695 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2696 if not par: continue
2697 self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno)
2698 elif ctx == 'TYPE_RENAME':
2699 if empty.match(line): continue
2700 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2701 if not par: continue
2702 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2703 if not par[1][0].isupper():
2704 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2705 UserWarning, fn, lineno)
2706 elif ctx == 'FIELD_RENAME':
2707 if empty.match(line): continue
2708 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2709 if not par: continue
2710 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2711 if not par[1][0].islower():
2712 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2713 UserWarning, fn, lineno)
2714 elif ctx == 'TF_RENAME':
2715 if empty.match(line): continue
2716 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2717 if not par: continue
2718 tmpu = par[1][0].upper() + par[1][1:]
2719 tmpl = par[1][0].lower() + par[1][1:]
2720 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
2721 if not tmpu[0].isupper():
2722 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2723 UserWarning, fn, lineno)
2724 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
2725 if not tmpl[0].islower():
2726 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2727 UserWarning, fn, lineno)
2728 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2729 if empty.match(line): continue
2730 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2731 if not par: continue
2732 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
2733 elif ctx == 'FN_PARS':
2734 if empty.match(line): continue
2736 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
2738 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2739 if not par: continue
2741 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
2743 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2744 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2745 result = cdirective.search(line)
2746 if result: # directive
2747 line = '#' + line[result.end():]
2748 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
2749 elif ctx == 'CLASS':
2750 if empty.match(line): continue
2751 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
2752 if not par: continue
2753 if not set_type_to_class(name, par[0], par[1:]):
2754 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
2755 UserWarning, fn, lineno)
2756 elif ctx == 'TABLE':
2757 self.report[name][-1]['text'] += line
2759 def set_opt(self, opt, par, fn, lineno):
2760 #print "set_opt: %s, %s" % (opt, par)
2762 par = self.check_par(par, 1, 1, fn, lineno)
2764 self.include_path.append(par[0])
2765 elif opt in ("-b", "BER", "CER", "DER"):
2766 par = self.check_par(par, 0, 0, fn, lineno)
2767 self.ectx.encoding = 'ber'
2768 elif opt in ("PER",):
2769 par = self.check_par(par, 0, 0, fn, lineno)
2770 self.ectx.encoding = 'per'
2771 elif opt in ("-p", "PROTO"):
2772 par = self.check_par(par, 1, 1, fn, lineno)
2774 self.ectx.proto_opt = par[0]
2775 self.ectx.merge_modules = True
2776 elif opt in ("ALIGNED",):
2777 par = self.check_par(par, 0, 0, fn, lineno)
2778 self.ectx.aligned = True
2779 elif opt in ("-u", "UNALIGNED"):
2780 par = self.check_par(par, 0, 0, fn, lineno)
2781 self.ectx.aligned = False
2782 elif opt in ("-d",):
2783 par = self.check_par(par, 1, 1, fn, lineno)
2785 self.ectx.dbgopt = par[0]
2786 elif opt in ("-e",):
2787 par = self.check_par(par, 0, 0, fn, lineno)
2788 self.ectx.expcnf = True
2789 elif opt in ("-S",):
2790 par = self.check_par(par, 0, 0, fn, lineno)
2791 self.ectx.merge_modules = True
2792 elif opt in ("GROUP_BY_PROT",):
2793 par = self.check_par(par, 0, 0, fn, lineno)
2794 self.ectx.group_by_prot = True
2795 elif opt in ("-o",):
2796 par = self.check_par(par, 1, 1, fn, lineno)
2798 self.ectx.outnm_opt = par[0]
2799 elif opt in ("-O",):
2800 par = self.check_par(par, 1, 1, fn, lineno)
2802 self.ectx.output.outdir = par[0]
2803 elif opt in ("-s",):
2804 par = self.check_par(par, 1, 1, fn, lineno)
2806 self.ectx.output.single_file = par[0]
2807 elif opt in ("-k",):
2808 par = self.check_par(par, 0, 0, fn, lineno)
2809 self.ectx.output.keep = True
2810 elif opt in ("-L",):
2811 par = self.check_par(par, 0, 0, fn, lineno)
2812 self.suppress_line = True
2813 elif opt in ("EMBEDDED_PDV_CB",):
2814 par = self.check_par(par, 1, 1, fn, lineno)
2816 self.ectx.default_embedded_pdv_cb = par[0]
2817 elif opt in ("EXTERNAL_TYPE_CB",):
2818 par = self.check_par(par, 1, 1, fn, lineno)
2820 self.ectx.default_external_type_cb = par[0]
2821 elif opt in ("-r",):
2822 par = self.check_par(par, 1, 1, fn, lineno)
2824 self.ectx.remove_prefix = par[0]
2826 warnings.warn_explicit("Unknown option %s" % (opt),
2827 UserWarning, fn, lineno)
2829 def dbg_print(self):
2830 print("\n# Conformance values")
2831 print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value"))
2833 tbls = sorted(self.table.keys())
2835 keys = sorted(self.table[t].keys())
2837 print("%-15s %4s %-15s %-20s %s" % (
2838 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']])))
2840 def unused_report(self):
2841 tbls = sorted(self.table.keys())
2843 if not self.tblcfg[t]['chk_use']: continue
2844 keys = sorted(self.table[t].keys())
2846 if not self.table[t][k]['used']:
2847 warnings.warn_explicit("Unused %s for %s" % (t, k),
2848 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2849 fnms = list(self.fn.keys())
2852 keys = sorted(self.fn[f].keys())
2854 if not self.fn[f][k]: continue
2855 if not self.fn[f][k]['used']:
2856 warnings.warn_explicit("Unused %s for %s" % (k, f),
2857 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2859 #--- EthOut -------------------------------------------------------------------
2865 self.single_file = None
2866 self.created_files = {}
2867 self.created_files_ord = []
2870 def outcomment(self, ln, comment=None):
2872 return '%s %s\n' % (comment, ln)
2874 return '/* %-74s */\n' % (ln)
2876 def created_file_add(self, name, keep_anyway):
2877 name = os.path.normcase(os.path.abspath(name))
2878 if name not in self.created_files:
2879 self.created_files_ord.append(name)
2880 self.created_files[name] = keep_anyway
2882 self.created_files[name] = self.created_files[name] or keep_anyway
2884 def created_file_exists(self, name):
2885 name = os.path.normcase(os.path.abspath(name))
2886 return name in self.created_files
2888 #--- output_fname -------------------------------------------------------
2889 def output_fname(self, ftype, ext='c'):
2891 if not ext in ('cnf',):
2898 #--- file_open -------------------------------------------------------
2899 def file_open(self, ftype, ext='c'):
2900 fn = self.output_fname(ftype, ext=ext)
2901 if self.created_file_exists(fn):
2908 fx.write(self.fhdr(fn, comment = comment))
2910 if (not self.single_file and not self.created_file_exists(fn)):
2911 fx.write(self.fhdr(fn))
2912 if not self.ectx.merge_modules:
2915 if self.ectx.groups():
2917 if (len(self.ectx.modules) > 1):
2919 for (m, p) in self.ectx.modules:
2922 mstr += "Module %s" % (self.ectx.Module())
2923 mstr += " --- --- ---"
2924 fx.write(self.outcomment(mstr, comment))
2927 #--- file_close -------------------------------------------------------
2928 def file_close(self, fx, discard=False, keep_anyway=False):
2930 if discard and not self.created_file_exists(fx.name):
2933 self.created_file_add(fx.name, keep_anyway)
2934 #--- fhdr -------------------------------------------------------
2935 def fhdr(self, fn, comment=None):
2937 out += self.outcomment('Do not modify this file. Changes will be overwritten.', comment)
2938 out += self.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment)
2939 out += self.outcomment(os.path.basename(fn), comment)
2940 out += self.outcomment(' '.join(sys.argv), comment)
2942 # Make Windows path separator look like Unix path separator
2943 out = out.replace('\\', '/')
2944 # Change absolute paths and relative paths generated outside
2945 # source directory to paths relative to asn1/<proto> subdir.
2946 out = re.sub(r'(\s)[./]\S*(/tools/|/epan/)', r'\1../..\2', out)
2947 out = re.sub(r'(\s)[./]\S*/asn1/\S*?([\s/])', r'\1.\2', out)
2950 #--- dbg_print -------------------------------------------------------
2951 def dbg_print(self):
2952 print("\n# Output files")
2953 print("\n".join(self.created_files_ord))
2956 #--- make_single_file -------------------------------------------------------
2957 def make_single_file(self):
2958 if (not self.single_file): return
2959 in_nm = self.single_file + '.c'
2960 out_nm = os.path.join(self.outdir, self.output_fname(''))
2961 self.do_include(out_nm, in_nm)
2962 in_nm = self.single_file + '.h'
2963 if (os.path.exists(in_nm)):
2964 out_nm = os.path.join(self.outdir, self.output_fname('', ext='h'))
2965 self.do_include(out_nm, in_nm)
2967 for fn in self.created_files_ord:
2968 if not self.created_files[fn]:
2971 #--- do_include -------------------------------------------------------
2972 def do_include(self, out_nm, in_nm):
2973 def check_file(fn, fnlist):
2974 fnfull = os.path.normcase(os.path.abspath(fn))
2975 if (fnfull in fnlist and os.path.exists(fnfull)):
2976 return os.path.normpath(fn)
2978 fin = open(in_nm, "r")
2979 fout = open(out_nm, "w")
2980 fout.write(self.fhdr(out_nm))
2981 fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n')
2983 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm)))
2985 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2990 cont_linenum = cont_linenum + 1;
2991 line = fin.readline()
2992 if (line == ''): break
2994 result = include.search(line)
2995 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2997 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2999 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
3001 ifile = check_file(result.group('fname'), self.created_files)
3004 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
3005 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile)))
3006 finc = open(ifile, "r")
3007 fout.write(finc.read())
3009 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
3010 fout.write('#line %u "%s"\n' % (cont_linenum+1, rel_dissector_path(in_nm)) )
3019 #--- Node ---------------------------------------------------------------------
3021 def __init__(self,*args, **kw):
3023 self.type = self.__class__.__name__
3025 assert (len(args) == 1)
3027 self.__dict__.update (kw)
3028 def str_child (self, key, child, depth):
3029 indent = " " * (2 * depth)
3030 keystr = indent + key + ": "
3031 if key == 'type': # already processed in str_depth
3033 if isinstance (child, Node): # ugh
3034 return keystr + "\n" + child.str_depth (depth+1)
3035 if isinstance(child, type ([])):
3038 if isinstance (x, Node):
3039 l.append (x.str_depth (depth+1))
3041 l.append (indent + " " + str(x) + "\n")
3042 return keystr + "[\n" + ''.join(l) + indent + "]\n"
3044 return keystr + str (child) + "\n"
3045 def str_depth (self, depth): # ugh
3046 indent = " " * (2 * depth)
3047 l = ["%s%s" % (indent, self.type)]
3048 l.append ("".join ([self.str_child (k_v[0], k_v[1], depth + 1) for k_v in list(self.__dict__.items ())]))
3049 return "\n".join (l)
3051 return "\n" + self.str_depth (0)
3052 def to_python (self, ctx):
3053 return self.str_depth (ctx.indent_lev)
3055 def eth_reg(self, ident, ectx):
3058 def fld_obj_repr(self, ectx):
3059 return "/* TO DO %s */" % (str(self))
3062 #--- ValueAssignment -------------------------------------------------------------
3063 class ValueAssignment (Node):
3064 def __init__(self,*args, **kw) :
3065 Node.__init__ (self,*args, **kw)
3067 def eth_reg(self, ident, ectx):
3068 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3069 ectx.eth_reg_vassign(self)
3070 ectx.eth_reg_value(self.ident, self.typ, self.val)
3072 #--- ObjectAssignment -------------------------------------------------------------
3073 class ObjectAssignment (Node):
3074 def __init__(self,*args, **kw) :
3075 Node.__init__ (self,*args, **kw)
3077 def __eq__(self, other):
3078 if self.cls != other.cls:
3080 if len(self.val) != len(other.val):
3082 for f in (list(self.val.keys())):
3083 if f not in other.val:
3085 if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
3086 if not self.val[f].fld_obj_eq(other.val[f]):
3089 if str(self.val[f]) != str(other.val[f]):
3093 def eth_reg(self, ident, ectx):
3094 def make_virtual_type(cls, field, prefix):
3095 if isinstance(self.val, str): return
3096 if field in self.val and not isinstance(self.val[field], Type_Ref):
3097 vnm = prefix + '-' + self.ident
3098 virtual_tr = Type_Ref(val = vnm)
3100 self.val[field] = virtual_tr
3101 ectx.eth_reg_assign(vnm, t, virt=True)
3102 ectx.eth_reg_type(vnm, t)
3103 t.eth_reg_sub(vnm, ectx)
3104 if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field):
3105 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))
3107 # end of make_virtual_type()
3108 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3109 self.module = ectx.Module()
3110 ectx.eth_reg_oassign(self)
3111 if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
3112 make_virtual_type(self.cls, '&Type', 'TYPE')
3113 if (self.cls == 'OPERATION'):
3114 make_virtual_type(self.cls, '&ArgumentType', 'ARG')
3115 make_virtual_type(self.cls, '&ResultType', 'RES')
3116 if (self.cls == 'ERROR'):
3117 make_virtual_type(self.cls, '&ParameterType', 'PAR')
3120 #--- Type ---------------------------------------------------------------------
3122 def __init__(self,*args, **kw) :
3126 self.named_list = None
3127 Node.__init__ (self,*args, **kw)
3130 if self.name is None :
3135 def HasConstraint(self):
3136 if self.constr is None :
3141 def HasSizeConstraint(self):
3142 return self.HasConstraint() and self.constr.IsSize()
3144 def HasValueConstraint(self):
3145 return self.HasConstraint() and self.constr.IsValue()
3147 def HasPermAlph(self):
3148 return self.HasConstraint() and self.constr.IsPermAlph()
3150 def HasContentsConstraint(self):
3151 return self.HasConstraint() and self.constr.IsContents()
3153 def HasOwnTag(self):
3154 return len(self.tags) > 0
3156 def HasImplicitTag(self, ectx):
3157 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
3159 def IndetermTag(self, ectx):
3162 def AddTag(self, tag):
3163 self.tags[0:0] = [tag]
3165 def GetTag(self, ectx):
3166 #print "GetTag(%s)\n" % self.name;
3167 if (self.HasOwnTag()):
3168 return self.tags[0].GetTag(ectx)
3170 return self.GetTTag(ectx)
3172 def GetTTag(self, ectx):
3173 print("#Unhandled GetTTag() in %s" % (self.type))
3174 print(self.str_depth(1))
3175 return ('BER_CLASS_unknown', 'TAG_unknown')
3177 def SetName(self, name):
3180 def AddConstraint(self, constr):
3181 if not self.HasConstraint():
3182 self.constr = constr
3184 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
3186 def eth_tname(self):
3187 return '#' + self.type + '_' + str(id(self))
3189 def eth_ftype(self, ectx):
3190 return ('FT_NONE', 'BASE_NONE')
3192 def eth_strings(self):
3195 def eth_omit_field(self):
3198 def eth_need_tree(self):
3201 def eth_has_vals(self):
3204 def eth_has_enum(self, tname, ectx):
3205 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
3207 def eth_need_pdu(self, ectx):
3210 def eth_named_bits(self):
3213 def eth_reg_sub(self, ident, ectx):
3216 def get_components(self, ectx):
3217 print("#Unhandled get_components() in %s" % (self.type))
3218 print(self.str_depth(1))
3221 def sel_req(self, sel, ectx):
3222 print("#Selection '%s' required for non-CHOICE type %s" % (sel, self.type))
3223 print(self.str_depth(1))
3225 def fld_obj_eq(self, other):
3226 return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
3228 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
3229 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3231 if (ectx.NeedTags() and (len(self.tags) > tstrip)):
3233 for i in range(len(self.tags)-1, tstrip-1, -1):
3234 tagged_type = TaggedType(val=tagged_type, tstrip=i)
3235 tagged_type.AddTag(self.tags[i])
3236 if not tagflag: # 1st tagged level
3237 if self.IsNamed() and not selflag:
3238 tagged_type.SetName(self.name)
3239 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
3242 if ident and self.IsNamed() and not tagflag and not selflag:
3243 nm = ident + '/' + self.name
3246 elif self.IsNamed():
3248 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
3249 if not ident: # Assignment
3250 ectx.eth_reg_assign(nm, self)
3251 if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx):
3252 ectx.eth_reg_type(nm, self)
3253 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
3254 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
3255 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
3256 if ectx.conform.check_item('SET_TYPE', nm):
3257 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
3259 ectx.eth_reg_type(nm, self) # new type
3261 elif ectx.conform.check_item('SET_TYPE', nm):
3262 trnm = ectx.conform.use_item('SET_TYPE', nm)
3263 elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx):
3264 ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints
3269 ectx.eth_reg_type(nm, self)
3271 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
3272 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
3273 ectx.eth_reg_assign(vnm, self, virt=True)
3274 ectx.eth_reg_type(vnm, self)
3275 self.eth_reg_sub(vnm, ectx)
3276 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
3277 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
3278 if ident and not tagflag and not self.eth_omit_field():
3279 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
3280 if ectx.conform.check_item('SET_TYPE', nm):
3281 virtual_tr.eth_reg_sub(nm, ectx)
3283 self.eth_reg_sub(nm, ectx)
3285 def eth_get_size_constr(self, ectx):
3286 (minv, maxv, ext) = ('MIN', 'MAX', False)
3287 if self.HasSizeConstraint():
3288 if self.constr.IsSize():
3289 (minv, maxv, ext) = self.constr.GetSize(ectx)
3290 if (self.constr.type == 'Intersection'):
3291 if self.constr.subtype[0].IsSize():
3292 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
3293 elif self.constr.subtype[1].IsSize():
3294 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
3295 if minv == 'MIN': minv = 'NO_BOUND'
3296 if maxv == 'MAX': maxv = 'NO_BOUND'
3297 if (ext): ext = 'TRUE'
3299 return (minv, maxv, ext)
3301 def eth_get_value_constr(self, ectx):
3302 (minv, maxv, ext) = ('MIN', 'MAX', False)
3303 if self.HasValueConstraint():
3304 (minv, maxv, ext) = self.constr.GetValue(ectx)
3305 if minv == 'MIN': minv = 'NO_BOUND'
3306 if maxv == 'MAX': maxv = 'NO_BOUND'
3307 if str(minv).isdigit():
3309 elif (str(minv)[0] == "-") and str(minv)[1:].isdigit():
3310 if (int(minv) == -(2**31)):
3312 elif (int(minv) < -(2**31)):
3313 minv = "G_GINT64_CONSTANT(%s)" % (str(minv))
3314 if str(maxv).isdigit():
3315 if (int(maxv) >= 2**32):
3316 maxv = "G_GUINT64_CONSTANT(%s)" % (str(maxv))
3319 if (ext): ext = 'TRUE'
3321 return (minv, maxv, ext)
3323 def eth_get_alphabet_constr(self, ectx):
3324 (alph, alphlen) = ('NULL', '0')
3325 if self.HasPermAlph():
3326 alph = self.constr.GetPermAlph(ectx)
3329 if (alph != 'NULL'):
3330 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
3331 alphlen = str(len(alph) - 2)
3333 alphlen = 'strlen(%s)' % (alph)
3334 return (alph, alphlen)
3336 def eth_type_vals(self, tname, ectx):
3337 if self.eth_has_vals():
3338 print("#Unhandled eth_type_vals('%s') in %s" % (tname, self.type))
3339 print(self.str_depth(1))
3342 def eth_type_enum(self, tname, ectx):
3343 if self.eth_has_enum(tname, ectx):
3344 print("#Unhandled eth_type_enum('%s') in %s" % (tname, self.type))
3345 print(self.str_depth(1))
3348 def eth_type_default_table(self, ectx, tname):
3351 def eth_type_default_body(self, ectx):
3352 print("#Unhandled eth_type_default_body() in %s" % (self.type))
3353 print(self.str_depth(1))
3356 def eth_type_default_pars(self, ectx, tname):
3363 'OFFSET' : 'offset',
3365 'HF_INDEX' : 'hf_index',
3367 'IMPLICIT_TAG' : 'implicit_tag',
3369 if (ectx.eth_type[tname]['tree']):
3370 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
3371 if (ectx.merge_modules):
3374 pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
3377 def eth_type_fn(self, proto, tname, ectx):
3378 body = self.eth_type_default_body(ectx, tname)
3379 pars = self.eth_type_default_pars(ectx, tname)
3380 if ectx.conform.check_item('FN_PARS', tname):
3381 pars.update(ectx.conform.use_item('FN_PARS', tname))
3382 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
3383 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
3384 pars['DEFAULT_BODY'] = body
3386 for k in list(pars.keys()):
3388 pars[k] = pars[k] % pars
3389 except (ValueError,TypeError):
3390 raise sys.exc_info()[0]("%s\n%s" % (str(pars), sys.exc_info()[1]))
3392 out += self.eth_type_default_table(ectx, tname) % pars
3393 out += ectx.eth_type_fn_hdr(tname)
3394 out += ectx.eth_type_fn_body(tname, body, pars=pars)
3395 out += ectx.eth_type_fn_ftr(tname)
3398 #--- Value --------------------------------------------------------------------
3400 def __init__(self,*args, **kw) :
3402 Node.__init__ (self,*args, **kw)
3404 def SetName(self, name) :
3407 def to_str(self, ectx):
3408 return str(self.val)
3413 def fld_obj_repr(self, ectx):
3414 return self.to_str(ectx)
3416 #--- Value_Ref -----------------------------------------------------------------
3417 class Value_Ref (Value):
3418 def to_str(self, ectx):
3419 return asn2c(self.val)
3421 #--- ObjectClass ---------------------------------------------------------------------
3422 class ObjectClass (Node):
3423 def __init__(self,*args, **kw) :
3425 Node.__init__ (self,*args, **kw)
3427 def SetName(self, name):
3429 add_class_ident(self.name)
3431 def eth_reg(self, ident, ectx):
3432 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
3433 ectx.eth_reg_objectclass(self.name, self)
3435 #--- Class_Ref -----------------------------------------------------------------
3436 class Class_Ref (ObjectClass):
3439 #--- ObjectClassDefn ---------------------------------------------------------------------
3440 class ObjectClassDefn (ObjectClass):
3441 def reg_types(self):
3442 for fld in self.fields:
3443 repr = fld.fld_repr()
3444 set_type_to_class(self.name, repr[0], repr[1:])
3447 #--- Tag ---------------------------------------------------------------
3449 def to_python (self, ctx):
3450 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
3453 self.typ.to_python (ctx))
3454 def IsImplicit(self, ectx):
3455 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def != 'EXPLICIT')))
3457 def GetTag(self, ectx):
3459 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
3460 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
3461 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
3462 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
3463 return (tc, self.num)
3465 def eth_tname(self):
3467 if (self.cls == 'UNIVERSAL'): n = 'U'
3468 elif (self.cls == 'APPLICATION'): n = 'A'
3469 elif (self.cls == 'CONTEXT'): n = 'C'
3470 elif (self.cls == 'PRIVATE'): n = 'P'
3471 return n + str(self.num)
3473 #--- Constraint ---------------------------------------------------------------
3475 class Constraint (Node):
3476 def to_python (self, ctx):
3477 print("Ignoring constraint:", self.type)
3478 return self.subtype.typ.to_python (ctx)
3480 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
3482 def eth_tname(self):
3483 return '#' + self.type + '_' + str(id(self))
3486 return (self.type == 'Size' and self.subtype.IsValue()) \
3487 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
3489 def GetSize(self, ectx):
3490 (minv, maxv, ext) = ('MIN', 'MAX', False)
3492 if self.type == 'Size':
3493 (minv, maxv, ext) = self.subtype.GetValue(ectx)
3494 elif self.type == 'Intersection':
3495 if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
3496 (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
3497 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
3498 (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
3499 return (minv, maxv, ext)
3502 return self.type == 'SingleValue' \
3503 or self.type == 'ValueRange' \
3504 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
3505 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
3507 def GetValue(self, ectx):
3508 (minv, maxv, ext) = ('MIN', 'MAX', False)
3510 if self.type == 'SingleValue':
3511 minv = ectx.value_get_eth(self.subtype)
3512 maxv = ectx.value_get_eth(self.subtype)
3513 ext = hasattr(self, 'ext') and self.ext
3514 elif self.type == 'ValueRange':
3515 minv = ectx.value_get_eth(self.subtype[0])
3516 maxv = ectx.value_get_eth(self.subtype[1])
3517 ext = hasattr(self, 'ext') and self.ext
3518 elif self.type == 'Intersection':
3519 if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
3520 (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
3521 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
3522 (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
3523 elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
3524 v0 = self.subtype[0].GetValue(ectx)
3525 v1 = self.subtype[1].GetValue(ectx)
3526 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
3527 elif self.type == 'Union':
3528 if self.subtype[0].IsValue() and self.subtype[1].IsValue():
3529 v0 = self.subtype[0].GetValue(ectx)
3530 v1 = self.subtype[1].GetValue(ectx)
3531 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
3532 return (minv, maxv, ext)
3534 def IsAlphabet(self):
3535 return self.type == 'SingleValue' \
3536 or self.type == 'ValueRange' \
3537 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
3538 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
3540 def GetAlphabet(self, ectx):
3542 if self.IsAlphabet():
3543 if self.type == 'SingleValue':
3544 alph = ectx.value_get_eth(self.subtype)
3545 elif self.type == 'ValueRange':
3546 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
3547 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
3549 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
3552 elif self.type == 'Union':
3553 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
3554 a0 = self.subtype[0].GetAlphabet(ectx)
3555 a1 = self.subtype[1].GetAlphabet(ectx)
3556 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
3557 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
3558 alph = '"' + a0[1:-1] + a1[1:-1] + '"'
3560 alph = a0 + ' ' + a1
3563 def IsPermAlph(self):
3564 return self.type == 'From' and self.subtype.IsAlphabet() \
3565 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
3567 def GetPermAlph(self, ectx):
3569 if self.IsPermAlph():
3570 if self.type == 'From':
3571 alph = self.subtype.GetAlphabet(ectx)
3572 elif self.type == 'Intersection':
3573 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
3574 alph = self.subtype[0].GetPermAlph(ectx)
3575 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
3576 alph = self.subtype[1].GetPermAlph(ectx)
3579 def IsContents(self):
3580 return self.type == 'Contents' \
3581 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
3583 def GetContents(self, ectx):
3585 if self.IsContents():
3586 if self.type == 'Contents':
3587 if self.subtype.type == 'Type_Ref':
3588 contents = self.subtype.val
3589 elif self.type == 'Intersection':
3590 if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
3591 contents = self.subtype[0].GetContents(ectx)
3592 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
3593 contents = self.subtype[1].GetContents(ectx)
3596 def IsNegativ(self):
3598 return isinstance(sval, str) and (sval[0] == '-')
3599 if self.type == 'SingleValue':
3600 return is_neg(self.subtype)
3601 elif self.type == 'ValueRange':
3602 if self.subtype[0] == 'MIN': return True
3603 return is_neg(self.subtype[0])
3606 def eth_constrname(self):
3608 if isinstance(val, Value_Ref):
3609 return asn2c(val.val)
3612 return 'M' + str(-int(val))
3614 return str(int(val))
3615 except (ValueError, TypeError):
3616 return asn2c(str(val))
3619 if hasattr(self, 'ext') and self.ext:
3621 if self.type == 'SingleValue':
3622 return int2str(self.subtype) + ext
3623 elif self.type == 'ValueRange':
3624 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
3625 elif self.type == 'Size':
3626 return 'SIZE_' + self.subtype.eth_constrname() + ext
3628 if (not hasattr(self, 'constr_num')):
3631 self.constr_num = constr_cnt
3632 return 'CONSTR%03d%s' % (self.constr_num, ext)
3634 def Needs64b(self, ectx):
3635 (minv, maxv, ext) = self.GetValue(ectx)
3636 if (str(minv).isdigit() or ((str(minv)[0] == "-") and str(minv)[1:].isdigit())) \
3637 and str(maxv).isdigit() and (abs(int(maxv) - int(minv)) >= 2**32):
3641 class Module (Node):
3642 def to_python (self, ctx):
3643 ctx.tag_def = self.tag_def.dfl_tag
3645 %s""" % (self.ident, self.body.to_python (ctx))
3648 return self.ident.val
3650 def get_proto(self, ectx):
3654 prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name())
3657 def to_eth(self, ectx):
3658 ectx.tags_def = 'EXPLICIT' # default = explicit
3659 ectx.proto = self.get_proto(ectx)
3660 ectx.tag_def = self.tag_def.dfl_tag
3661 ectx.eth_reg_module(self)
3662 self.body.to_eth(ectx)
3664 class Module_Body (Node):
3665 def to_python (self, ctx):
3666 # XXX handle exports, imports.
3667 l = [x.to_python (ctx) for x in self.assign_list]
3668 l = [a for a in l if a != '']
3669 return "\n".join (l)
3671 def to_eth(self, ectx):
3673 ectx.eth_exports(self.exports)
3675 for i in self.imports:
3677 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
3678 ectx.eth_module_dep_add(ectx.Module(), mod)
3679 for s in i.symbol_list:
3680 if isinstance(s, Type_Ref):
3681 ectx.eth_import_type(s.val, mod, proto)
3682 elif isinstance(s, Value_Ref):
3683 ectx.eth_import_value(s.val, mod, proto)
3684 elif isinstance(s, Class_Ref):
3685 ectx.eth_import_class(s.val, mod, proto)
3687 msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
3688 warnings.warn_explicit(msg, UserWarning, '', 0)
3690 for a in self.assign_list:
3693 class Default_Tags (Node):
3694 def to_python (self, ctx): # not to be used directly
3697 # XXX should just calculate dependencies as we go along.
3698 def calc_dependencies (node, dict, trace = 0):
3699 if not hasattr (node, '__dict__'):
3700 if trace: print("#returning, node=", node)
3702 if isinstance (node, Type_Ref):
3704 if trace: print("#Setting", node.val)
3706 for (a, val) in list(node.__dict__.items ()):
3707 if trace: print("# Testing node ", node, "attr", a, " val", val)
3710 elif isinstance (val, Node):
3711 calc_dependencies (val, dict, trace)
3712 elif isinstance (val, type ([])):
3714 calc_dependencies (v, dict, trace)
3717 class Type_Assign (Node):
3718 def __init__ (self, *args, **kw):
3719 Node.__init__ (self, *args, **kw)
3720 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3721 to_test = self.val.typ
3724 if isinstance (to_test, SequenceType):
3725 to_test.sequence_name = self.name.name
3727 def to_python (self, ctx):
3729 calc_dependencies (self.val, dep_dict, 0)
3730 depend_list = list(dep_dict.keys ())
3731 return ctx.register_assignment (self.name.name,
3732 self.val.to_python (ctx),
3735 class PyQuote (Node):
3736 def to_python (self, ctx):
3737 return ctx.register_pyquote (self.val)
3739 #--- Type_Ref -----------------------------------------------------------------
3740 class Type_Ref (Type):
3741 def to_python (self, ctx):
3744 def eth_reg_sub(self, ident, ectx):
3745 ectx.eth_dep_add(ident, self.val)
3747 def eth_tname(self):
3748 if self.HasSizeConstraint():
3749 return asn2c(self.val) + '_' + self.constr.eth_constrname()
3751 return asn2c(self.val)
3753 def tr_need_own_fn(self, ectx):
3754 return ectx.Per() and self.HasSizeConstraint()
3756 def fld_obj_repr(self, ectx):
3759 def get_components(self, ectx):
3760 if self.val not in ectx.type or ectx.type[self.val]['import']:
3761 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
3762 warnings.warn_explicit(msg, UserWarning, '', 0)
3765 return ectx.type[self.val]['val'].get_components(ectx)
3767 def GetTTag(self, ectx):
3768 #print "GetTTag(%s)\n" % self.val;
3769 if (ectx.type[self.val]['import']):
3770 if 'ttag' not in ectx.type[self.val]:
3771 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
3772 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
3773 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
3774 warnings.warn_explicit(msg, UserWarning, '', 0)
3775 ttag = ('-1/*imported*/', '-1/*imported*/')
3776 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
3777 return ectx.type[self.val]['ttag']
3779 return ectx.type[self.val]['val'].GetTag(ectx)
3781 def IndetermTag(self, ectx):
3782 if (ectx.type[self.val]['import']):
3785 return ectx.type[self.val]['val'].IndetermTag(ectx)
3787 def eth_type_default_pars(self, ectx, tname):
3789 pars = Type.eth_type_default_pars(self, ectx, tname)
3792 t = ectx.type[self.val]['ethname']
3793 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3794 pars['TYPE_REF_TNAME'] = t
3795 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3796 if self.HasSizeConstraint():
3797 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3800 def eth_type_default_body(self, ectx, tname):
3802 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3803 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3805 if self.HasSizeConstraint():
3806 body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset',
3807 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3808 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3810 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3811 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3813 body = '#error Can not decode %s' % (tname)
3816 #--- SelectionType ------------------------------------------------------------
3817 class SelectionType (Type):
3818 def to_python (self, ctx):
3821 def sel_of_typeref(self):
3822 return self.typ.type == 'Type_Ref'
3824 def eth_reg_sub(self, ident, ectx):
3825 if not self.sel_of_typeref():
3828 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
3829 ectx.eth_dep_add(ident, self.seltype)
3831 def eth_ftype(self, ectx):
3832 (ftype, display) = ('FT_NONE', 'BASE_NONE')
3833 if self.sel_of_typeref() and not ectx.type[self.seltype]['import']:
3834 (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx)
3835 return (ftype, display)
3837 def GetTTag(self, ectx):
3838 #print "GetTTag(%s)\n" % self.seltype;
3839 if (ectx.type[self.seltype]['import']):
3840 if 'ttag' not in ectx.type[self.seltype]:
3841 if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
3842 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
3843 warnings.warn_explicit(msg, UserWarning, '', 0)
3844 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
3845 return ectx.type[self.seltype]['ttag']
3847 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
3849 def eth_type_default_pars(self, ectx, tname):
3850 pars = Type.eth_type_default_pars(self, ectx, tname)
3851 if self.sel_of_typeref():
3852 t = ectx.type[self.seltype]['ethname']
3853 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3854 pars['TYPE_REF_TNAME'] = t
3855 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3858 def eth_type_default_body(self, ectx, tname):
3859 if not self.sel_of_typeref():
3860 body = '#error Can not decode %s' % (tname)
3862 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3863 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3865 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3866 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3868 body = '#error Can not decode %s' % (tname)
3871 #--- TaggedType -----------------------------------------------------------------
3872 class TaggedType (Type):
3873 def eth_tname(self):
3875 for i in range(self.tstrip, len(self.val.tags)):
3876 tn += self.val.tags[i].eth_tname()
3878 tn += self.val.eth_tname()
3881 def eth_set_val_name(self, ident, val_name, ectx):
3882 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3883 self.val_name = val_name
3884 ectx.eth_dep_add(ident, self.val_name)
3886 def eth_reg_sub(self, ident, ectx):
3887 self.val_name = ident + '/' + UNTAG_TYPE_NAME
3888 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
3890 def GetTTag(self, ectx):
3891 #print "GetTTag(%s)\n" % self.seltype;
3892 return self.GetTag(ectx)
3894 def eth_ftype(self, ectx):
3895 return self.val.eth_ftype(ectx)
3897 def eth_type_default_pars(self, ectx, tname):
3898 pars = Type.eth_type_default_pars(self, ectx, tname)
3899 t = ectx.type[self.val_name]['ethname']
3900 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3901 pars['TYPE_REF_TNAME'] = t
3902 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3903 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
3904 if self.HasImplicitTag(ectx):
3905 pars['TAG_IMPL'] = 'TRUE'
3907 pars['TAG_IMPL'] = 'FALSE'
3910 def eth_type_default_body(self, ectx, tname):
3912 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
3913 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3914 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
3916 body = '#error Can not decode %s' % (tname)
3919 #--- SqType -----------------------------------------------------------
3920 class SqType (Type):
3921 def out_item(self, f, val, optional, ext, ectx):
3922 if (val.eth_omit_field()):
3923 t = ectx.type[val.ident]['ethname']
3924 fullname = ectx.dummy_eag_field
3926 ef = ectx.field[f]['ethname']
3927 t = ectx.eth_hf[ef]['ethtype']
3928 fullname = ectx.eth_hf[ef]['fullname']
3930 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
3931 #print val.str_depth(1)
3934 opt = 'BER_FLAGS_OPTIONAL'
3935 if (not val.HasOwnTag()):
3936 if (opt): opt += '|'
3937 opt += 'BER_FLAGS_NOOWNTAG'
3938 elif (val.HasImplicitTag(ectx)):
3939 if (opt): opt += '|'
3940 opt += 'BER_FLAGS_IMPLTAG'
3941 if (val.IndetermTag(ectx)):
3942 if (opt): opt += '|'
3943 opt += 'BER_FLAGS_NOTCHKTAG'
3944 if (not opt): opt = '0'
3947 opt = 'ASN1_OPTIONAL'
3949 opt = 'ASN1_NOT_OPTIONAL'
3951 (tc, tn) = val.GetTag(ectx)
3952 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3953 % ('&'+fullname, tc, tn, opt, ectx.eth_type[t]['proto'], t)
3955 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
3956 % ('&'+fullname, ext, opt, ectx.eth_type[t]['proto'], t)
3961 #--- SeqType -----------------------------------------------------------
3962 class SeqType (SqType):
3964 def all_components(self):
3965 lst = self.elt_list[:]
3966 if hasattr(self, 'ext_list'):
3967 lst.extend(self.ext_list)
3968 if hasattr(self, 'elt_list2'):
3969 lst.extend(self.elt_list2)
3972 def need_components(self):
3973 lst = self.all_components()
3975 if e.type == 'components_of':
3979 def expand_components(self, ectx):
3980 while self.need_components():
3981 for i in range(len(self.elt_list)):
3982 if self.elt_list[i].type == 'components_of':
3983 comp = self.elt_list[i].typ.get_components(ectx)
3984 self.elt_list[i:i+1] = comp
3986 if hasattr(self, 'ext_list'):
3987 for i in range(len(self.ext_list)):
3988 if self.ext_list[i].type == 'components_of':
3989 comp = self.ext_list[i].typ.get_components(ectx)
3990 self.ext_list[i:i+1] = comp
3992 if hasattr(self, 'elt_list2'):
3993 for i in range(len(self.elt_list2)):
3994 if self.elt_list2[i].type == 'components_of':
3995 comp = self.elt_list2[i].typ.get_components(ectx)
3996 self.elt_list2[i:i+1] = comp
3999 def get_components(self, ectx):
4000 lst = self.elt_list[:]
4001 if hasattr(self, 'elt_list2'):
4002 lst.extend(self.elt_list2)
4005 def eth_reg_sub(self, ident, ectx, components_available=False):
4006 # check if autotag is required
4008 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
4010 lst = self.all_components()
4011 for e in (self.elt_list):
4012 if e.val.HasOwnTag(): autotag = False; break;
4013 # expand COMPONENTS OF
4014 if self.need_components():
4015 if components_available:
4016 self.expand_components(ectx)
4018 ectx.eth_comp_req(ident)
4020 # extension addition groups
4021 if hasattr(self, 'ext_list'):
4022 if (ectx.Per()): # add names
4024 for e in (self.ext_list):
4025 if isinstance(e.val, ExtensionAdditionGroup):
4026 e.val.parent_ident = ident
4027 e.val.parent_tname = ectx.type[ident]['tname']
4029 e.val.SetName("eag_v%s" % (e.val.ver))
4031 e.val.SetName("eag_%d" % (eag_num))
4035 for e in (self.ext_list):
4036 if isinstance(e.val, ExtensionAdditionGroup):
4037 new_ext_list.extend(e.val.elt_list)
4039 new_ext_list.append(e)
4040 self.ext_list = new_ext_list
4044 for e in (self.elt_list):
4045 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4047 if autotag and hasattr(self, 'elt_list2'):
4048 for e in (self.elt_list2):
4049 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4051 if autotag and hasattr(self, 'ext_list'):
4052 for e in (self.ext_list):
4053 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4055 # register components
4056 for e in (self.elt_list):
4057 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4058 if hasattr(self, 'ext_list'):
4059 for e in (self.ext_list):
4060 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4061 if hasattr(self, 'elt_list2'):
4062 for e in (self.elt_list2):
4063 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4065 def eth_type_default_table(self, ectx, tname):
4066 #print "eth_type_default_table(tname='%s')" % (tname)
4067 fname = ectx.eth_type[tname]['ref'][0]
4068 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
4069 if hasattr(self, 'ext_list'):
4070 ext = 'ASN1_EXTENSION_ROOT'
4072 ext = 'ASN1_NO_EXTENSIONS'
4073 empty_ext_flag = '0'
4074 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)):
4075 empty_ext_flag = ext
4076 for e in (self.elt_list):
4077 f = fname + '/' + e.val.name
4078 table += self.out_item(f, e.val, e.optional, ext, ectx)
4079 if hasattr(self, 'ext_list'):
4080 for e in (self.ext_list):
4081 f = fname + '/' + e.val.name
4082 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4083 if hasattr(self, 'elt_list2'):
4084 for e in (self.elt_list2):
4085 f = fname + '/' + e.val.name
4086 table += self.out_item(f, e.val, e.optional, ext, ectx)
4088 table += " { NULL, 0, 0, 0, NULL }\n};\n"
4090 table += " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag)
4093 #--- SeqOfType -----------------------------------------------------------
4094 class SeqOfType (SqType):
4095 def eth_type_default_table(self, ectx, tname):
4096 #print "eth_type_default_table(tname='%s')" % (tname)
4097 fname = ectx.eth_type[tname]['ref'][0]
4098 if self.val.IsNamed ():
4099 f = fname + '/' + self.val.name
4101 f = fname + '/' + ITEM_FIELD_NAME
4102 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
4103 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
4107 #--- SequenceOfType -----------------------------------------------------------
4108 class SequenceOfType (SeqOfType):
4109 def to_python (self, ctx):
4110 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4111 # or '' + (1,) for optional
4113 if self.size_constr != None:
4114 print("#Ignoring size constraint:", self.size_constr.subtype)
4115 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
4116 self.val.to_python (ctx),
4119 def eth_reg_sub(self, ident, ectx):
4121 if not self.val.IsNamed ():
4122 itmnm += '/' + ITEM_FIELD_NAME
4123 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
4125 def eth_tname(self):
4126 if self.val.type != 'Type_Ref':
4127 return '#' + self.type + '_' + str(id(self))
4128 if not self.HasConstraint():
4129 return "SEQUENCE_OF_" + self.val.eth_tname()
4130 elif self.constr.IsSize():
4131 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4133 return '#' + self.type + '_' + str(id(self))
4135 def eth_ftype(self, ectx):
4136 return ('FT_UINT32', 'BASE_DEC')
4138 def eth_need_tree(self):
4141 def GetTTag(self, ectx):
4142 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4144 def eth_type_default_pars(self, ectx, tname):
4145 pars = Type.eth_type_default_pars(self, ectx, tname)
4146 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4147 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
4150 def eth_type_default_body(self, ectx, tname):
4152 if (ectx.constraints_check and self.HasSizeConstraint()):
4153 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4154 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4155 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4157 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4158 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4159 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4160 elif (ectx.Per() and not self.HasConstraint()):
4161 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4162 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4163 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4164 elif (ectx.Per() and self.constr.type == 'Size'):
4165 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4166 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4167 ('%(ETT_INDEX)s', '%(TABLE)s',),
4168 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
4170 body = '#error Can not decode %s' % (tname)
4174 #--- SetOfType ----------------------------------------------------------------
4175 class SetOfType (SeqOfType):
4176 def eth_reg_sub(self, ident, ectx):
4178 if not self.val.IsNamed ():
4179 itmnm += '/' + ITEM_FIELD_NAME
4180 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
4182 def eth_tname(self):
4183 if self.val.type != 'Type_Ref':
4184 return '#' + self.type + '_' + str(id(self))
4185 if not self.HasConstraint():
4186 return "SET_OF_" + self.val.eth_tname()
4187 elif self.constr.IsSize():
4188 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4190 return '#' + self.type + '_' + str(id(self))
4192 def eth_ftype(self, ectx):
4193 return ('FT_UINT32', 'BASE_DEC')
4195 def eth_need_tree(self):
4198 def GetTTag(self, ectx):
4199 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4201 def eth_type_default_pars(self, ectx, tname):
4202 pars = Type.eth_type_default_pars(self, ectx, tname)
4203 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4204 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
4207 def eth_type_default_body(self, ectx, tname):
4209 if (ectx.constraints_check and self.HasSizeConstraint()):
4210 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4211 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4212 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4214 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4215 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4216 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4217 elif (ectx.Per() and not self.HasConstraint()):
4218 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4219 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4220 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4221 elif (ectx.Per() and self.constr.type == 'Size'):
4222 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4223 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4224 ('%(ETT_INDEX)s', '%(TABLE)s',),
4225 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),))
4227 body = '#error Can not decode %s' % (tname)
4230 def mk_tag_str (ctx, cls, typ, num):
4232 # XXX should do conversion to int earlier!
4235 if typ == 'DEFAULT':
4237 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
4239 #--- SequenceType -------------------------------------------------------------
4240 class SequenceType (SeqType):
4241 def to_python (self, ctx):
4242 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4243 # or '' + (1,) for optional
4244 # XXX should also collect names for SEQUENCE inside SEQUENCE or
4245 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
4246 # from? for others, element or arm name would be fine)
4247 seq_name = getattr (self, 'sequence_name', None)
4248 if seq_name == None:
4251 seq_name = "'" + seq_name + "'"
4252 if 'ext_list' in self.__dict__:
4253 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
4254 self.elts_to_py (self.elt_list, ctx),
4255 self.elts_to_py (self.ext_list, ctx), seq_name)
4257 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
4258 self.elts_to_py (self.elt_list, ctx), seq_name)
4259 def elts_to_py (self, list, ctx):
4260 # we have elt_type, val= named_type, maybe default=, optional=
4261 # named_type node: either ident = or typ =
4262 # need to dismember these in order to generate Python output syntax.
4265 assert (e.type == 'elt_type')
4267 optflag = e.optional
4268 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
4269 assert (nt.type == 'named_type')
4272 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4273 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4274 nt.typ.tag.tag_typ,nt.typ.tag.num)
4278 return "('%s',%s,%s,%d)" % (identstr, tagstr,
4279 nt.typ.to_python (ctx), optflag)
4280 indentstr = ",\n" + ctx.spaces ()
4281 rv = indentstr.join ([elt_to_py (e) for e in list])
4285 def eth_need_tree(self):
4288 def GetTTag(self, ectx):
4289 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4291 def eth_type_default_pars(self, ectx, tname):
4292 pars = Type.eth_type_default_pars(self, ectx, tname)
4293 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4296 def eth_type_default_body(self, ectx, tname):
4298 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4299 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4300 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4302 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4303 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4304 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4306 body = '#error Can not decode %s' % (tname)
4309 #--- ExtensionAdditionGroup ---------------------------------------------------
4310 class ExtensionAdditionGroup (SeqType):
4311 def __init__(self,*args, **kw) :
4312 self.parent_ident = None
4313 self.parent_tname = None
4314 SeqType.__init__ (self,*args, **kw)
4316 def eth_omit_field(self):
4319 def eth_tname(self):
4320 if (self.parent_tname and self.IsNamed()):
4321 return self.parent_tname + "_" + self.name
4323 return SeqType.eth_tname(self)
4325 def eth_reg_sub(self, ident, ectx):
4326 ectx.eth_dummy_eag_field_required()
4327 ectx.eth_dep_add(self.parent_ident, ident)
4328 SeqType.eth_reg_sub(self, ident, ectx)
4330 def eth_type_default_pars(self, ectx, tname):
4331 pars = Type.eth_type_default_pars(self, ectx, tname)
4332 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4335 def eth_type_default_body(self, ectx, tname):
4337 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_eag', ret='offset',
4338 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),))
4340 body = '#error Can not decode %s' % (tname)
4344 #--- SetType ------------------------------------------------------------------
4345 class SetType (SeqType):
4347 def eth_need_tree(self):
4350 def GetTTag(self, ectx):
4351 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4353 def eth_type_default_pars(self, ectx, tname):
4354 pars = Type.eth_type_default_pars(self, ectx, tname)
4355 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4358 def eth_type_default_body(self, ectx, tname):
4360 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4361 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4362 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4364 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4365 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4366 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4368 body = '#error Can not decode %s' % (tname)
4371 #--- ChoiceType ---------------------------------------------------------------
4372 class ChoiceType (Type):
4373 def to_python (self, ctx):
4374 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4375 # or '' + (1,) for optional
4376 if 'ext_list' in self.__dict__:
4377 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
4378 self.elts_to_py (self.elt_list, ctx),
4379 self.elts_to_py (self.ext_list, ctx))
4381 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
4382 def elts_to_py (self, list, ctx):
4385 assert (nt.type == 'named_type')
4387 if hasattr (nt, 'ident'):
4390 if hasattr (nt.typ, 'val'):
4391 identstr = nt.typ.val # XXX, making up name
4392 elif hasattr (nt.typ, 'name'):
4393 identstr = nt.typ.name
4395 identstr = ctx.make_new_name ()
4397 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4398 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4399 nt.typ.tag.tag_typ,nt.typ.tag.num)
4403 return "('%s',%s,%s)" % (identstr, tagstr,
4404 nt.typ.to_python (ctx))
4405 indentstr = ",\n" + ctx.spaces ()
4406 rv = indentstr.join ([elt_to_py (e) for e in list])
4410 def eth_reg_sub(self, ident, ectx):
4411 #print "eth_reg_sub(ident='%s')" % (ident)
4412 # check if autotag is required
4414 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
4416 for e in (self.elt_list):
4417 if e.HasOwnTag(): autotag = False; break;
4418 if autotag and hasattr(self, 'ext_list'):
4419 for e in (self.ext_list):
4420 if e.HasOwnTag(): autotag = False; break;
4424 for e in (self.elt_list):
4425 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4427 if autotag and hasattr(self, 'ext_list'):
4428 for e in (self.ext_list):
4429 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4431 for e in (self.elt_list):
4432 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4433 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4434 ectx.eth_sel_req(ident, e.name)
4435 if hasattr(self, 'ext_list'):
4436 for e in (self.ext_list):
4437 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4438 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4439 ectx.eth_sel_req(ident, e.name)
4441 def sel_item(self, ident, sel, ectx):
4442 lst = self.elt_list[:]
4443 if hasattr(self, 'ext_list'):
4444 lst.extend(self.ext_list)
4446 for e in (self.elt_list):
4447 if e.IsNamed() and (e.name == sel):
4451 print("#CHOICE %s does not contain item %s" % (ident, sel))
4454 def sel_req(self, ident, sel, ectx):
4455 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4456 ee = self.sel_item(ident, sel, ectx)
4458 ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
4460 def eth_ftype(self, ectx):
4461 return ('FT_UINT32', 'BASE_DEC')
4463 def eth_ftype_sel(self, sel, ectx):
4464 ee = self.sel_item('', sel, ectx)
4466 return ee.eth_ftype(ectx)
4468 return ('FT_NONE', 'BASE_NONE')
4470 def eth_strings(self):
4473 def eth_need_tree(self):
4476 def eth_has_vals(self):
4479 def GetTTag(self, ectx):
4481 cls = 'BER_CLASS_ANY/*choice*/'
4482 #if hasattr(self, 'ext_list'):
4483 # lst.extend(self.ext_list)
4485 # cls = lst[0].GetTag(ectx)[0]
4487 # if (e.GetTag(ectx)[0] != cls):
4488 # cls = '-1/*choice*/'
4489 return (cls, '-1/*choice*/')
4491 def GetTTagSel(self, sel, ectx):
4492 ee = self.sel_item('', sel, ectx)
4494 return ee.GetTag(ectx)
4496 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4498 def IndetermTag(self, ectx):
4499 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4500 return not self.HasOwnTag()
4502 def detect_tagval(self, ectx):
4504 lst = self.elt_list[:]
4505 if hasattr(self, 'ext_list'):
4506 lst.extend(self.ext_list)
4507 if (len(lst) > 0) and (not ectx.Per() or lst[0].HasOwnTag()):
4508 t = lst[0].GetTag(ectx)[0]
4513 if (t == 'BER_CLASS_UNI'):
4516 if not ectx.Per() or e.HasOwnTag():
4517 tt = e.GetTag(ectx)[0]
4525 def get_vals(self, ectx):
4526 tagval = self.detect_tagval(ectx)
4529 for e in (self.elt_list):
4530 if (tagval): val = e.GetTag(ectx)[1]
4531 else: val = str(cnt)
4532 vals.append((val, e.name))
4534 if hasattr(self, 'ext_list'):
4535 for e in (self.ext_list):
4536 if (tagval): val = e.GetTag(ectx)[1]
4537 else: val = str(cnt)
4538 vals.append((val, e.name))
4542 def eth_type_vals(self, tname, ectx):
4544 vals = self.get_vals(ectx)
4545 out += ectx.eth_vals(tname, vals)
4548 def reg_enum_vals(self, tname, ectx):
4549 vals = self.get_vals(ectx)
4550 for (val, id) in vals:
4551 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4553 def eth_type_enum(self, tname, ectx):
4555 vals = self.get_vals(ectx)
4556 out += ectx.eth_enum(tname, vals)
4559 def eth_type_default_pars(self, ectx, tname):
4560 pars = Type.eth_type_default_pars(self, ectx, tname)
4561 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4564 def eth_type_default_table(self, ectx, tname):
4565 def out_item(val, e, ext, ectx):
4566 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
4568 vval = ectx.eth_enum_item(tname, e.name)
4571 f = fname + '/' + e.name
4572 ef = ectx.field[f]['ethname']
4573 t = ectx.eth_hf[ef]['ethtype']
4576 if (not e.HasOwnTag()):
4577 opt = 'BER_FLAGS_NOOWNTAG'
4578 elif (e.HasImplicitTag(ectx)):
4579 if (opt): opt += '|'
4580 opt += 'BER_FLAGS_IMPLTAG'
4581 if (not opt): opt = '0'
4583 (tc, tn) = e.GetTag(ectx)
4584 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4585 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
4587 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4588 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
4593 #print "eth_type_default_table(tname='%s')" % (tname)
4594 fname = ectx.eth_type[tname]['ref'][0]
4595 tagval = self.detect_tagval(ectx)
4596 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4598 if hasattr(self, 'ext_list'):
4599 ext = 'ASN1_EXTENSION_ROOT'
4601 ext = 'ASN1_NO_EXTENSIONS'
4602 empty_ext_flag = '0'
4603 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0):
4604 empty_ext_flag = ext
4605 for e in (self.elt_list):
4606 if (tagval): val = e.GetTag(ectx)[1]
4607 else: val = str(cnt)
4608 table += out_item(val, e, ext, ectx)
4610 if hasattr(self, 'ext_list'):
4611 for e in (self.ext_list):
4612 if (tagval): val = e.GetTag(ectx)[1]
4613 else: val = str(cnt)
4614 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4617 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4619 table += " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag)
4622 def eth_type_default_body(self, ectx, tname):
4624 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4625 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4626 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4629 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4630 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4631 ('%(ETT_INDEX)s', '%(TABLE)s',),
4634 body = '#error Can not decode %s' % (tname)
4637 #--- ChoiceValue ----------------------------------------------------
4638 class ChoiceValue (Value):
4639 def to_str(self, ectx):
4640 return self.val.to_str(ectx)
4642 def fld_obj_eq(self, other):
4643 return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
4645 #--- EnumeratedType -----------------------------------------------------------
4646 class EnumeratedType (Type):
4647 def to_python (self, ctx):
4648 def strify_one (named_num):
4649 return "%s=%s" % (named_num.ident, named_num.val)
4650 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
4652 def eth_ftype(self, ectx):
4653 return ('FT_UINT32', 'BASE_DEC')
4655 def eth_strings(self):
4658 def eth_has_vals(self):
4661 def GetTTag(self, ectx):
4662 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4664 def get_vals_etc(self, ectx):
4672 for e in (self.val):
4673 if e.type == 'NamedNumber':
4674 used[int(e.val)] = True
4675 for e in (self.val):
4676 if e.type == 'NamedNumber':
4679 while lastv in used:
4683 vals.append((val, e.ident))
4684 map_table.append(val)
4688 if self.ext is not None:
4689 for e in (self.ext):
4690 if e.type == 'NamedNumber':
4691 used[int(e.val)] = True
4692 for e in (self.ext):
4693 if e.type == 'NamedNumber':
4696 while lastv in used:
4700 vals.append((val, e.ident))
4701 map_table.append(val)
4706 for i in range(len(map_table)):
4707 need_map = need_map or (map_table[i] != i)
4710 return (vals, root_num, ext_num, map_table)
4712 def eth_type_vals(self, tname, ectx):
4714 vals = self.get_vals_etc(ectx)[0]
4715 out += ectx.eth_vals(tname, vals)
4718 def reg_enum_vals(self, tname, ectx):
4719 vals = self.get_vals_etc(ectx)[0]
4720 for (val, id) in vals:
4721 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4723 def eth_type_enum(self, tname, ectx):
4725 vals = self.get_vals_etc(ectx)[0]
4726 out += ectx.eth_enum(tname, vals)
4729 def eth_type_default_pars(self, ectx, tname):
4730 pars = Type.eth_type_default_pars(self, ectx, tname)
4731 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
4732 if (self.ext != None):
4736 pars['ROOT_NUM'] = str(root_num)
4738 pars['EXT_NUM'] = str(ext_num)
4740 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4742 pars['TABLE'] = 'NULL'
4745 def eth_type_default_table(self, ectx, tname):
4746 if (not ectx.Per()): return ''
4747 map_table = self.get_vals_etc(ectx)[3]
4748 if (map_table == None): return ''
4749 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4750 table += ", ".join([str(v) for v in map_table])
4754 def eth_type_default_body(self, ectx, tname):
4756 if (ectx.constraints_check and self.HasValueConstraint()):
4757 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
4758 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4759 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4761 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4762 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4765 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
4766 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4767 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4769 body = '#error Can not decode %s' % (tname)
4772 #--- EmbeddedPDVType -----------------------------------------------------------
4773 class EmbeddedPDVType (Type):
4774 def eth_tname(self):
4775 return 'EMBEDDED_PDV'
4777 def eth_ftype(self, ectx):
4778 return ('FT_NONE', 'BASE_NONE')
4780 def GetTTag(self, ectx):
4781 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4783 def eth_type_default_pars(self, ectx, tname):
4784 pars = Type.eth_type_default_pars(self, ectx, tname)
4785 if ectx.default_embedded_pdv_cb:
4786 pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb
4788 pars['TYPE_REF_FN'] = 'NULL'
4791 def eth_type_default_body(self, ectx, tname):
4793 body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset',
4794 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4796 body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset',
4797 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4799 body = '#error Can not decode %s' % (tname)
4802 #--- ExternalType -----------------------------------------------------------
4803 class ExternalType (Type):
4804 def eth_tname(self):
4807 def eth_ftype(self, ectx):
4808 return ('FT_NONE', 'BASE_NONE')
4810 def GetTTag(self, ectx):
4811 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4813 def eth_type_default_pars(self, ectx, tname):
4814 pars = Type.eth_type_default_pars(self, ectx, tname)
4815 if ectx.default_external_type_cb:
4816 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4818 pars['TYPE_REF_FN'] = 'NULL'
4821 def eth_type_default_body(self, ectx, tname):
4823 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4824 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4826 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4827 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4829 body = '#error Can not decode %s' % (tname)
4832 #--- OpenType -----------------------------------------------------------
4833 class OpenType (Type):
4834 def to_python (self, ctx):
4837 def single_type(self):
4838 if (self.HasConstraint() and
4839 self.constr.type == 'Type' and
4840 self.constr.subtype.type == 'Type_Ref'):
4841 return self.constr.subtype.val
4844 def eth_reg_sub(self, ident, ectx):
4845 t = self.single_type()
4847 ectx.eth_dep_add(ident, t)
4849 def eth_tname(self):
4850 t = self.single_type()
4852 return 'OpenType_' + t
4854 return Type.eth_tname(self)
4856 def eth_ftype(self, ectx):
4857 return ('FT_NONE', 'BASE_NONE')
4859 def GetTTag(self, ectx):
4860 return ('BER_CLASS_ANY', '0')
4862 def eth_type_default_pars(self, ectx, tname):
4863 pars = Type.eth_type_default_pars(self, ectx, tname)
4864 pars['FN_VARIANT'] = ectx.default_opentype_variant
4865 t = self.single_type()
4867 t = ectx.type[t]['ethname']
4868 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4869 pars['TYPE_REF_TNAME'] = t
4870 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4872 pars['TYPE_REF_FN'] = 'NULL'
4875 def eth_type_default_body(self, ectx, tname):
4877 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
4878 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4880 body = '#error Can not decode %s' % (tname)
4883 #--- InstanceOfType -----------------------------------------------------------
4884 class InstanceOfType (Type):
4885 def eth_tname(self):
4886 return 'INSTANCE_OF'
4888 def eth_ftype(self, ectx):
4889 return ('FT_NONE', 'BASE_NONE')
4891 def GetTTag(self, ectx):
4892 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4894 def eth_type_default_pars(self, ectx, tname):
4895 pars = Type.eth_type_default_pars(self, ectx, tname)
4896 if ectx.default_external_type_cb:
4897 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4899 pars['TYPE_REF_FN'] = 'NULL'
4902 def eth_type_default_body(self, ectx, tname):
4904 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4905 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4907 body = '#error Can not decode %s' % (tname)
4909 body = '#error Can not decode %s' % (tname)
4912 #--- AnyType -----------------------------------------------------------
4913 class AnyType (Type):
4914 def to_python (self, ctx):
4917 def eth_ftype(self, ectx):
4918 return ('FT_NONE', 'BASE_NONE')
4920 def GetTTag(self, ectx):
4921 return ('BER_CLASS_ANY', '0')
4923 def eth_type_default_body(self, ectx, tname):
4924 body = '#error Can not decode %s' % (tname)
4927 class Literal (Node):
4928 def to_python (self, ctx):
4931 #--- NullType -----------------------------------------------------------------
4932 class NullType (Type):
4933 def to_python (self, ctx):
4936 def eth_tname(self):
4939 def GetTTag(self, ectx):
4940 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
4942 def eth_type_default_body(self, ectx, tname):
4944 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4945 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4947 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4948 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4950 body = '#error Can not decode %s' % (tname)
4953 #--- NullValue ----------------------------------------------------
4954 class NullValue (Value):
4955 def to_str(self, ectx):
4958 #--- RealType -----------------------------------------------------------------
4959 class RealType (Type):
4960 def to_python (self, ctx):
4963 def eth_tname(self):
4966 def GetTTag(self, ectx):
4967 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
4969 def eth_ftype(self, ectx):
4970 return ('FT_DOUBLE', 'BASE_NONE')
4972 def eth_type_default_body(self, ectx, tname):
4974 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4975 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4978 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4979 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4981 body = '#error Can not decode %s' % (tname)
4984 #--- BooleanType --------------------------------------------------------------
4985 class BooleanType (Type):
4986 def to_python (self, ctx):
4987 return 'asn1.BOOLEAN'
4989 def eth_tname(self):
4992 def GetTTag(self, ectx):
4993 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
4995 def eth_ftype(self, ectx):
4996 return ('FT_BOOLEAN', 'BASE_NONE')
4998 def eth_type_default_body(self, ectx, tname):
5000 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
5001 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5003 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
5004 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5006 body = '#error Can not decode %s' % (tname)
5009 #--- OctetStringType ----------------------------------------------------------
5010 class OctetStringType (Type):
5011 def to_python (self, ctx):
5012 return 'asn1.OCTSTRING'
5014 def eth_tname(self):
5015 if not self.HasConstraint():
5016 return 'OCTET_STRING'
5017 elif self.constr.type == 'Size':
5018 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
5020 return '#' + self.type + '_' + str(id(self))
5022 def eth_ftype(self, ectx):
5023 return ('FT_BYTES', 'BASE_NONE')
5025 def GetTTag(self, ectx):
5026 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
5028 def eth_need_pdu(self, ectx):
5030 if self.HasContentsConstraint():
5031 t = self.constr.GetContents(ectx)
5032 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5034 'new' : ectx.default_containing_variant == '_pdu_new' }
5037 def eth_type_default_pars(self, ectx, tname):
5038 pars = Type.eth_type_default_pars(self, ectx, tname)
5039 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5040 if self.HasContentsConstraint():
5041 pars['FN_VARIANT'] = ectx.default_containing_variant
5042 t = self.constr.GetContents(ectx)
5044 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5045 t = ectx.field[t]['ethname']
5046 pars['TYPE_REF_PROTO'] = ''
5047 pars['TYPE_REF_TNAME'] = t
5048 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5050 t = ectx.type[t]['ethname']
5051 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5052 pars['TYPE_REF_TNAME'] = t
5053 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5055 pars['TYPE_REF_FN'] = 'NULL'
5058 def eth_type_default_body(self, ectx, tname):
5060 if (ectx.constraints_check and self.HasSizeConstraint()):
5061 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret='offset',
5062 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5063 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5065 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5066 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5069 if self.HasContentsConstraint():
5070 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
5071 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5072 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
5074 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5075 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5076 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
5078 body = '#error Can not decode %s' % (tname)
5081 #--- CharacterStringType ------------------------------------------------------
5082 class CharacterStringType (Type):
5083 def eth_tname(self):
5084 if not self.HasConstraint():
5085 return self.eth_tsname()
5086 elif self.constr.type == 'Size':
5087 return self.eth_tsname() + '_' + self.constr.eth_constrname()
5089 return '#' + self.type + '_' + str(id(self))
5091 def eth_ftype(self, ectx):
5092 return ('FT_STRING', 'BASE_NONE')
5094 class RestrictedCharacterStringType (CharacterStringType):
5095 def to_python (self, ctx):
5096 return 'asn1.' + self.eth_tsname()
5098 def GetTTag(self, ectx):
5099 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
5101 def eth_type_default_pars(self, ectx, tname):
5102 pars = Type.eth_type_default_pars(self, ectx, tname)
5103 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5104 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
5105 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
5108 def eth_type_default_body(self, ectx, tname):
5110 if (ectx.constraints_check and self.HasSizeConstraint()):
5111 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret='offset',
5112 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5113 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5114 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5116 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
5117 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5118 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5120 elif (ectx.Per() and self.HasPermAlph()):
5121 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
5122 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5123 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
5126 if (self.eth_tsname() == 'GeneralString'):
5127 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5128 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5129 elif (self.eth_tsname() == 'GeneralizedTime'):
5130 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', 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 elif (self.eth_tsname() == 'UTCTime'):
5134 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
5135 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5136 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5138 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5139 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5140 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5142 body = '#error Can not decode %s' % (tname)
5145 class BMPStringType (RestrictedCharacterStringType):
5146 def eth_tsname(self):
5149 class GeneralStringType (RestrictedCharacterStringType):
5150 def eth_tsname(self):
5151 return 'GeneralString'
5153 class GraphicStringType (RestrictedCharacterStringType):
5154 def eth_tsname(self):
5155 return 'GraphicString'
5157 class IA5StringType (RestrictedCharacterStringType):
5158 def eth_tsname(self):
5161 class NumericStringType (RestrictedCharacterStringType):
5162 def eth_tsname(self):
5163 return 'NumericString'
5165 class PrintableStringType (RestrictedCharacterStringType):
5166 def eth_tsname(self):
5167 return 'PrintableString'
5169 class TeletexStringType (RestrictedCharacterStringType):
5170 def eth_tsname(self):
5171 return 'TeletexString'
5173 class T61StringType (RestrictedCharacterStringType):
5174 def eth_tsname(self):
5176 def GetTTag(self, ectx):
5177 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
5179 class UniversalStringType (RestrictedCharacterStringType):
5180 def eth_tsname(self):
5181 return 'UniversalString'
5183 class UTF8StringType (RestrictedCharacterStringType):
5184 def eth_tsname(self):
5187 class VideotexStringType (RestrictedCharacterStringType):
5188 def eth_tsname(self):
5189 return 'VideotexString'
5191 class VisibleStringType (RestrictedCharacterStringType):
5192 def eth_tsname(self):
5193 return 'VisibleString'
5195 class ISO646StringType (RestrictedCharacterStringType):
5196 def eth_tsname(self):
5197 return 'ISO646String'
5198 def GetTTag(self, ectx):
5199 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
5201 class UnrestrictedCharacterStringType (CharacterStringType):
5202 def to_python (self, ctx):
5203 return 'asn1.UnrestrictedCharacterString'
5204 def eth_tsname(self):
5205 return 'CHARACTER_STRING'
5207 #--- UsefulType ---------------------------------------------------------------
5208 class GeneralizedTime (RestrictedCharacterStringType):
5209 def eth_tsname(self):
5210 return 'GeneralizedTime'
5212 def eth_type_default_body(self, ectx, tname):
5214 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5215 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5218 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5220 class UTCTime (RestrictedCharacterStringType):
5221 def eth_tsname(self):
5224 def eth_type_default_body(self, ectx, tname):
5226 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5227 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5230 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5232 class ObjectDescriptor (RestrictedCharacterStringType):
5233 def eth_tsname(self):
5234 return 'ObjectDescriptor'
5236 def eth_type_default_body(self, ectx, tname):
5238 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5240 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
5241 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5243 body = '#error Can not decode %s' % (tname)
5246 #--- ObjectIdentifierType -----------------------------------------------------
5247 class ObjectIdentifierType (Type):
5248 def to_python (self, ctx):
5249 return 'asn1.OBJECT_IDENTIFIER'
5251 def eth_tname(self):
5252 return 'OBJECT_IDENTIFIER'
5254 def eth_ftype(self, ectx):
5255 return ('FT_OID', 'BASE_NONE')
5257 def GetTTag(self, ectx):
5258 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
5260 def eth_type_default_pars(self, ectx, tname):
5261 pars = Type.eth_type_default_pars(self, ectx, tname)
5262 pars['FN_VARIANT'] = ectx.default_oid_variant
5265 def eth_type_default_body(self, ectx, tname):
5267 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5268 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5270 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5271 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5273 body = '#error Can not decode %s' % (tname)
5276 #--- ObjectIdentifierValue ----------------------------------------------------
5277 class ObjectIdentifierValue (Value):
5278 def get_num(self, path, val):
5279 return str(oid_names.get(path + '/' + val, val))
5281 def to_str(self, ectx):
5286 for v in self.comp_list:
5287 if isinstance(v, Node) and (v.type == 'name_and_number'):
5292 vstr = self.get_num(path, v)
5293 if not first and not vstr.isdigit():
5294 vstr = ectx.value_get_val(vstr)
5299 out += ectx.value_get_eth(vstr) + '"'
5309 v = self.comp_list[0]
5310 if isinstance(v, Node) and (v.type == 'name_and_number'):
5315 vstr = self.get_num('', v)
5321 class NamedNumber(Node):
5322 def to_python (self, ctx):
5323 return "('%s',%s)" % (self.ident, self.val)
5325 class NamedNumListBase(Node):
5326 def to_python (self, ctx):
5327 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
5328 [x.to_python (ctx) for x in self.named_list]))
5330 #--- RelativeOIDType ----------------------------------------------------------
5331 class RelativeOIDType (Type):
5333 def eth_tname(self):
5334 return 'RELATIVE_OID'
5336 def eth_ftype(self, ectx):
5337 return ('FT_REL_OID', 'BASE_NONE')
5339 def GetTTag(self, ectx):
5340 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5342 def eth_type_default_pars(self, ectx, tname):
5343 pars = Type.eth_type_default_pars(self, ectx, tname)
5344 pars['FN_VARIANT'] = ectx.default_oid_variant
5347 def eth_type_default_body(self, ectx, tname):
5349 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5350 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5352 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5353 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5355 body = '#error Can not decode %s' % (tname)
5359 #--- IntegerType --------------------------------------------------------------
5360 class IntegerType (Type):
5361 def to_python (self, ctx):
5362 return "asn1.INTEGER_class ([%s])" % (",".join (
5363 [x.to_python (ctx) for x in self.named_list]))
5365 def add_named_value(self, ident, val):
5366 e = NamedNumber(ident = ident, val = val)
5367 if not self.named_list:
5368 self.named_list = []
5369 self.named_list.append(e)
5371 def eth_tname(self):
5373 return Type.eth_tname(self)
5374 if not self.HasConstraint():
5376 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
5377 return 'INTEGER' + '_' + self.constr.eth_constrname()
5379 return 'INTEGER' + '_' + self.constr.eth_tname()
5381 def GetTTag(self, ectx):
5382 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5385 def eth_ftype(self, ectx):
5386 if self.HasConstraint():
5387 if not self.constr.IsNegativ():
5388 if self.constr.Needs64b(ectx):
5389 return ('FT_UINT64', 'BASE_DEC')
5391 return ('FT_UINT32', 'BASE_DEC')
5392 if self.constr.Needs64b(ectx):
5393 return ('FT_INT64', 'BASE_DEC')
5394 return ('FT_INT32', 'BASE_DEC')
5396 def eth_strings(self):
5397 if (self.named_list):
5402 def eth_has_vals(self):
5403 if (self.named_list):
5408 def get_vals(self, ectx):
5410 for e in (self.named_list):
5411 vals.append((int(e.val), e.ident))
5414 def eth_type_vals(self, tname, ectx):
5415 if not self.eth_has_vals(): return ''
5417 vals = self.get_vals(ectx)
5418 out += ectx.eth_vals(tname, vals)
5421 def reg_enum_vals(self, tname, ectx):
5422 vals = self.get_vals(ectx)
5423 for (val, id) in vals:
5424 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
5426 def eth_type_enum(self, tname, ectx):
5427 if not self.eth_has_enum(tname, ectx): return ''
5429 vals = self.get_vals(ectx)
5430 out += ectx.eth_enum(tname, vals)
5433 def eth_type_default_pars(self, ectx, tname):
5434 pars = Type.eth_type_default_pars(self, ectx, tname)
5435 if self.HasValueConstraint():
5436 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
5437 if (pars['FN_VARIANT'] == '') and self.constr.Needs64b(ectx):
5438 if ectx.Ber(): pars['FN_VARIANT'] = '64'
5439 else: pars['FN_VARIANT'] = '_64b'
5442 def eth_type_default_body(self, ectx, tname):
5444 if (ectx.constraints_check and self.HasValueConstraint()):
5445 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5446 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5447 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5449 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5450 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5452 elif (ectx.Per() and not self.HasValueConstraint()):
5453 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5454 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5455 elif (ectx.Per() and self.HasValueConstraint()):
5456 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5457 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5458 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5460 body = '#error Can not decode %s' % (tname)
5463 #--- BitStringType ------------------------------------------------------------
5464 class BitStringType (Type):
5465 def to_python (self, ctx):
5466 return "asn1.BITSTRING_class ([%s])" % (",".join (
5467 [x.to_python (ctx) for x in self.named_list]))
5469 def eth_tname(self):
5471 return Type.eth_tname(self)
5472 elif not self.HasConstraint():
5474 elif self.constr.IsSize():
5475 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
5477 return '#' + self.type + '_' + str(id(self))
5479 def GetTTag(self, ectx):
5480 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5482 def eth_ftype(self, ectx):
5483 return ('FT_BYTES', 'BASE_NONE')
5485 def eth_need_tree(self):
5486 return self.named_list
5488 def eth_need_pdu(self, ectx):
5490 if self.HasContentsConstraint():
5491 t = self.constr.GetContents(ectx)
5492 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5494 'new' : ectx.default_containing_variant == '_pdu_new' }
5497 def eth_named_bits(self):
5499 if (self.named_list):
5500 for e in (self.named_list):
5501 bits.append((int(e.val), e.ident))
5504 def eth_type_default_pars(self, ectx, tname):
5505 pars = Type.eth_type_default_pars(self, ectx, tname)
5506 pars['LEN_PTR'] = 'NULL'
5507 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5508 if 'ETT_INDEX' not in pars:
5509 pars['ETT_INDEX'] = '-1'
5510 pars['TABLE'] = 'NULL'
5511 if self.eth_named_bits():
5512 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5513 if self.HasContentsConstraint():
5514 pars['FN_VARIANT'] = ectx.default_containing_variant
5515 t = self.constr.GetContents(ectx)
5517 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5518 t = ectx.field[t]['ethname']
5519 pars['TYPE_REF_PROTO'] = ''
5520 pars['TYPE_REF_TNAME'] = t
5521 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5523 t = ectx.type[t]['ethname']
5524 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5525 pars['TYPE_REF_TNAME'] = t
5526 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5528 pars['TYPE_REF_FN'] = 'NULL'
5531 def eth_type_default_table(self, ectx, tname):
5532 #print "eth_type_default_table(tname='%s')" % (tname)
5534 bits = self.eth_named_bits()
5535 if (bits and ectx.Ber()):
5536 table = ectx.eth_bits(tname, bits)
5539 def eth_type_default_body(self, ectx, tname):
5541 if (ectx.constraints_check and self.HasSizeConstraint()):
5542 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret='offset',
5543 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5544 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5547 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
5548 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5549 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5552 if self.HasContentsConstraint():
5553 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
5554 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5555 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5557 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
5558 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5559 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s', '%(LEN_PTR)s'),))
5561 body = '#error Can not decode %s' % (tname)
5564 #--- BStringValue ------------------------------------------------------------
5583 class BStringValue (Value):
5584 def to_str(self, ectx):
5587 v += '0' * (8 - len(v) % 8)
5589 for i in (list(range(0, len(v), 4))):
5590 vv += bstring_tab[v[i:i+4]]
5593 #--- HStringValue ------------------------------------------------------------
5594 class HStringValue (Value):
5595 def to_str(self, ectx):
5597 vv += self.val[1:-2]
5600 return int(self.val[1:-2], 16)
5602 #--- FieldSpec ----------------------------------------------------------------
5603 class FieldSpec (Node):
5604 def __init__(self,*args, **kw) :
5606 Node.__init__ (self,*args, **kw)
5608 def SetName(self, name):
5612 return ['#UNSUPPORTED_' + self.type]
5616 repr.extend(self.get_repr())
5619 class TypeFieldSpec (FieldSpec):
5623 class FixedTypeValueFieldSpec (FieldSpec):
5625 if isinstance(self.typ, Type_Ref):
5626 repr = ['TypeReference', self.typ.val]
5628 repr = [self.typ.type]
5631 class VariableTypeValueFieldSpec (FieldSpec):
5633 return ['_' + self.type]
5635 class FixedTypeValueSetFieldSpec (FieldSpec):
5637 return ['_' + self.type]
5639 class ObjectFieldSpec (FieldSpec):
5641 return ['ClassReference', self.cls.val]
5643 class ObjectSetFieldSpec (FieldSpec):
5645 return ['ClassReference', self.cls.val]
5647 #==============================================================================
5649 def p_module_list_1 (t):
5650 'module_list : module_list ModuleDefinition'
5651 t[0] = t[1] + [t[2]]
5653 def p_module_list_2 (t):
5654 'module_list : ModuleDefinition'
5658 #--- ITU-T Recommendation X.680 -----------------------------------------------
5661 # 11 ASN.1 lexical items --------------------------------------------------------
5663 # 11.2 Type references
5665 'type_ref : UCASE_IDENT'
5666 t[0] = Type_Ref(val=t[1])
5669 def p_identifier (t):
5670 'identifier : LCASE_IDENT'
5673 # 11.4 Value references
5674 # cause reduce/reduce conflict
5675 #def p_valuereference (t):
5676 # 'valuereference : LCASE_IDENT'
5677 # t[0] = Value_Ref(val=t[1])
5679 # 11.5 Module references
5680 def p_modulereference (t):
5681 'modulereference : UCASE_IDENT'
5685 # 12 Module definition --------------------------------------------------------
5688 def p_ModuleDefinition (t):
5689 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5690 t[0] = Module (ident = t[1], tag_def = t[3], body = t[7])
5692 def p_ModuleBegin (t):
5694 if t[-4].val == 'Remote-Operations-Information-Objects':
5697 def p_TagDefault_1 (t):
5698 '''TagDefault : EXPLICIT TAGS
5700 | AUTOMATIC TAGS '''
5701 t[0] = Default_Tags (dfl_tag = t[1])
5703 def p_TagDefault_2 (t):
5705 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5706 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
5708 def p_ModuleIdentifier_1 (t):
5709 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5710 t [0] = Node('module_ident', val = t[1], ident = t[2])
5712 def p_ModuleIdentifier_2 (t):
5713 'ModuleIdentifier : modulereference' # name, oid
5714 t [0] = Node('module_ident', val = t[1], ident = None)
5716 def p_DefinitiveIdentifier (t):
5717 'DefinitiveIdentifier : ObjectIdentifierValue'
5720 #def p_module_ref (t):
5721 # 'module_ref : UCASE_IDENT'
5724 def p_ModuleBody_1 (t):
5725 'ModuleBody : Exports Imports AssignmentList'
5726 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
5728 def p_ModuleBody_2 (t):
5730 t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
5732 def p_Exports_1 (t):
5733 'Exports : EXPORTS syms_exported SEMICOLON'
5736 def p_Exports_2 (t):
5737 'Exports : EXPORTS ALL SEMICOLON'
5740 def p_Exports_3 (t):
5744 def p_syms_exported_1 (t):
5745 'syms_exported : exp_sym_list'
5748 def p_syms_exported_2 (t):
5752 def p_exp_sym_list_1 (t):
5753 'exp_sym_list : Symbol'
5756 def p_exp_sym_list_2 (t):
5757 'exp_sym_list : exp_sym_list COMMA Symbol'
5758 t[0] = t[1] + [t[3]]
5761 def p_Imports_1 (t):
5762 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5764 global lcase_ident_assigned
5765 lcase_ident_assigned = {}
5767 def p_importsbegin (t):
5769 global lcase_ident_assigned
5771 lcase_ident_assigned = {}
5772 lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5774 def p_Imports_2 (t):
5778 def p_SymbolsImported_1(t):
5779 'SymbolsImported : '
5782 def p_SymbolsImported_2 (t):
5783 'SymbolsImported : SymbolsFromModuleList'
5786 def p_SymbolsFromModuleList_1 (t):
5787 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5788 t[0] = t[1] + [t[2]]
5790 def p_SymbolsFromModuleList_2 (t):
5791 'SymbolsFromModuleList : SymbolsFromModule'
5794 def p_SymbolsFromModule (t):
5795 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
5796 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
5797 for s in (t[0].symbol_list):
5798 if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
5799 import_symbols_from_module(t[0].module, t[0].symbol_list)
5801 def import_symbols_from_module(module, symbol_list):
5802 if module.val == 'Remote-Operations-Information-Objects':
5803 for i in range(len(symbol_list)):
5805 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
5807 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5808 symbol_list[i] = Class_Ref (val = s.val)
5810 for i in range(len(symbol_list)):
5812 if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)):
5813 import_class_from_module(module.val, s.val)
5814 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5815 symbol_list[i] = Class_Ref (val = s.val)
5817 def p_GlobalModuleReference (t):
5818 'GlobalModuleReference : modulereference AssignedIdentifier'
5819 t [0] = Node('module_ident', val = t[1], ident = t[2])
5821 def p_AssignedIdentifier_1 (t):
5822 'AssignedIdentifier : ObjectIdentifierValue'
5825 def p_AssignedIdentifier_2 (t):
5826 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5829 def p_AssignedIdentifier_3 (t):
5830 'AssignedIdentifier : '
5833 def p_SymbolList_1 (t):
5834 'SymbolList : Symbol'
5837 def p_SymbolList_2 (t):
5838 'SymbolList : SymbolList COMMA Symbol'
5839 t[0] = t[1] + [t[3]]
5842 '''Symbol : Reference
5843 | ParameterizedReference'''
5846 def p_Reference_1 (t):
5847 '''Reference : type_ref
5848 | objectclassreference '''
5851 def p_Reference_2 (t):
5852 '''Reference : LCASE_IDENT_ASSIGNED
5853 | identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5854 t[0] = Value_Ref(val=t[1])
5856 def p_AssignmentList_1 (t):
5857 'AssignmentList : AssignmentList Assignment'
5858 t[0] = t[1] + [t[2]]
5860 def p_AssignmentList_2 (t):
5861 'AssignmentList : Assignment SEMICOLON'
5864 def p_AssignmentList_3 (t):
5865 'AssignmentList : Assignment'
5868 def p_Assignment (t):
5869 '''Assignment : TypeAssignment
5871 | ValueSetTypeAssignment
5872 | ObjectClassAssignment
5874 | ObjectSetAssignment
5875 | ParameterizedAssignment
5880 # 13 Referencing type and value definitions -----------------------------------
5883 def p_DefinedType (t):
5884 '''DefinedType : ExternalTypeReference
5886 | ParameterizedType'''
5889 def p_DefinedValue_1(t):
5890 '''DefinedValue : ExternalValueReference'''
5893 def p_DefinedValue_2(t):
5894 '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5895 t[0] = Value_Ref(val=t[1])
5898 def p_ExternalTypeReference (t):
5899 'ExternalTypeReference : modulereference DOT type_ref'
5900 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
5902 def p_ExternalValueReference (t):
5903 'ExternalValueReference : modulereference DOT identifier'
5904 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
5907 # 15 Assigning types and values -----------------------------------------------
5910 def p_TypeAssignment (t):
5911 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
5916 def p_ValueAssignment (t):
5917 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
5918 t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
5920 # only "simple" types are supported to simplify grammer
5921 def p_ValueType (t):
5922 '''ValueType : type_ref
5925 | ObjectIdentifierType
5932 def p_ValueSetTypeAssignment (t):
5933 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
5934 t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4])
5938 'ValueSet : lbraceignore rbraceignore'
5942 # 16 Definition of types and values -------------------------------------------
5946 '''Type : BuiltinType
5948 | ConstrainedType'''
5952 def p_BuiltinType (t):
5953 '''BuiltinType : AnyType
5956 | CharacterStringType
5964 | ObjectClassFieldType
5965 | ObjectIdentifierType
5977 def p_ReferencedType (t):
5978 '''ReferencedType : DefinedType
5984 def p_NamedType (t):
5985 'NamedType : identifier Type'
5991 '''Value : BuiltinValue
5993 | ObjectClassFieldValue'''
5997 def p_BuiltinValue (t):
5998 '''BuiltinValue : BooleanValue
6001 | ObjectIdentifierValue
6006 | char_string''' # XXX we don't support {data} here
6010 def p_ReferencedValue (t):
6011 '''ReferencedValue : DefinedValue
6012 | ValueFromObject'''
6016 #def p_NamedValue (t):
6017 # 'NamedValue : identifier Value'
6018 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
6021 # 17 Notation for the boolean type --------------------------------------------
6024 def p_BooleanType (t):
6025 'BooleanType : BOOLEAN'
6026 t[0] = BooleanType ()
6029 def p_BooleanValue (t):
6030 '''BooleanValue : TRUE
6035 # 18 Notation for the integer type --------------------------------------------
6038 def p_IntegerType_1 (t):
6039 'IntegerType : INTEGER'
6040 t[0] = IntegerType (named_list = None)
6042 def p_IntegerType_2 (t):
6043 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
6044 t[0] = IntegerType(named_list = t[3])
6046 def p_NamedNumberList_1 (t):
6047 'NamedNumberList : NamedNumber'
6050 def p_NamedNumberList_2 (t):
6051 'NamedNumberList : NamedNumberList COMMA NamedNumber'
6052 t[0] = t[1] + [t[3]]
6054 def p_NamedNumber (t):
6055 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
6056 | identifier LPAREN DefinedValue RPAREN'''
6057 t[0] = NamedNumber(ident = t[1], val = t[3])
6059 def p_SignedNumber_1 (t):
6060 'SignedNumber : NUMBER'
6063 def p_SignedNumber_2 (t):
6064 'SignedNumber : MINUS NUMBER'
6068 def p_IntegerValue (t):
6069 'IntegerValue : SignedNumber'
6072 # 19 Notation for the enumerated type -----------------------------------------
6075 def p_EnumeratedType (t):
6076 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
6077 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
6079 def p_Enumerations_1 (t):
6080 'Enumerations : Enumeration'
6081 t[0] = { 'val' : t[1], 'ext' : None }
6083 def p_Enumerations_2 (t):
6084 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
6085 t[0] = { 'val' : t[1], 'ext' : [] }
6087 def p_Enumerations_3 (t):
6088 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
6089 t[0] = { 'val' : t[1], 'ext' : t[6] }
6091 def p_Enumeration_1 (t):
6092 'Enumeration : EnumerationItem'
6095 def p_Enumeration_2 (t):
6096 'Enumeration : Enumeration COMMA EnumerationItem'
6097 t[0] = t[1] + [t[3]]
6099 def p_EnumerationItem (t):
6100 '''EnumerationItem : Identifier
6104 def p_Identifier (t):
6105 'Identifier : identifier'
6106 t[0] = Node ('Identifier', ident = t[1])
6109 # 20 Notation for the real type -----------------------------------------------
6117 def p_RealValue (t):
6118 '''RealValue : REAL_NUMBER
6119 | SpecialRealValue'''
6122 def p_SpecialRealValue (t):
6123 '''SpecialRealValue : PLUS_INFINITY
6128 # 21 Notation for the bitstring type ------------------------------------------
6131 def p_BitStringType_1 (t):
6132 'BitStringType : BIT STRING'
6133 t[0] = BitStringType (named_list = None)
6135 def p_BitStringType_2 (t):
6136 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
6137 t[0] = BitStringType (named_list = t[4])
6139 def p_NamedBitList_1 (t):
6140 'NamedBitList : NamedBit'
6143 def p_NamedBitList_2 (t):
6144 'NamedBitList : NamedBitList COMMA NamedBit'
6145 t[0] = t[1] + [t[3]]
6148 '''NamedBit : identifier LPAREN NUMBER RPAREN
6149 | identifier LPAREN DefinedValue RPAREN'''
6150 t[0] = NamedNumber (ident = t[1], val = t[3])
6153 # 22 Notation for the octetstring type ----------------------------------------
6156 def p_OctetStringType (t):
6157 'OctetStringType : OCTET STRING'
6158 t[0] = OctetStringType ()
6161 # 23 Notation for the null type -----------------------------------------------
6169 def p_NullValue (t):
6174 # 24 Notation for sequence types ----------------------------------------------
6177 def p_SequenceType_1 (t):
6178 'SequenceType : SEQUENCE LBRACE RBRACE'
6179 t[0] = SequenceType (elt_list = [])
6181 def p_SequenceType_2 (t):
6182 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
6183 t[0] = SequenceType (elt_list = t[3]['elt_list'])
6184 if 'ext_list' in t[3]:
6185 t[0].ext_list = t[3]['ext_list']
6186 if 'elt_list2' in t[3]:
6187 t[0].elt_list2 = t[3]['elt_list2']
6189 def p_ExtensionAndException_1 (t):
6190 'ExtensionAndException : ELLIPSIS'
6193 def p_OptionalExtensionMarker_1 (t):
6194 'OptionalExtensionMarker : COMMA ELLIPSIS'
6197 def p_OptionalExtensionMarker_2 (t):
6198 'OptionalExtensionMarker : '
6201 def p_ComponentTypeLists_1 (t):
6202 'ComponentTypeLists : ComponentTypeList'
6203 t[0] = {'elt_list' : t[1]}
6205 def p_ComponentTypeLists_2 (t):
6206 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
6207 t[0] = {'elt_list' : t[1], 'ext_list' : []}
6209 def p_ComponentTypeLists_3 (t):
6210 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6211 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6213 def p_ComponentTypeLists_4 (t):
6214 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
6215 t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]}
6217 def p_ComponentTypeLists_5 (t):
6218 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
6219 t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]}
6221 def p_ComponentTypeLists_6 (t):
6222 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
6223 t[0] = {'elt_list' : [], 'ext_list' : []}
6225 def p_ComponentTypeLists_7 (t):
6226 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6227 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
6229 def p_ExtensionEndMarker (t):
6230 'ExtensionEndMarker : COMMA ELLIPSIS'
6233 def p_ExtensionAdditionList_1 (t):
6234 'ExtensionAdditionList : COMMA ExtensionAddition'
6237 def p_ExtensionAdditionList_2 (t):
6238 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition'
6239 t[0] = t[1] + [t[3]]
6241 def p_ExtensionAddition_1 (t):
6242 'ExtensionAddition : ExtensionAdditionGroup'
6243 t[0] = Node ('elt_type', val = t[1], optional = 0)
6245 def p_ExtensionAddition_2 (t):
6246 'ExtensionAddition : ComponentType'
6249 def p_ExtensionAdditionGroup (t):
6250 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK'
6251 t[0] = ExtensionAdditionGroup (ver = t[2], elt_list = t[3])
6253 def p_VersionNumber_1 (t):
6256 def p_VersionNumber_2 (t):
6257 'VersionNumber : NUMBER COLON'
6260 def p_ComponentTypeList_1 (t):
6261 'ComponentTypeList : ComponentType'
6264 def p_ComponentTypeList_2 (t):
6265 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
6266 t[0] = t[1] + [t[3]]
6268 def p_ComponentType_1 (t):
6269 'ComponentType : NamedType'
6270 t[0] = Node ('elt_type', val = t[1], optional = 0)
6272 def p_ComponentType_2 (t):
6273 'ComponentType : NamedType OPTIONAL'
6274 t[0] = Node ('elt_type', val = t[1], optional = 1)
6276 def p_ComponentType_3 (t):
6277 'ComponentType : NamedType DEFAULT DefaultValue'
6278 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
6280 def p_ComponentType_4 (t):
6281 'ComponentType : COMPONENTS OF Type'
6282 t[0] = Node ('components_of', typ = t[3])
6284 def p_DefaultValue_1 (t):
6285 '''DefaultValue : ReferencedValue
6293 | ObjectClassFieldValue'''
6296 def p_DefaultValue_2 (t):
6297 'DefaultValue : lbraceignore rbraceignore'
6301 def p_SequenceValue_1 (t):
6302 'SequenceValue : LBRACE RBRACE'
6306 #def p_SequenceValue_2 (t):
6307 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
6310 #def p_ComponentValueList_1 (t):
6311 # 'ComponentValueList : NamedValue'
6314 #def p_ComponentValueList_2 (t):
6315 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
6316 # t[0] = t[1] + [t[3]]
6319 # 25 Notation for sequence-of types -------------------------------------------
6322 def p_SequenceOfType (t):
6323 '''SequenceOfType : SEQUENCE OF Type
6324 | SEQUENCE OF NamedType'''
6325 t[0] = SequenceOfType (val = t[3], size_constr = None)
6328 # 26 Notation for set types ---------------------------------------------------
6331 def p_SetType_1 (t):
6332 'SetType : SET LBRACE RBRACE'
6333 t[0] = SetType (elt_list = [])
6335 def p_SetType_2 (t):
6336 'SetType : SET LBRACE ComponentTypeLists RBRACE'
6337 t[0] = SetType (elt_list = t[3]['elt_list'])
6338 if 'ext_list' in t[3]:
6339 t[0].ext_list = t[3]['ext_list']
6340 if 'elt_list2' in t[3]:
6341 t[0].elt_list2 = t[3]['elt_list2']
6344 # 27 Notation for set-of types ------------------------------------------------
6347 def p_SetOfType (t):
6348 '''SetOfType : SET OF Type
6349 | SET OF NamedType'''
6350 t[0] = SetOfType (val = t[3])
6352 # 28 Notation for choice types ------------------------------------------------
6355 def p_ChoiceType (t):
6356 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE'
6357 if 'ext_list' in t[3]:
6358 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
6360 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
6362 def p_AlternativeTypeLists_1 (t):
6363 'AlternativeTypeLists : AlternativeTypeList'
6364 t[0] = {'elt_list' : t[1]}
6366 def p_AlternativeTypeLists_2 (t):
6367 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker'
6368 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6370 def p_ExtensionAdditionAlternatives_1 (t):
6371 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList'
6374 def p_ExtensionAdditionAlternatives_2 (t):
6375 'ExtensionAdditionAlternatives : '
6378 def p_ExtensionAdditionAlternativesList_1 (t):
6379 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative'
6382 def p_ExtensionAdditionAlternativesList_2 (t):
6383 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative'
6386 def p_ExtensionAdditionAlternative_1 (t):
6387 'ExtensionAdditionAlternative : NamedType'
6390 def p_ExtensionAdditionAlternative_2 (t):
6391 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup'
6394 def p_ExtensionAdditionAlternativesGroup (t):
6395 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK'
6398 def p_AlternativeTypeList_1 (t):
6399 'AlternativeTypeList : NamedType'
6402 def p_AlternativeTypeList_2 (t):
6403 'AlternativeTypeList : AlternativeTypeList COMMA NamedType'
6404 t[0] = t[1] + [t[3]]
6407 def p_ChoiceValue_1 (t):
6408 '''ChoiceValue : identifier COLON Value
6409 | identifier COLON NullValue '''
6411 if not isinstance(val, Value):
6412 val = Value(val=val)
6413 t[0] = ChoiceValue (choice = t[1], val = val)
6415 # 29 Notation for selection types
6418 def p_SelectionType (t): #
6419 'SelectionType : identifier LT Type'
6420 t[0] = SelectionType (typ = t[3], sel = t[1])
6422 # 30 Notation for tagged types ------------------------------------------------
6425 def p_TaggedType_1 (t):
6426 'TaggedType : Tag Type'
6427 t[1].mode = 'default'
6431 def p_TaggedType_2 (t):
6432 '''TaggedType : Tag IMPLICIT Type
6433 | Tag EXPLICIT Type'''
6439 'Tag : LBRACK Class ClassNumber RBRACK'
6440 t[0] = Tag(cls = t[2], num = t[3])
6442 def p_ClassNumber_1 (t):
6443 'ClassNumber : number'
6446 def p_ClassNumber_2 (t):
6447 'ClassNumber : DefinedValue'
6451 '''Class : UNIVERSAL
6461 # 31 Notation for the object identifier type ----------------------------------
6464 def p_ObjectIdentifierType (t):
6465 'ObjectIdentifierType : OBJECT IDENTIFIER'
6466 t[0] = ObjectIdentifierType()
6469 def p_ObjectIdentifierValue (t):
6470 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6471 t[0] = ObjectIdentifierValue (comp_list=t[2])
6473 def p_oid_comp_list_1 (t):
6474 'oid_comp_list : oid_comp_list ObjIdComponents'
6475 t[0] = t[1] + [t[2]]
6477 def p_oid_comp_list_2 (t):
6478 'oid_comp_list : ObjIdComponents'
6481 def p_ObjIdComponents (t):
6482 '''ObjIdComponents : NameForm
6484 | NameAndNumberForm'''
6488 '''NameForm : LCASE_IDENT
6489 | LCASE_IDENT_ASSIGNED'''
6492 def p_NumberForm (t):
6493 '''NumberForm : NUMBER'''
6497 def p_NameAndNumberForm (t):
6498 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6499 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6500 t[0] = Node('name_and_number', ident = t[1], number = t[3])
6502 # 32 Notation for the relative object identifier type -------------------------
6505 def p_RelativeOIDType (t):
6506 'RelativeOIDType : RELATIVE_OID'
6507 t[0] = RelativeOIDType()
6509 # 33 Notation for the embedded-pdv type ---------------------------------------
6512 def p_EmbeddedPDVType (t):
6513 'EmbeddedPDVType : EMBEDDED PDV'
6514 t[0] = EmbeddedPDVType()
6516 # 34 Notation for the external type -------------------------------------------
6519 def p_ExternalType (t):
6520 'ExternalType : EXTERNAL'
6521 t[0] = ExternalType()
6523 # 36 Notation for character string types --------------------------------------
6526 def p_CharacterStringType (t):
6527 '''CharacterStringType : RestrictedCharacterStringType
6528 | UnrestrictedCharacterStringType'''
6532 # 37 Definition of restricted character string types --------------------------
6534 def p_RestrictedCharacterStringType_1 (t):
6535 'RestrictedCharacterStringType : BMPString'
6536 t[0] = BMPStringType ()
6537 def p_RestrictedCharacterStringType_2 (t):
6538 'RestrictedCharacterStringType : GeneralString'
6539 t[0] = GeneralStringType ()
6540 def p_RestrictedCharacterStringType_3 (t):
6541 'RestrictedCharacterStringType : GraphicString'
6542 t[0] = GraphicStringType ()
6543 def p_RestrictedCharacterStringType_4 (t):
6544 'RestrictedCharacterStringType : IA5String'
6545 t[0] = IA5StringType ()
6546 def p_RestrictedCharacterStringType_5 (t):
6547 'RestrictedCharacterStringType : ISO646String'
6548 t[0] = ISO646StringType ()
6549 def p_RestrictedCharacterStringType_6 (t):
6550 'RestrictedCharacterStringType : NumericString'
6551 t[0] = NumericStringType ()
6552 def p_RestrictedCharacterStringType_7 (t):
6553 'RestrictedCharacterStringType : PrintableString'
6554 t[0] = PrintableStringType ()
6555 def p_RestrictedCharacterStringType_8 (t):
6556 'RestrictedCharacterStringType : TeletexString'
6557 t[0] = TeletexStringType ()
6558 def p_RestrictedCharacterStringType_9 (t):
6559 'RestrictedCharacterStringType : T61String'
6560 t[0] = T61StringType ()
6561 def p_RestrictedCharacterStringType_10 (t):
6562 'RestrictedCharacterStringType : UniversalString'
6563 t[0] = UniversalStringType ()
6564 def p_RestrictedCharacterStringType_11 (t):
6565 'RestrictedCharacterStringType : UTF8String'
6566 t[0] = UTF8StringType ()
6567 def p_RestrictedCharacterStringType_12 (t):
6568 'RestrictedCharacterStringType : VideotexString'
6569 t[0] = VideotexStringType ()
6570 def p_RestrictedCharacterStringType_13 (t):
6571 'RestrictedCharacterStringType : VisibleString'
6572 t[0] = VisibleStringType ()
6575 # 40 Definition of unrestricted character string types ------------------------
6578 def p_UnrestrictedCharacterStringType (t):
6579 'UnrestrictedCharacterStringType : CHARACTER STRING'
6580 t[0] = UnrestrictedCharacterStringType ()
6583 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6585 # 42 Generalized time ---------------------------------------------------------
6587 def p_UsefulType_1 (t):
6588 'UsefulType : GeneralizedTime'
6589 t[0] = GeneralizedTime()
6591 # 43 Universal time -----------------------------------------------------------
6593 def p_UsefulType_2 (t):
6594 'UsefulType : UTCTime'
6597 # 44 The object descriptor type -----------------------------------------------
6599 def p_UsefulType_3 (t):
6600 'UsefulType : ObjectDescriptor'
6601 t[0] = ObjectDescriptor()
6604 # 45 Constrained types --------------------------------------------------------
6607 def p_ConstrainedType_1 (t):
6608 'ConstrainedType : Type Constraint'
6610 t[0].AddConstraint(t[2])
6612 def p_ConstrainedType_2 (t):
6613 'ConstrainedType : TypeWithConstraint'
6617 def p_TypeWithConstraint_1 (t):
6618 '''TypeWithConstraint : SET Constraint OF Type
6619 | SET SizeConstraint OF Type'''
6620 t[0] = SetOfType (val = t[4], constr = t[2])
6622 def p_TypeWithConstraint_2 (t):
6623 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6624 | SEQUENCE SizeConstraint OF Type'''
6625 t[0] = SequenceOfType (val = t[4], constr = t[2])
6627 def p_TypeWithConstraint_3 (t):
6628 '''TypeWithConstraint : SET Constraint OF NamedType
6629 | SET SizeConstraint OF NamedType'''
6630 t[0] = SetOfType (val = t[4], constr = t[2])
6632 def p_TypeWithConstraint_4 (t):
6633 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6634 | SEQUENCE SizeConstraint OF NamedType'''
6635 t[0] = SequenceOfType (val = t[4], constr = t[2])
6639 def p_Constraint (t):
6640 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6643 def p_ConstraintSpec (t):
6644 '''ConstraintSpec : ElementSetSpecs
6645 | GeneralConstraint'''
6648 # 46 Element set specification ------------------------------------------------
6651 def p_ElementSetSpecs_1 (t):
6652 'ElementSetSpecs : RootElementSetSpec'
6655 def p_ElementSetSpecs_2 (t):
6656 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6660 def p_ElementSetSpecs_3 (t):
6661 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6665 def p_RootElementSetSpec (t):
6666 'RootElementSetSpec : ElementSetSpec'
6669 def p_AdditionalElementSetSpec (t):
6670 'AdditionalElementSetSpec : ElementSetSpec'
6673 def p_ElementSetSpec (t):
6674 'ElementSetSpec : Unions'
6678 'Unions : Intersections'
6682 'Unions : UElems UnionMark Intersections'
6683 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
6689 def p_Intersections_1 (t):
6690 'Intersections : IntersectionElements'
6693 def p_Intersections_2 (t):
6694 'Intersections : IElems IntersectionMark IntersectionElements'
6695 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
6698 'IElems : Intersections'
6701 def p_IntersectionElements (t):
6702 'IntersectionElements : Elements'
6705 def p_UnionMark (t):
6709 def p_IntersectionMark (t):
6710 '''IntersectionMark : CIRCUMFLEX
6714 def p_Elements_1 (t):
6715 'Elements : SubtypeElements'
6718 def p_Elements_2 (t):
6719 'Elements : LPAREN ElementSetSpec RPAREN'
6722 # 47 Subtype elements ---------------------------------------------------------
6725 def p_SubtypeElements (t):
6726 '''SubtypeElements : SingleValue
6732 | InnerTypeConstraints
6733 | PatternConstraint'''
6738 def p_SingleValue (t):
6739 'SingleValue : Value'
6740 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
6742 # 47.3 Contained subtype
6744 def p_ContainedSubtype (t):
6745 'ContainedSubtype : Includes Type'
6746 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
6749 '''Includes : INCLUDES
6754 def p_ValueRange (t):
6755 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6756 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
6759 def p_LowerEndpoint_1 (t):
6760 'LowerEndpoint : LowerEndValue'
6763 def p_LowerEndpoint_2 (t):
6764 'LowerEndpoint : LowerEndValue LT'
6765 t[0] = t[1] # but not inclusive range
6767 def p_UpperEndpoint_1 (t):
6768 'UpperEndpoint : UpperEndValue'
6771 def p_UpperEndpoint_2 (t):
6772 'UpperEndpoint : LT UpperEndValue'
6773 t[0] = t[1] # but not inclusive range
6776 def p_LowerEndValue (t):
6777 '''LowerEndValue : Value
6781 def p_UpperEndValue (t):
6782 '''UpperEndValue : Value
6786 # 47.5 Size constraint
6788 def p_SizeConstraint (t):
6789 'SizeConstraint : SIZE Constraint'
6790 t[0] = Constraint (type = 'Size', subtype = t[2])
6792 # 47.6 Type constraint
6794 def p_TypeConstraint (t):
6795 'TypeConstraint : Type'
6796 t[0] = Constraint (type = 'Type', subtype = t[1])
6798 # 47.7 Permitted alphabet
6800 def p_PermittedAlphabet (t):
6801 'PermittedAlphabet : FROM Constraint'
6802 t[0] = Constraint (type = 'From', subtype = t[2])
6804 # 47.8 Inner subtyping
6806 def p_InnerTypeConstraints (t):
6807 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6808 | WITH COMPONENTS MultipleTypeConstraints'''
6809 pass # ignore PER invisible constraint
6812 def p_SingleTypeConstraint (t):
6813 'SingleTypeConstraint : Constraint'
6817 def p_MultipleTypeConstraints (t):
6818 '''MultipleTypeConstraints : FullSpecification
6819 | PartialSpecification'''
6822 def p_FullSpecification (t):
6823 'FullSpecification : LBRACE TypeConstraints RBRACE'
6826 def p_PartialSpecification (t):
6827 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6830 def p_TypeConstraints_1 (t):
6831 'TypeConstraints : named_constraint'
6834 def p_TypeConstraints_2 (t):
6835 'TypeConstraints : TypeConstraints COMMA named_constraint'
6836 t[0] = t[1] + [t[3]]
6838 def p_named_constraint_1 (t):
6839 'named_constraint : identifier constraint'
6840 return Node ('named_constraint', ident = t[1], constr = t[2])
6842 def p_named_constraint_2 (t):
6843 'named_constraint : constraint'
6844 return Node ('named_constraint', constr = t[1])
6846 def p_constraint (t):
6847 'constraint : value_constraint presence_constraint'
6848 t[0] = Node ('constraint', value = t[1], presence = t[2])
6850 def p_value_constraint_1 (t):
6851 'value_constraint : Constraint'
6854 def p_value_constraint_2 (t):
6855 'value_constraint : '
6858 def p_presence_constraint_1 (t):
6859 '''presence_constraint : PRESENT
6864 def p_presence_constraint_2 (t):
6865 '''presence_constraint : '''
6868 # 47.9 Pattern constraint
6870 def p_PatternConstraint (t):
6871 'PatternConstraint : PATTERN Value'
6872 t[0] = Constraint (type = 'Pattern', subtype = t[2])
6874 # 49 The exception identifier
6877 def p_ExceptionSpec_1 (t):
6878 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
6881 def p_ExceptionSpec_2 (t):
6885 def p_ExceptionIdentification (t):
6886 '''ExceptionIdentification : SignedNumber
6888 | Type COLON Value '''
6891 # /*-----------------------------------------------------------------------*/
6892 # /* Value Notation Productions */
6893 # /*-----------------------------------------------------------------------*/
6897 def p_binary_string (t):
6898 'binary_string : BSTRING'
6899 t[0] = BStringValue(val = t[1])
6901 def p_hex_string (t):
6902 'hex_string : HSTRING'
6903 t[0] = HStringValue(val = t[1])
6905 def p_char_string (t):
6906 'char_string : QSTRING'
6914 #--- ITU-T Recommendation X.208 -----------------------------------------------
6916 # 27 Notation for the any type ------------------------------------------------
6921 | ANY DEFINED BY identifier'''
6924 #--- ITU-T Recommendation X.681 -----------------------------------------------
6926 # 7 ASN.1 lexical items -------------------------------------------------------
6928 # 7.1 Information object class references
6930 def p_objectclassreference (t):
6931 'objectclassreference : CLASS_IDENT'
6932 t[0] = Class_Ref(val=t[1])
6934 # 7.2 Information object references
6936 def p_objectreference (t):
6937 'objectreference : LCASE_IDENT'
6940 # 7.3 Information object set references
6942 #def p_objectsetreference (t):
6943 # 'objectsetreference : UCASE_IDENT'
6946 # 7.4 Type field references
6947 # ucasefieldreference
6948 # 7.5 Value field references
6949 # lcasefieldreference
6950 # 7.6 Value set field references
6951 # ucasefieldreference
6952 # 7.7 Object field references
6953 # lcasefieldreference
6954 # 7.8 Object set field references
6955 # ucasefieldreference
6957 def p_ucasefieldreference (t):
6958 'ucasefieldreference : AMPERSAND UCASE_IDENT'
6961 def p_lcasefieldreference (t):
6962 'lcasefieldreference : AMPERSAND LCASE_IDENT'
6965 # 8 Referencing definitions
6968 def p_DefinedObjectClass (t):
6969 '''DefinedObjectClass : objectclassreference
6970 | UsefulObjectClassReference'''
6973 obj_class = t[0].val
6975 def p_DefinedObject (t):
6976 '''DefinedObject : objectreference'''
6980 def p_UsefulObjectClassReference (t):
6981 '''UsefulObjectClassReference : TYPE_IDENTIFIER
6982 | ABSTRACT_SYNTAX'''
6983 t[0] = Class_Ref(val=t[1])
6985 # 9 Information object class definition and assignment
6988 def p_ObjectClassAssignment (t):
6989 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
6990 | UCASE_IDENT ASSIGNMENT ObjectClass'''
6993 if isinstance(t[0], ObjectClassDefn):
6997 def p_ObjectClass (t):
6998 '''ObjectClass : DefinedObjectClass
7000 | ParameterizedObjectClass '''
7004 def p_ObjectClassDefn (t):
7005 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
7006 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
7007 t[0] = ObjectClassDefn(fields = t[3])
7009 def p_FieldSpecs_1 (t):
7010 'FieldSpecs : FieldSpec'
7013 def p_FieldSpecs_2 (t):
7014 'FieldSpecs : FieldSpecs COMMA FieldSpec'
7015 t[0] = t[1] + [t[3]]
7017 def p_WithSyntaxSpec (t):
7018 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
7022 def p_FieldSpec (t):
7023 '''FieldSpec : TypeFieldSpec
7024 | FixedTypeValueFieldSpec
7025 | VariableTypeValueFieldSpec
7026 | FixedTypeValueSetFieldSpec
7028 | ObjectSetFieldSpec '''
7032 def p_TypeFieldSpec (t):
7033 '''TypeFieldSpec : ucasefieldreference
7034 | ucasefieldreference TypeOptionalitySpec '''
7035 t[0] = TypeFieldSpec()
7038 def p_TypeOptionalitySpec_1 (t):
7039 'TypeOptionalitySpec ::= OPTIONAL'
7042 def p_TypeOptionalitySpec_2 (t):
7043 'TypeOptionalitySpec ::= DEFAULT Type'
7047 def p_FixedTypeValueFieldSpec (t):
7048 '''FixedTypeValueFieldSpec : lcasefieldreference Type
7049 | lcasefieldreference Type UNIQUE
7050 | lcasefieldreference Type ValueOptionalitySpec
7051 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
7052 t[0] = FixedTypeValueFieldSpec(typ = t[2])
7055 def p_ValueOptionalitySpec_1 (t):
7056 'ValueOptionalitySpec ::= OPTIONAL'
7059 def p_ValueOptionalitySpec_2 (t):
7060 'ValueOptionalitySpec ::= DEFAULT Value'
7065 def p_VariableTypeValueFieldSpec (t):
7066 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
7067 | lcasefieldreference FieldName ValueOptionalitySpec '''
7068 t[0] = VariableTypeValueFieldSpec()
7072 def p_FixedTypeValueSetFieldSpec (t):
7073 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
7074 | ucasefieldreference Type ValueSetOptionalitySpec '''
7075 t[0] = FixedTypeValueSetFieldSpec()
7078 def p_ValueSetOptionalitySpec_1 (t):
7079 'ValueSetOptionalitySpec ::= OPTIONAL'
7082 def p_ValueSetOptionalitySpec_2 (t):
7083 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
7087 def p_ObjectFieldSpec (t):
7088 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
7089 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
7090 t[0] = ObjectFieldSpec(cls=t[2])
7095 def p_ObjectOptionalitySpec_1 (t):
7096 'ObjectOptionalitySpec ::= OPTIONAL'
7099 def p_ObjectOptionalitySpec_2 (t):
7100 'ObjectOptionalitySpec ::= DEFAULT Object'
7104 def p_ObjectSetFieldSpec (t):
7105 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
7106 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
7107 t[0] = ObjectSetFieldSpec(cls=t[2])
7110 def p_ObjectSetOptionalitySpec_1 (t):
7111 'ObjectSetOptionalitySpec ::= OPTIONAL'
7114 def p_ObjectSetOptionalitySpec_2 (t):
7115 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
7119 def p_PrimitiveFieldName (t):
7120 '''PrimitiveFieldName : ucasefieldreference
7121 | lcasefieldreference '''
7125 def p_FieldName_1 (t):
7126 'FieldName : PrimitiveFieldName'
7129 def p_FieldName_2 (t):
7130 'FieldName : FieldName DOT PrimitiveFieldName'
7131 t[0] = t[1] + '.' + t[3]
7133 # 11 Information object definition and assignment
7136 def p_ObjectAssignment (t):
7137 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
7138 t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4])
7144 '''Object : DefinedObject
7146 | ParameterizedObject'''
7150 def p_ObjectDefn (t):
7151 'ObjectDefn : lbraceobject bodyobject rbraceobject'
7154 # {...} block of object definition
7155 def p_lbraceobject(t):
7156 'lbraceobject : braceobjectbegin LBRACE'
7159 def p_braceobjectbegin(t):
7160 'braceobjectbegin : '
7163 if set_class_syntax(obj_class):
7167 state = 'braceignore'
7168 lexer.push_state(state)
7170 def p_rbraceobject(t):
7171 'rbraceobject : braceobjectend RBRACE'
7174 def p_braceobjectend(t):
7178 set_class_syntax(None)
7180 def p_bodyobject_1 (t):
7184 def p_bodyobject_2 (t):
7185 'bodyobject : cls_syntax_list'
7188 def p_cls_syntax_list_1 (t):
7189 'cls_syntax_list : cls_syntax_list cls_syntax'
7193 def p_cls_syntax_list_2 (t):
7194 'cls_syntax_list : cls_syntax'
7198 def p_cls_syntax_1 (t):
7199 'cls_syntax : Type IDENTIFIED BY Value'
7200 t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
7202 def p_cls_syntax_2 (t):
7203 'cls_syntax : HAS PROPERTY Value'
7204 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7207 def p_cls_syntax_3 (t):
7208 '''cls_syntax : ERRORS ObjectSet
7210 | RETURN RESULT BooleanValue
7211 | SYNCHRONOUS BooleanValue
7212 | INVOKE PRIORITY Value
7213 | RESULT_PRIORITY Value
7215 | ALWAYS RESPONDS BooleanValue
7216 | IDEMPOTENT BooleanValue '''
7217 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7219 def p_cls_syntax_4 (t):
7220 '''cls_syntax : ARGUMENT Type
7222 | PARAMETER Type '''
7223 t[0] = { get_class_fieled(t[1]) : t[2] }
7225 def p_cls_syntax_5 (t):
7226 'cls_syntax : CODE Value'
7227 fld = get_class_fieled(t[1]);
7228 t[0] = { fld : t[2] }
7229 if isinstance(t[2], ChoiceValue):
7230 fldt = fld + '.' + t[2].choice
7233 def p_cls_syntax_6 (t):
7234 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
7235 | RESULT Type OPTIONAL BooleanValue
7236 | PARAMETER Type OPTIONAL BooleanValue '''
7237 t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
7239 # 12 Information object set definition and assignment
7242 def p_ObjectSetAssignment (t):
7243 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
7244 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
7247 def p_ObjectSet (t):
7248 'ObjectSet : lbraceignore rbraceignore'
7251 # 14 Notation for the object class field type ---------------------------------
7254 def p_ObjectClassFieldType (t):
7255 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
7256 t[0] = get_type_from_class(t[1], t[3])
7259 def p_ObjectClassFieldValue (t):
7260 '''ObjectClassFieldValue : OpenTypeFieldVal'''
7263 def p_OpenTypeFieldVal (t):
7264 '''OpenTypeFieldVal : Type COLON Value
7265 | NullType COLON NullValue'''
7269 # 15 Information from objects -------------------------------------------------
7273 def p_ValueFromObject (t):
7274 'ValueFromObject : LCASE_IDENT DOT FieldName'
7275 t[0] = t[1] + '.' + t[3]
7278 # Annex C - The instance-of type ----------------------------------------------
7281 def p_InstanceOfType (t):
7282 'InstanceOfType : INSTANCE OF DefinedObjectClass'
7283 t[0] = InstanceOfType()
7288 useful_object_class_types = {
7290 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
7291 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
7293 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
7294 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
7295 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
7298 object_class_types = { }
7300 object_class_typerefs = { }
7302 object_class_classrefs = { }
7305 class _VariableTypeValueFieldSpec (AnyType):
7308 class _FixedTypeValueSetFieldSpec (AnyType):
7311 class_types_creator = {
7312 'BooleanType' : lambda : BooleanType(),
7313 'IntegerType' : lambda : IntegerType(),
7314 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
7315 'OpenType' : lambda : OpenType(),
7317 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
7318 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
7324 'TYPE-IDENTIFIER' : {
7326 'IDENTIFIED' : 'IDENTIFIED',
7328 'IDENTIFIED BY' : '&id',
7330 'ABSTRACT-SYNTAX' : {
7332 'IDENTIFIED' : 'IDENTIFIED',
7334 'IDENTIFIED BY' : '&id',
7336 'PROPERTY' : 'PROPERTY',
7337 'HAS PROPERTY' : '&property',
7341 class_syntaxes_enabled = {
7342 'TYPE-IDENTIFIER' : True,
7343 'ABSTRACT-SYNTAX' : True,
7347 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
7348 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
7351 class_current_syntax = None
7353 def get_syntax_tokens(syntaxes):
7355 for s in (syntaxes):
7356 for k in (list(syntaxes[s].keys())):
7359 tokens[k] = tokens[k].replace('-', '_')
7360 return list(tokens.values())
7362 tokens = tokens + get_syntax_tokens(x681_syntaxes)
7364 def set_class_syntax(syntax):
7365 global class_syntaxes_enabled
7366 global class_current_syntax
7367 #print "set_class_syntax", syntax, class_current_syntax
7368 if class_syntaxes_enabled.get(syntax, False):
7369 class_current_syntax = syntax
7372 class_current_syntax = None
7375 def is_class_syntax(name):
7376 global class_syntaxes
7377 global class_current_syntax
7378 #print "is_class_syntax", name, class_current_syntax
7379 if not class_current_syntax:
7381 return name in class_syntaxes[class_current_syntax]
7383 def get_class_fieled(name):
7384 if not class_current_syntax:
7386 return class_syntaxes[class_current_syntax][name]
7388 def is_class_ident(name):
7389 return name in class_names
7391 def add_class_ident(name):
7392 #print "add_class_ident", name
7393 class_names[name] = name
7395 def get_type_from_class(cls, fld):
7396 flds = fld.split('.')
7397 if (isinstance(cls, Class_Ref)):
7398 key = cls.val + '.' + flds[0]
7400 key = cls + '.' + flds[0]
7402 if key in object_class_classrefs:
7403 return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:]))
7405 if key in object_class_typerefs:
7406 return Type_Ref(val=object_class_typerefs[key])
7408 creator = lambda : AnyType()
7409 creator = useful_object_class_types.get(key, creator)
7410 creator = object_class_types.get(key, creator)
7413 def set_type_to_class(cls, fld, pars):
7414 #print "set_type_to_class", cls, fld, pars
7415 key = cls + '.' + fld
7416 typename = 'OpenType'
7420 pars.append(typename)
7423 if (isinstance(pars[1], Class_Ref)):
7424 pars[1] = pars[1].val
7428 if key in object_class_types:
7429 msg = object_class_types[key]().type
7430 if key in object_class_typerefs:
7431 msg = "TypeReference " + object_class_typerefs[key]
7432 if key in object_class_classrefs:
7433 msg = "ClassReference " + object_class_classrefs[key]
7435 if msg == ' '.join(pars):
7439 msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars))
7440 msg1 = "Already defined as '%s'" % (msg)
7441 raise CompError(msg0 + msg1)
7443 if (typename == 'ClassReference'):
7444 if not typeref: return False
7445 object_class_classrefs[key] = typeref
7448 if (typename == 'TypeReference'):
7449 if not typeref: return False
7450 object_class_typerefs[key] = typeref
7453 creator = class_types_creator.get(typename)
7455 object_class_types[key] = creator
7460 def import_class_from_module(mod, cls):
7461 add_class_ident(cls)
7462 mcls = "$%s$%s" % (mod, cls)
7463 for k in list(object_class_classrefs.keys()):
7464 kk = k.split('.', 1)
7466 object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k]
7467 for k in list(object_class_typerefs.keys()):
7468 kk = k.split('.', 1)
7470 object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k]
7471 for k in list(object_class_types.keys()):
7472 kk = k.split('.', 1)
7474 object_class_types[cls + '.' + kk[0]] = object_class_types[k]
7476 #--- ITU-T Recommendation X.682 -----------------------------------------------
7478 # 8 General constraint specification ------------------------------------------
7481 def p_GeneralConstraint (t):
7482 '''GeneralConstraint : UserDefinedConstraint
7484 | ContentsConstraint'''
7487 # 9 User-defined constraints --------------------------------------------------
7490 def p_UserDefinedConstraint (t):
7491 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7492 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
7494 def p_UserDefinedConstraintParameterList_1 (t):
7495 'UserDefinedConstraintParameterList : '
7498 def p_UserDefinedConstraintParameterList_2 (t):
7499 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7502 def p_UserDefinedConstraintParameterList_3 (t):
7503 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7504 t[0] = t[1] + [t[3]]
7507 def p_UserDefinedConstraintParameter (t):
7508 'UserDefinedConstraintParameter : Type'
7511 # 10 Table constraints, including component relation constraints --------------
7514 def p_TableConstraint (t):
7515 '''TableConstraint : SimpleTableConstraint
7516 | ComponentRelationConstraint'''
7517 t[0] = Constraint(type = 'Table', subtype = t[1])
7519 def p_SimpleTableConstraint (t):
7520 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7524 def p_ComponentRelationConstraint (t):
7525 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7526 t[0] = t[2] + str(t[5])
7528 def p_AtNotations_1 (t):
7529 'AtNotations : AtNotation'
7532 def p_AtNotations_2 (t):
7533 'AtNotations : AtNotations COMMA AtNotation'
7534 t[0] = t[1] + [t[3]]
7536 def p_AtNotation_1 (t):
7537 'AtNotation : AT ComponentIdList'
7540 def p_AtNotation_2 (t):
7541 'AtNotation : AT DOT Level ComponentIdList'
7542 t[0] = '@.' + t[3] + t[4]
7552 def p_ComponentIdList_1 (t):
7553 'ComponentIdList : LCASE_IDENT'
7556 def p_ComponentIdList_2 (t):
7557 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7558 t[0] = t[1] + '.' + t[3]
7560 # 11 Contents constraints -----------------------------------------------------
7563 def p_ContentsConstraint (t):
7564 'ContentsConstraint : CONTAINING type_ref'
7565 t[0] = Constraint(type = 'Contents', subtype = t[2])
7568 #--- ITU-T Recommendation X.683 -----------------------------------------------
7570 # 8 Parameterized assignments -------------------------------------------------
7573 def p_ParameterizedAssignment (t):
7574 '''ParameterizedAssignment : ParameterizedTypeAssignment
7575 | ParameterizedObjectClassAssignment
7576 | ParameterizedObjectAssignment
7577 | ParameterizedObjectSetAssignment'''
7581 def p_ParameterizedTypeAssignment (t):
7582 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7584 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
7586 def p_ParameterizedObjectClassAssignment (t):
7587 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7588 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7591 if isinstance(t[0], ObjectClassDefn):
7594 def p_ParameterizedObjectAssignment (t):
7595 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7596 t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
7600 def p_ParameterizedObjectSetAssignment (t):
7601 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7602 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
7605 def p_ParameterList (t):
7606 'ParameterList : lbraceignore rbraceignore'
7608 #def p_ParameterList (t):
7609 # 'ParameterList : LBRACE Parameters RBRACE'
7612 #def p_Parameters_1 (t):
7613 # 'Parameters : Parameter'
7616 #def p_Parameters_2 (t):
7617 # 'Parameters : Parameters COMMA Parameter'
7618 # t[0] = t[1] + [t[3]]
7620 #def p_Parameter_1 (t):
7621 # 'Parameter : Type COLON Reference'
7622 # t[0] = [t[1], t[3]]
7624 #def p_Parameter_2 (t):
7625 # 'Parameter : Reference'
7629 # 9 Referencing parameterized definitions -------------------------------------
7632 def p_ParameterizedReference (t):
7633 'ParameterizedReference : Reference LBRACE RBRACE'
7638 def p_ParameterizedType (t):
7639 'ParameterizedType : type_ref ActualParameterList'
7644 def p_ParameterizedObjectClass (t):
7645 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7649 def p_ParameterizedObject (t):
7650 'ParameterizedObject : DefinedObject ActualParameterList'
7655 def p_ActualParameterList (t):
7656 'ActualParameterList : lbraceignore rbraceignore'
7658 #def p_ActualParameterList (t):
7659 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7662 #def p_ActualParameters_1 (t):
7663 # 'ActualParameters : ActualParameter'
7666 #def p_ActualParameters_2 (t):
7667 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7668 # t[0] = t[1] + [t[3]]
7670 #def p_ActualParameter (t):
7671 # '''ActualParameter : Type
7676 #--- ITU-T Recommendation X.880 -----------------------------------------------
7680 '&ArgumentType' : [],
7681 '&argumentTypeOptional' : [ 'BooleanType' ],
7682 '&returnResult' : [ 'BooleanType' ],
7684 '&resultTypeOptional' : [ 'BooleanType' ],
7685 '&Errors' : [ 'ClassReference', 'ERROR' ],
7686 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7687 '&synchronous' : [ 'BooleanType' ],
7688 '&idempotent' : [ 'BooleanType' ],
7689 '&alwaysReturns' : [ 'BooleanType' ],
7690 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7691 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7692 '&operationCode' : [ 'TypeReference', 'Code' ],
7695 '&ParameterType' : [],
7696 '¶meterTypeOptional' : [ 'BooleanType' ],
7697 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7698 '&errorCode' : [ 'TypeReference', 'Code' ],
7700 'OPERATION-PACKAGE' : {
7701 '&Both' : [ 'ClassReference', 'OPERATION' ],
7702 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7703 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7704 '&id' : [ 'ObjectIdentifierType' ],
7706 'CONNECTION-PACKAGE' : {
7707 '&bind' : [ 'ClassReference', 'OPERATION' ],
7708 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7709 '&responderCanUnbind' : [ 'BooleanType' ],
7710 '&unbindCanFail' : [ 'BooleanType' ],
7711 '&id' : [ 'ObjectIdentifierType' ],
7714 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7715 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7716 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7717 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7718 '&id' : [ 'ObjectIdentifierType' ],
7720 'ROS-OBJECT-CLASS' : {
7721 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7722 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7723 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7724 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7725 '&id' : [ 'ObjectIdentifierType' ],
7731 'ARGUMENT' : '&ArgumentType',
7732 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7733 'RESULT' : '&ResultType',
7734 'RESULT OPTIONAL' : '&resultTypeOptional',
7735 'RETURN' : 'RETURN',
7736 'RETURN RESULT' : '&returnResult',
7737 'ERRORS' : '&Errors',
7738 'LINKED' : '&Linked',
7739 'SYNCHRONOUS' : '&synchronous',
7740 'IDEMPOTENT' : '&idempotent',
7741 'ALWAYS' : 'ALWAYS',
7742 'RESPONDS' : 'RESPONDS',
7743 'ALWAYS RESPONDS' : '&alwaysReturns',
7744 'INVOKE' : 'INVOKE',
7745 'PRIORITY' : 'PRIORITY',
7746 'INVOKE PRIORITY' : '&InvokePriority',
7747 'RESULT-PRIORITY': '&ResultPriority',
7748 'CODE' : '&operationCode',
7751 'PARAMETER' : '&ParameterType',
7752 'PARAMETER OPTIONAL' : '¶meterTypeOptional',
7753 'PRIORITY' : '&ErrorPriority',
7754 'CODE' : '&errorCode',
7756 # 'OPERATION-PACKAGE' : {
7758 # 'CONNECTION-PACKAGE' : {
7762 # 'ROS-OBJECT-CLASS' : {
7766 def x880_module_begin():
7767 #print "x880_module_begin()"
7768 for name in list(x880_classes.keys()):
7769 add_class_ident(name)
7771 def x880_import(name):
7772 if name in x880_syntaxes:
7773 class_syntaxes_enabled[name] = True
7774 class_syntaxes[name] = x880_syntaxes[name]
7775 if name in x880_classes:
7776 add_class_ident(name)
7777 for f in (list(x880_classes[name].keys())):
7778 set_type_to_class(name, f, x880_classes[name][f])
7780 tokens = tokens + get_syntax_tokens(x880_syntaxes)
7783 #def p_lbrace_oid(t):
7784 # 'lbrace_oid : brace_oid_begin LBRACE'
7787 #def p_brace_oid_begin(t):
7788 # 'brace_oid_begin : '
7792 #def p_rbrace_oid(t):
7793 # 'rbrace_oid : brace_oid_end RBRACE'
7796 #def p_brace_oid_end(t):
7797 # 'brace_oid_end : '
7801 # {...} block to be ignored
7802 def p_lbraceignore(t):
7803 'lbraceignore : braceignorebegin LBRACE'
7806 def p_braceignorebegin(t):
7807 'braceignorebegin : '
7810 lexer.push_state('braceignore')
7812 def p_rbraceignore(t):
7813 'rbraceignore : braceignoreend RBRACE'
7816 def p_braceignoreend(t):
7823 raise ParseError(t, input_file)
7826 '''pyquote : PYQUOTE'''
7827 t[0] = PyQuote (val = t[1])
7833 token = lexer.token ()
7839 def do_module (ast, defined_dict):
7840 assert (ast.type == 'Module')
7841 ctx = Ctx (defined_dict)
7842 print(ast.to_python (ctx))
7843 print(ctx.output_assignments ())
7844 print(ctx.output_pyquotes ())
7846 def eth_do_module (ast, ectx):
7847 assert (ast.type == 'Module')
7848 if ectx.dbg('s'): print(ast.str_depth(0))
7851 def testyacc(s, fn, defined_dict):
7852 ast = yacc.parse(s, debug=0)
7853 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
7854 print("""#!/usr/bin/env python
7855 # Auto-generated from %s at %s
7856 from PyZ3950 import asn1""" % (fn, time_str))
7858 eth_do_module (module, defined_dict)
7861 # Wireshark compiler
7864 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
7866 -b : BER (default is PER)
7867 -u : Unaligned (default is aligned)
7868 -p proto : Protocol name (implies -S). Default is module-name
7869 from input_file (renamed by #.MODULE if present)
7870 -o name : Output files name core (default is <proto>)
7871 -O dir : Output directory for dissector
7872 -c cnf_file : Conformance file
7873 -I path : Path for conformance file includes
7874 -e : Create conformance file for exported types
7875 -E : Just create conformance file for exported types
7876 -S : Single output for multiple modules
7877 -s template : Single file output (template is input file
7878 without .c/.h extension)
7879 -k : Keep intermediate files though single file output is used
7880 -L : Suppress #line directive from .cnf file
7881 -D dir : Directory for input_file(s) (default: '.')
7882 -C : Add check for SIZE constraints
7883 -r prefix : Remove the prefix from type names
7885 input_file(s) : Input ASN.1 file(s)
7887 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
7891 s - internal ASN.1 structure
7892 a - list of assignments
7894 c - conformance values
7895 m - list of compiled modules with dependency
7896 o - list of output files
7903 print("ASN.1 to Wireshark dissector compiler");
7905 opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLCr:");
7906 except getopt.GetoptError:
7907 eth_usage(); sys.exit(2)
7909 eth_usage(); sys.exit(2)
7914 ectx = EthCtx(conform, output)
7915 ectx.encoding = 'per'
7916 ectx.proto_opt = None
7918 ectx.tag_opt = False
7919 ectx.outnm_opt = None
7924 ectx.justexpcnf = False
7925 ectx.merge_modules = False
7926 ectx.group_by_prot = False
7927 ectx.conform.last_group = 0
7928 ectx.conform.suppress_line = False;
7929 ectx.output.outnm = None
7930 ectx.output.single_file = None
7931 ectx.constraints_check = False;
7933 if o in ("-h", "-?"):
7934 eth_usage(); sys.exit(2)
7938 ectx.conform.include_path.append(a)
7941 ectx.justexpcnf = True
7945 ectx.constraints_check = True
7947 warnings.warn("Command line option -X is obsolete and can be removed")
7949 warnings.warn("Command line option -T is obsolete and can be removed")
7952 ectx.conform.read(conf_to_read)
7955 if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-X", "-T"):
7956 pass # already processed
7960 ectx.conform.set_opt(o, par, "commandline", 0)
7962 (ld, yd, pd) = (0, 0, 0);
7963 if ectx.dbg('l'): ld = 1
7964 if ectx.dbg('y'): yd = 1
7965 if ectx.dbg('p'): pd = 2
7966 lexer = lex.lex(debug=ld)
7967 yacc.yacc(method='LALR', debug=yd)
7968 g_conform = ectx.conform
7973 if (ectx.srcdir): fn = ectx.srcdir + '/' + fn
7974 # Read ASN.1 definition, trying one of the common encodings.
7975 data = open(fn, "rb").read()
7976 for encoding in ('utf-8', 'windows-1252'):
7978 data = data.decode(encoding)
7981 warnings.warn_explicit("Decoding %s as %s failed, trying next." % (fn, encoding), UserWarning, '', 0)
7982 # Py2 compat, name.translate in eth_output_hf_arr fails with unicode
7983 if not isinstance(data, str):
7984 data = data.encode('utf-8')
7985 ast.extend(yacc.parse(data, lexer=lexer, debug=pd))
7987 if (ectx.merge_modules): # common output for all module
7990 eth_do_module(module, ectx)
7992 ectx.eth_do_output()
7993 elif (ectx.groups()): # group by protocols/group
7996 if (ectx.group_by_prot): # group by protocols
7998 prot = module.get_proto(ectx)
7999 if prot not in pr2gr:
8000 pr2gr[prot] = len(groups)
8002 groups[pr2gr[prot]].append(module)
8003 else: # group by groups
8008 eth_do_module(module, ectx)
8010 ectx.eth_do_output()
8011 else: # output for each module
8014 eth_do_module(module, ectx)
8016 ectx.eth_do_output()
8022 ectx.conform.dbg_print()
8023 if not ectx.justexpcnf:
8024 ectx.conform.unused_report()
8027 ectx.output.dbg_print()
8028 ectx.output.make_single_file()
8034 if len (sys.argv) == 1:
8036 s = input ('Query: ')
8039 testfn (s, 'console', {})
8042 for fn in sys.argv [1:]:
8044 testfn (f.read (), fn, defined_dict)
8049 #--- BODY ---------------------------------------------------------------------
8051 if __name__ == '__main__':
8052 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
8057 #------------------------------------------------------------------------------
8059 # Editor modelines - http://www.wireshark.org/tools/modelines.html
8061 # c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil
8062 # vi: set shiftwidth=4 tabstop=8 expandtab:
8063 # :indentSize=4:tabSize=8:noTabs=true: