5 # ASN.1 to Wireshark dissector compiler
11 """ASN.1 to Wireshark dissector compiler"""
14 # Compiler from ASN.1 specification to the Wireshark dissector
16 # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license
17 # http://www.pobox.com/~asl2/software/PyZ3950/
18 # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
20 # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
21 # http://www.dabeaz.com/ply/
24 # ITU-T Recommendation X.680 (07/2002),
25 # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
27 # ITU-T Recommendation X.681 (07/2002),
28 # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
30 # ITU-T Recommendation X.682 (07/2002),
31 # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
33 # ITU-T Recommendation X.683 (07/2002),
34 # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
36 # ITU-T Recommendation X.880 (07/1994),
37 # Information technology - Remote Operations: Concepts, model and notation
53 # OID name -> number conversion table
59 '0/recommendation' : 0,
88 '0/administration' : 2,
89 '0/network-operator' : 3,
90 '0/identified-organization' : 4,
91 '0/r-recommendation' : 5,
95 '1/registration-authority' : 1,
97 '1/identified-organization' : 3,
98 '/joint-iso-itu-t' : 2,
99 '/joint-iso-ccitt' : 2,
100 '2/presentation' : 0,
102 '2/association-control' : 2,
103 '2/reliable-transfer' : 3,
104 '2/remote-operations' : 4,
112 '2/osi-management' : 9,
113 '2/transaction-processing' : 10,
115 '2/distinguished-object-reference' : 11,
116 '2/reference-data-transfe' : 12,
117 '2/network-layer' : 13,
118 '2/network-layer-management' : 13,
119 '2/transport-layer' : 14,
120 '2/transport-layer-management' : 14,
121 '2/datalink-layer' : 15,
122 '2/datalink-layer-managemen' : 15,
123 '2/datalink-layer-management-information' : 15,
125 '2/registration-procedures' : 17,
126 '2/registration-procedure' : 17,
127 '2/physical-layer' : 18,
128 '2/physical-layer-management' : 18,
131 '2/generic-upper-layers-security' : 20,
133 '2/transport-layer-security-protocol' : 21,
134 '2/network-layer-security-protocol' : 22,
135 '2/international-organizations' : 23,
136 '2/internationalRA' : 23,
144 return id.replace('-', '_').replace('.', '_').replace('&', '_')
151 class LexError(Exception):
152 def __init__(self, tok, filename=None):
154 self.filename = filename
155 self.msg = "Unexpected character %r" % (self.tok.value[0])
156 Exception.__init__(self, self.msg)
158 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
162 class ParseError(Exception):
163 def __init__(self, tok, filename=None):
165 self.filename = filename
166 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
167 Exception.__init__(self, self.msg)
169 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
173 class DuplicateError(Exception):
174 def __init__(self, type, ident):
177 self.msg = "Duplicate %s for %s" % (self.type, self.ident)
178 Exception.__init__(self, self.msg)
183 class CompError(Exception):
184 def __init__(self, msg):
186 Exception.__init__(self, self.msg)
193 ('braceignore','exclusive'),
197 ('left', 'UNION', 'BAR'),
198 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
200 # 11 ASN.1 lexical items
203 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
204 r'\.\.' : 'RANGE', # 11.17 Range separator
205 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
206 #r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
207 #r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
208 # 11.26 Single character lexical items
223 #r"'" : 'APOSTROPHE',
226 r'\!' : 'EXCLAMATION',
227 r'\^' : 'CIRCUMFLEX',
232 # 11.27 Reserved words
234 # all keys in reserved_words must start w/ upper case
237 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
239 'APPLICATION' : 'APPLICATION',
240 'AUTOMATIC' : 'AUTOMATIC',
243 'BOOLEAN' : 'BOOLEAN',
245 'CHARACTER' : 'CHARACTER',
248 'COMPONENT' : 'COMPONENT',
249 'COMPONENTS' : 'COMPONENTS',
250 'CONSTRAINED' : 'CONSTRAINED',
251 'CONTAINING' : 'CONTAINING',
252 'DEFAULT' : 'DEFAULT',
253 'DEFINITIONS' : 'DEFINITIONS',
254 'EMBEDDED' : 'EMBEDDED',
255 # 'ENCODED' : 'ENCODED',
257 'ENUMERATED' : 'ENUMERATED',
258 # 'EXCEPT' : 'EXCEPT',
259 'EXPLICIT' : 'EXPLICIT',
260 'EXPORTS' : 'EXPORTS',
261 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
262 'EXTERNAL' : 'EXTERNAL',
265 'GeneralizedTime' : 'GeneralizedTime',
266 'IDENTIFIER' : 'IDENTIFIER',
267 'IMPLICIT' : 'IMPLICIT',
268 # 'IMPLIED' : 'IMPLIED',
269 'IMPORTS' : 'IMPORTS',
270 'INCLUDES' : 'INCLUDES',
271 'INSTANCE' : 'INSTANCE',
272 'INTEGER' : 'INTEGER',
273 'INTERSECTION' : 'INTERSECTION',
276 'MINUS-INFINITY' : 'MINUS_INFINITY',
279 'ObjectDescriptor' : 'ObjectDescriptor',
282 'OPTIONAL' : 'OPTIONAL',
283 'PATTERN' : 'PATTERN',
285 'PLUS-INFINITY' : 'PLUS_INFINITY',
286 'PRESENT' : 'PRESENT',
287 'PRIVATE' : 'PRIVATE',
289 'RELATIVE-OID' : 'RELATIVE_OID',
290 'SEQUENCE' : 'SEQUENCE',
297 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
300 'UNIVERSAL' : 'UNIVERSAL',
301 'UTCTime' : 'UTCTime',
303 # X.208 obsolete but still used
305 'DEFINED' : 'DEFINED',
308 for k in list(static_tokens.keys()):
309 if static_tokens [k] == None:
310 static_tokens [k] = k
312 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
313 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
316 for s in StringTypes:
317 reserved_words[s + 'String'] = s + 'String'
319 tokens = list(static_tokens.values()) \
320 + list(reserved_words.values()) \
321 + ['BSTRING', 'HSTRING', 'QSTRING',
322 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
323 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
326 cur_mod = __import__ (__name__) # XXX blech!
328 for (k, v) in list(static_tokens.items ()):
329 cur_mod.__dict__['t_' + v] = k
331 # 11.10 Binary strings
336 # 11.12 Hexadecimal strings
345 def t_UCASE_IDENT (t):
346 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
347 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
348 if (is_class_syntax(t.value)): t.type = t.value
349 t.type = reserved_words.get(t.value, t.type)
352 lcase_ident_assigned = {}
353 def t_LCASE_IDENT (t):
354 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
355 if (not in_oid and (t.value in lcase_ident_assigned)): t.type = 'LCASE_IDENT_ASSIGNED'
359 def t_REAL_NUMBER (t):
360 r"[0-9]+\.[0-9]*(?!\.)"
369 pyquote_str = 'PYQUOTE'
371 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
372 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
373 if t.value[2:2+len (pyquote_str)] == pyquote_str:
374 t.value = t.value[2+len(pyquote_str):]
375 t.value = t.value.lstrip ()
384 t.lexer.lineno += t.value.count("\n")
388 raise LexError(t, input_file)
390 # state 'braceignore'
392 def t_braceignore_lbrace(t):
396 def t_braceignore_rbrace(t):
399 # If closing brace, return token
400 if t.lexer.level == 0:
404 def t_braceignore_QSTRING (t):
406 t.lexer.lineno += t.value.count("\n")
408 def t_braceignore_COMMENT(t):
409 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
410 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
412 def t_braceignore_nonspace(t):
413 r'[^\s\{\}\"-]+|-(?!-)'
415 t_braceignore_ignore = " \t\r"
417 def t_braceignore_NEWLINE(t):
419 t.lexer.lineno += t.value.count("\n")
421 def t_braceignore_error(t):
425 def __init__ (self, defined_dict, indent = 0):
426 self.tags_def = 'EXPLICIT' # default = explicit
428 self.assignments = {}
429 self.dependencies = {}
431 self.defined_dict = defined_dict
434 return " " * (4 * self.indent_lev)
439 assert (self.indent_lev >= 0)
440 def register_assignment (self, ident, val, dependencies):
441 if ident in self.assignments:
442 raise DuplicateError("assignment", ident)
443 if ident in self.defined_dict:
444 raise "cross-module duplicates for " + ident
445 self.defined_dict [ident] = 1
446 self.assignments[ident] = val
447 self.dependencies [ident] = dependencies
449 # return "#%s depends on %s" % (ident, str (dependencies))
450 def register_pyquote (self, val):
451 self.pyquotes.append (val)
453 def output_assignments (self):
456 assign_keys = list(self.assignments.keys())
457 to_output_count = len (assign_keys)
460 for (ident, val) in list(self.assignments.items ()):
461 if ident in already_output:
464 for d in self.dependencies [ident]:
465 if ((d not in already_output) and
469 text_list.append ("%s=%s" % (ident,
470 self.assignments [ident]))
471 already_output [ident] = 1
474 assert (to_output_count >= 0)
476 if to_output_count == 0:
478 # OK, we detected a cycle
480 for ident in list(self.assignments.keys ()):
481 if ident not in already_output:
482 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
483 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
485 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
486 for (ident, val) in list(self.assignments.items ()):
487 if ident not in already_output:
488 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
491 return "\n".join (text_list)
492 def output_pyquotes (self):
493 return "\n".join (self.pyquotes)
494 def make_new_name (self):
496 return "_compiler_generated_name_%d" % (self.name_ctr,)
498 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
511 #--- common dependency computation ---
512 # Input : list of items
513 # dictionary with lists of dependency
516 # Output : list of two outputs:
517 # [0] list of items in dependency
518 # [1] list of cycle dependency cycles
519 def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False):
522 x = {} # already emitted
523 #print '# Dependency computation'
526 #print 'Continue: %s : %s' % (t, (map_fn(t))
529 stackx = {t : dependency.get(t, [])[:]}
530 #print 'Push: %s : %s' % (t, str(stackx[t]))
532 if stackx[stack[-1]]: # has dependencies
533 d = stackx[stack[-1]].pop(0)
534 if map_fn(d) in x or ignore_fn(d):
536 if d in stackx: # cyclic dependency
539 c = [d] + c[0:c.index(d)+1]
542 #print 'Cyclic: %s ' % (' -> '.join(c))
545 stackx[d] = dependency.get(d, [])[:]
546 #print 'Push: %s : %s' % (d, str(stackx[d]))
548 #print 'Pop: %s' % (stack[-1])
549 del stackx[stack[-1]]
550 e = map_fn(stack.pop())
553 #print 'Add: %s' % (e)
556 return (item_ord, item_cyc)
558 #--- EthCtx -------------------------------------------------------------------
560 def __init__(self, conform, output, indent = 0):
561 self.conform = conform
563 self.conform.ectx = self
564 self.output.ectx = self
565 self.encoding = 'per'
567 self.default_oid_variant = ''
568 self.default_opentype_variant = ''
569 self.default_containing_variant = '_pdu_new'
570 self.default_embedded_pdv_cb = None
571 self.default_external_type_cb = None
573 self.emitted_pdu = {}
576 self.all_type_attr = {}
580 def encp(self): # encoding protocol
585 def Per(self): return self.encoding == 'per'
586 def Ber(self): return self.encoding == 'ber'
587 def Aligned(self): return self.aligned
588 def Unaligned(self): return not self.aligned
589 def Tag(self): return self.tag_opt or self.Ber()
590 def NAPI(self): return False # disable planned features
592 def Module(self): # current module name
593 return self.modules[-1][0]
596 return self.group_by_prot or (self.conform.last_group > 0)
599 if (self.dbgopt.find(d) >= 0):
604 def value_max(self, a, b):
605 if (a == 'MAX') or (b == 'MAX'): return 'MAX';
606 if a == 'MIN': return b;
607 if b == 'MIN': return a;
609 if (int(a) > int(b)):
613 except (ValueError, TypeError):
615 return "MAX((%s),(%s))" % (a, b)
617 def value_min(self, a, b):
618 if (a == 'MIN') or (b == 'MIN'): return 'MIN';
619 if a == 'MAX': return b;
620 if b == 'MAX': return a;
622 if (int(a) < int(b)):
626 except (ValueError, TypeError):
628 return "MIN((%s),(%s))" % (a, b)
630 def value_get_eth(self, val):
631 if isinstance(val, Value):
632 return val.to_str(self)
634 if val in self.value:
635 ethname = self.value[val]['ethname']
638 def value_get_val(self, nm):
641 if self.value[nm]['import']:
642 v = self.get_val_from_all(nm, self.value[nm]['import'])
644 msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto'])
645 warnings.warn_explicit(msg, UserWarning, '', 0)
649 val = self.value[nm]['value']
650 if isinstance (val, Value):
651 val = val.to_str(self)
653 msg = 'Need value of unknown value identifier %s' % (nm)
654 warnings.warn_explicit(msg, UserWarning, '', 0)
657 def eth_get_type_attr(self, type):
658 #print "eth_get_type_attr(%s)" % (type)
660 while (not self.type[type]['import']):
661 val = self.type[type]['val']
664 while (val.type == 'TaggedType'):
667 if (val.type != 'Type_Ref'):
677 if (self.type[t]['import']):
678 attr.update(self.type[t]['attr'])
679 attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import']))
680 elif (self.type[t]['val'].type == 'SelectionType'):
681 val = self.type[t]['val']
682 (ftype, display) = val.eth_ftype(self)
683 attr.update({ 'TYPE' : ftype, 'DISPLAY' : display,
684 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' });
686 attr.update(self.type[t]['attr'])
687 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
691 def eth_get_type_attr_from_all(self, type, module):
693 if module in self.all_type_attr and type in self.all_type_attr[module]:
694 attr = self.all_type_attr[module][type]
697 def get_ttag_from_all(self, type, module):
699 if module in self.all_tags and type in self.all_tags[module]:
700 ttag = self.all_tags[module][type]
703 def get_val_from_all(self, nm, module):
705 if module in self.all_vals and nm in self.all_vals[module]:
706 val = self.all_vals[module][nm]
709 def get_obj_repr(self, ident, restr):
710 def set_type_fn(cls, field, fnfield):
711 obj[fnfield + '_fn'] = 'NULL'
712 obj[fnfield + '_pdu'] = 'NULL'
713 if field in val and isinstance(val[field], Type_Ref):
714 p = val[field].eth_type_default_pars(self, '')
715 obj[fnfield + '_fn'] = p['TYPE_REF_FN']
716 obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration
717 if (self.conform.check_item('PDU', cls + '.' + field)):
718 obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname']
720 # end of get_type_fn()
721 obj = { '_name' : ident, '_ident' : asn2c(ident)}
722 obj['_class'] = self.oassign[ident].cls
723 obj['_module'] = self.oassign[ident].module
724 val = self.oassign[ident].val
739 for f in list(val.keys()):
740 if isinstance(val[f], Node):
741 obj[f] = val[f].fld_obj_repr(self)
744 if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'):
745 set_type_fn(obj['_class'], '&Type', '_type')
746 if (obj['_class'] == 'OPERATION'):
747 set_type_fn(obj['_class'], '&ArgumentType', '_argument')
748 set_type_fn(obj['_class'], '&ResultType', '_result')
749 if (obj['_class'] == 'ERROR'):
750 set_type_fn(obj['_class'], '&ParameterType', '_parameter')
753 #--- eth_reg_module -----------------------------------------------------------
754 def eth_reg_module(self, module):
755 #print "eth_reg_module(module='%s')" % (module)
756 name = module.get_name()
757 self.modules.append([name, module.get_proto(self)])
758 if name in self.module:
759 raise DuplicateError("module", name)
760 self.module[name] = []
761 self.module_ord.append(name)
763 #--- eth_module_dep_add ------------------------------------------------------------
764 def eth_module_dep_add(self, module, dep):
765 self.module[module].append(dep)
767 #--- eth_exports ------------------------------------------------------------
768 def eth_exports(self, exports):
769 self.exports_all = False
770 if ((len(exports) == 1) and (exports[0] == 'ALL')):
771 self.exports_all = True
774 if isinstance(e, Type_Ref):
775 self.exports.append(e.val)
776 elif isinstance(e, Class_Ref):
777 self.cexports.append(e.val)
779 self.vexports.append(e)
781 #--- eth_reg_assign ---------------------------------------------------------
782 def eth_reg_assign(self, ident, val, virt=False):
783 #print "eth_reg_assign(ident='%s')" % (ident)
784 if ident in self.assign:
785 raise DuplicateError("assignment", ident)
786 self.assign[ident] = { 'val' : val , 'virt' : virt }
787 self.assign_ord.append(ident)
788 if (self.exports_all):
789 self.exports.append(ident)
791 #--- eth_reg_vassign --------------------------------------------------------
792 def eth_reg_vassign(self, vassign):
793 ident = vassign.ident
794 #print "eth_reg_vassign(ident='%s')" % (ident)
795 if ident in self.vassign:
796 raise DuplicateError("value assignment", ident)
797 self.vassign[ident] = vassign
798 self.vassign_ord.append(ident)
799 if (self.exports_all):
800 self.vexports.append(ident)
802 #--- eth_reg_oassign --------------------------------------------------------
803 def eth_reg_oassign(self, oassign):
804 ident = oassign.ident
805 #print "eth_reg_oassign(ident='%s')" % (ident)
806 if ident in self.oassign:
807 if self.oassign[ident] == oassign:
808 return # OK - already defined
810 raise DuplicateError("information object assignment", ident)
811 self.oassign[ident] = oassign
812 self.oassign_ord.append(ident)
813 self.oassign_cls.setdefault(oassign.cls, []).append(ident)
815 #--- eth_import_type --------------------------------------------------------
816 def eth_import_type(self, ident, mod, proto):
817 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
818 if ident in self.type:
819 #print "already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-'))
820 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
821 return # OK - already defined
822 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
823 return # OK - already imported
825 raise DuplicateError("type", ident)
826 self.type[ident] = {'import' : mod, 'proto' : proto,
828 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
829 'STRINGS' : 'NULL', 'BITMASK' : '0' }
830 mident = "$%s$%s" % (mod, ident)
831 if (self.conform.check_item('TYPE_ATTR', mident)):
832 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', mident))
834 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
835 if (self.conform.check_item('IMPORT_TAG', mident)):
836 self.conform.copy_item('IMPORT_TAG', ident, mident)
837 self.type_imp.append(ident)
839 #--- dummy_import_type --------------------------------------------------------
840 def dummy_import_type(self, ident):
842 if ident in self.type:
843 raise "Try to dummy import for existing type :" + ident
844 ethtype = asn2c(ident)
845 self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
846 'ethname' : ethtype }
847 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
848 'STRINGS' : 'NULL', 'BITMASK' : '0' }
849 self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
850 print "Dummy imported: %s (%s)" % (ident, ethtype)
853 #--- eth_import_class --------------------------------------------------------
854 def eth_import_class(self, ident, mod, proto):
855 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
856 if ident in self.objectclass:
857 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
858 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
859 return # OK - already defined
860 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
861 return # OK - already imported
863 raise DuplicateError("object class", ident)
864 self.objectclass[ident] = {'import' : mod, 'proto' : proto,
866 self.objectclass_imp.append(ident)
868 #--- eth_import_value -------------------------------------------------------
869 def eth_import_value(self, ident, mod, proto):
870 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
871 if ident in self.value:
872 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
873 if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) :
874 return # OK - already defined
875 elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) :
876 return # OK - already imported
878 raise DuplicateError("value", ident)
879 self.value[ident] = {'import' : mod, 'proto' : proto,
881 self.value_imp.append(ident)
883 #--- eth_sel_req ------------------------------------------------------------
884 def eth_sel_req(self, typ, sel):
885 key = typ + '.' + sel
886 if key not in self.sel_req:
887 self.sel_req[key] = { 'typ' : typ , 'sel' : sel}
888 self.sel_req_ord.append(key)
891 #--- eth_comp_req ------------------------------------------------------------
892 def eth_comp_req(self, type):
893 self.comp_req_ord.append(type)
895 #--- eth_dep_add ------------------------------------------------------------
896 def eth_dep_add(self, type, dep):
897 if type not in self.type_dep:
898 self.type_dep[type] = []
899 self.type_dep[type].append(dep)
901 #--- eth_reg_type -----------------------------------------------------------
902 def eth_reg_type(self, ident, val):
903 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
904 if ident in self.type:
905 if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) :
906 # replace imported type
908 self.type_imp.remove(ident)
910 raise DuplicateError("type", ident)
911 self.type[ident] = { 'val' : val, 'import' : None }
912 self.type[ident]['module'] = self.Module()
913 self.type[ident]['proto'] = self.proto
914 if len(ident.split('/')) > 1:
915 self.type[ident]['tname'] = val.eth_tname()
917 self.type[ident]['tname'] = asn2c(ident)
918 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
919 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
920 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
921 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
922 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
923 self.type[ident]['ethname'] = ''
924 if (val.type == 'Type_Ref') or (val.type == 'TaggedType') or (val.type == 'SelectionType') :
925 self.type[ident]['attr'] = {}
927 (ftype, display) = val.eth_ftype(self)
928 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
929 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
930 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
931 self.type_ord.append(ident)
933 if (self.conform.check_item('PDU', ident)):
934 self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident))
936 #--- eth_reg_objectclass ----------------------------------------------------------
937 def eth_reg_objectclass(self, ident, val):
938 #print "eth_reg_objectclass(ident='%s')" % (ident)
939 if ident in self.objectclass:
940 if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) :
941 # replace imported object class
942 del self.objectclass[ident]
943 self.objectclass_imp.remove(ident)
944 elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \
945 isinstance(val, Class_Ref) and \
946 (self.objectclass[ident]['val'].val == val.val):
947 pass # ignore duplicated CLASS1 ::= CLASS2
949 raise DuplicateError("object class", ident)
950 self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto }
951 self.objectclass[ident]['val'] = val
952 self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident)
953 self.objectclass_ord.append(ident)
955 #--- eth_reg_value ----------------------------------------------------------
956 def eth_reg_value(self, ident, type, value, ethname=None):
957 #print "eth_reg_value(ident='%s')" % (ident)
958 if ident in self.value:
959 if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) :
960 # replace imported value
961 del self.value[ident]
962 self.value_imp.remove(ident)
964 self.value[ident]['ethname'] = ethname
967 raise DuplicateError("value", ident)
968 self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto,
969 'type' : type, 'value' : value,
971 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
972 self.value[ident]['ethname'] = ''
973 if (ethname): self.value[ident]['ethname'] = ethname
974 self.value_ord.append(ident)
976 #--- eth_reg_field ----------------------------------------------------------
977 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
978 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
979 if ident in self.field:
980 if pdu and (type == self.field[ident]['type']):
981 pass # OK already created PDU
983 raise DuplicateError("field", ident)
984 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
985 'modified' : '', 'attr' : {} }
986 name = ident.split('/')[-1]
987 if len(ident.split('/')) > 1 and name == '_item': # Sequence/Set of type
988 if len(self.field[ident]['type'].split('/')) > 1:
989 self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2]
990 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
992 self.field[ident]['attr']['NAME'] = '"%s"' % self.field[ident]['type']
993 self.field[ident]['attr']['ABBREV'] = asn2c(self.field[ident]['type'])
995 self.field[ident]['attr']['NAME'] = '"%s"' % name
996 self.field[ident]['attr']['ABBREV'] = asn2c(name)
997 if self.conform.check_item('FIELD_ATTR', ident):
998 self.field[ident]['modified'] = '#' + str(id(self))
999 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
1001 self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0)
1002 self.pdu_ord.append(ident)
1004 self.field_ord.append(ident)
1006 self.eth_dep_add(parent, type)
1008 #--- eth_clean --------------------------------------------------------------
1009 def eth_clean(self):
1010 self.proto = self.proto_opt;
1011 #--- ASN.1 tables ----------------
1013 self.assign_ord = []
1022 self.sel_req_ord = []
1023 self.comp_req_ord = []
1025 self.vassign_ord = []
1029 self.objectclass = {}
1030 self.objectclass_ord = []
1031 self.objectclass_imp = []
1033 self.oassign_ord = []
1034 self.oassign_cls = {}
1035 #--- Modules ------------
1037 self.exports_all = False
1041 #--- types -------------------
1043 self.eth_type_ord = []
1044 self.eth_export_ord = []
1045 self.eth_type_dupl = {}
1047 #--- value dependencies -------------------
1049 #--- values -------------------
1051 self.eth_value_ord = []
1052 #--- fields -------------------------
1054 self.eth_hf_ord = []
1055 self.eth_hfpdu_ord = []
1056 self.eth_hf_dupl = {}
1057 #--- type dependencies -------------------
1058 self.eth_type_ord1 = []
1059 self.eth_dep_cycle = []
1060 self.dep_cycle_eth_type = {}
1061 #--- value dependencies and export -------------------
1062 self.eth_value_ord1 = []
1063 self.eth_vexport_ord = []
1065 #--- eth_prepare ------------------------------------------------------------
1066 def eth_prepare(self):
1067 self.eproto = asn2c(self.proto)
1069 #--- dummy types/fields for PDU registration ---
1071 if (self.conform.check_item('PDU', nm)):
1072 self.eth_reg_type('_dummy/'+nm, NullType())
1073 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
1075 #--- required PDUs ----------------------------
1076 for t in self.type_ord:
1077 pdu = self.type[t]['val'].eth_need_pdu(self)
1078 if not pdu: continue
1081 pdu['hidden'] = False
1082 pdu['need_decl'] = True
1083 if f not in self.field:
1084 self.eth_reg_field(f, f, pdu=pdu)
1086 #--- values -> named values -------------------
1088 for v in self.value_ord:
1089 if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1090 if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1091 tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v)
1093 tnm = self.value[v]['type'].val
1094 if tnm in self.type \
1095 and not self.type[tnm]['import'] \
1096 and (self.type[tnm]['val'].type == 'IntegerType'):
1097 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
1098 self.value[v]['no_emit'] = True
1099 t_for_update[tnm] = True
1100 for t in list(t_for_update.keys()):
1101 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
1102 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
1104 #--- required components of ---------------------------
1105 #print "self.comp_req_ord = ", self.comp_req_ord
1106 for t in self.comp_req_ord:
1107 self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
1109 #--- required selection types ---------------------------
1110 #print "self.sel_req_ord = ", self.sel_req_ord
1111 for t in self.sel_req_ord:
1112 tt = self.sel_req[t]['typ']
1113 if tt not in self.type:
1114 self.dummy_import_type(t)
1115 elif self.type[tt]['import']:
1116 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
1118 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
1120 #--- types -------------------
1121 for t in self.type_imp:
1123 self.eth_type[nm] = { 'import' : self.type[t]['import'],
1124 'proto' : asn2c(self.type[t]['proto']),
1125 'attr' : {}, 'ref' : []}
1126 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1127 self.type[t]['ethname'] = nm
1128 for t in self.type_ord:
1129 nm = self.type[t]['tname']
1130 if ((nm.find('#') >= 0) or
1131 ((len(t.split('/'))>1) and
1132 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or
1133 self.conform.get_fn_presence('/'.join((t,'_item'))) or self.conform.check_item('FN_PARS', '/'.join((t,'_item')))) and
1134 not self.conform.check_item('TYPE_RENAME', t))):
1135 if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequence of type at the 1st level
1136 nm = t.split('/')[0] + t.split('/')[1]
1137 elif t.split('/')[-1] == '_item': # Sequence/Set of type at next levels
1138 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
1139 elif t.split('/')[-1] == '_untag': # Untagged type
1140 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
1142 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
1144 if nm in self.eth_type:
1145 if nm in self.eth_type_dupl:
1146 self.eth_type_dupl[nm].append(t)
1148 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
1149 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
1150 if nm in self.eth_type:
1151 self.eth_type[nm]['ref'].append(t)
1153 self.eth_type_ord.append(nm)
1154 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
1155 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
1156 'val' : self.type[t]['val'],
1157 'attr' : {}, 'ref' : [t]}
1158 self.type[t]['ethname'] = nm
1159 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
1160 self.eth_export_ord.append(nm)
1161 self.eth_type[nm]['export'] |= self.type[t]['export']
1162 self.eth_type[nm]['enum'] |= self.type[t]['enum']
1163 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
1164 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
1165 if self.type[t]['attr'].get('STRINGS') == '$$':
1166 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
1167 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1168 for t in self.eth_type_ord:
1169 bits = self.eth_type[t]['val'].eth_named_bits()
1171 for (val, id) in bits:
1172 self.named_bit.append({'name' : id, 'val' : val,
1173 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
1174 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1176 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
1177 if self.eth_type[t]['val'].eth_need_tree():
1178 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
1180 self.eth_type[t]['tree'] = None
1182 #--- register values from enums ------------
1183 for t in self.eth_type_ord:
1184 if (self.eth_type[t]['val'].eth_has_enum(t, self)):
1185 self.eth_type[t]['val'].reg_enum_vals(t, self)
1187 #--- value dependencies -------------------
1188 for v in self.value_ord:
1189 if isinstance (self.value[v]['value'], Value):
1190 dep = self.value[v]['value'].get_dep()
1192 dep = self.value[v]['value']
1193 if dep and dep in self.value:
1194 self.value_dep.setdefault(v, []).append(dep)
1196 #--- exports all necessary values
1197 for v in self.value_ord:
1198 if not self.value[v]['export']: continue
1199 deparr = self.value_dep.get(v, [])
1202 if not self.value[d]['import']:
1203 if not self.value[d]['export']:
1204 self.value[d]['export'] = EF_TYPE
1205 deparr.extend(self.value_dep.get(d, []))
1207 #--- values -------------------
1208 for v in self.value_imp:
1210 self.eth_value[nm] = { 'import' : self.value[v]['import'],
1211 'proto' : asn2c(self.value[v]['proto']),
1213 self.value[v]['ethname'] = nm
1214 for v in self.value_ord:
1215 if (self.value[v]['ethname']):
1217 if (self.value[v]['no_emit']):
1220 self.eth_value[nm] = { 'import' : None,
1221 'proto' : asn2c(self.value[v]['proto']),
1222 'export' : self.value[v]['export'], 'ref' : [v] }
1223 self.eth_value[nm]['value'] = self.value[v]['value']
1224 self.eth_value_ord.append(nm)
1225 self.value[v]['ethname'] = nm
1227 #--- fields -------------------------
1228 for f in (self.pdu_ord + self.field_ord):
1229 if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequence/Set of type
1230 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
1232 nm = f.split('/')[-1]
1233 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
1235 if (self.field[f]['pdu']):
1237 if (not self.merge_modules or self.field[f]['pdu']['export']):
1238 nm = self.eproto + '_' + nm
1239 t = self.field[f]['type']
1241 ethtype = self.type[t]['ethname']
1242 else: # undefined type
1243 ethtype = self.dummy_import_type(t)
1244 ethtypemod = ethtype + self.field[f]['modified']
1245 if nm in self.eth_hf:
1246 if nm in self.eth_hf_dupl:
1247 if ethtypemod in self.eth_hf_dupl[nm]:
1248 nm = self.eth_hf_dupl[nm][ethtypemod]
1249 self.eth_hf[nm]['ref'].append(f)
1250 self.field[f]['ethname'] = nm
1253 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
1254 self.eth_hf_dupl[nm][ethtype] = nmx
1257 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
1258 self.eth_hf[nm]['ref'].append(f)
1259 self.field[f]['ethname'] = nm
1263 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
1266 if (self.field[f]['pdu']):
1267 self.eth_hfpdu_ord.append(nm)
1269 self.eth_hf_ord.append(nm)
1270 fullname = 'hf_%s_%s' % (self.eproto, nm)
1271 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
1272 attr.update(self.field[f]['attr'])
1273 if (self.NAPI() and 'NAME' in attr):
1274 attr['NAME'] += self.field[f]['idx']
1275 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
1276 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
1277 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
1278 'attr' : attr.copy(),
1280 self.field[f]['ethname'] = nm
1281 #--- type dependencies -------------------
1282 (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'])
1284 while i < len(self.eth_dep_cycle):
1285 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1286 self.dep_cycle_eth_type.setdefault(t, []).append(i)
1289 #--- value dependencies and export -------------------
1290 for v in self.eth_value_ord:
1291 if self.eth_value[v]['export']:
1292 self.eth_vexport_ord.append(v)
1294 self.eth_value_ord1.append(v)
1296 #--- export tags, values, ... ---
1297 for t in self.exports:
1298 if t not in self.type:
1300 if self.type[t]['import']:
1302 m = self.type[t]['module']
1304 if m not in self.all_tags:
1305 self.all_tags[m] = {}
1306 self.all_tags[m][t] = self.type[t]['val'].GetTTag(self)
1307 if m not in self.all_type_attr:
1308 self.all_type_attr[m] = {}
1309 self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy()
1310 for v in self.vexports:
1311 if v not in self.value:
1313 if self.value[v]['import']:
1315 m = self.value[v]['module']
1316 if m not in self.all_vals:
1317 self.all_vals[m] = {}
1318 vv = self.value[v]['value']
1319 if isinstance (vv, Value):
1320 vv = vv.to_str(self)
1321 self.all_vals[m][v] = vv
1323 #--- eth_vals_nm ------------------------------------------------------------
1324 def eth_vals_nm(self, tname):
1326 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
1327 out += "%s_" % (self.eproto)
1328 out += "%s_vals" % (tname)
1331 #--- eth_vals ---------------------------------------------------------------
1332 def eth_vals(self, tname, vals):
1334 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
1335 if (not self.eth_type[tname]['export'] & EF_VALS):
1337 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
1339 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
1340 for (val, id) in vals:
1342 vval = self.eth_enum_item(tname, id)
1345 out += ' { %3s, "%s" },\n' % (vval, id)
1346 out += " { 0, NULL }\n};\n"
1349 #--- eth_enum_prefix ------------------------------------------------------------
1350 def eth_enum_prefix(self, tname, type=False):
1352 if (self.eth_type[tname]['export'] & EF_ENUM):
1353 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
1355 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
1358 if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type):
1359 if (out): out += '_'
1361 if (self.eth_type[tname]['enum'] & EF_UCASE):
1363 if (out): out += '_'
1366 #--- eth_enum_nm ------------------------------------------------------------
1367 def eth_enum_nm(self, tname):
1368 out = self.eth_enum_prefix(tname, type=True)
1372 #--- eth_enum_item ---------------------------------------------------------------
1373 def eth_enum_item(self, tname, ident):
1374 out = self.eth_enum_prefix(tname)
1376 if (self.eth_type[tname]['enum'] & EF_UCASE):
1380 #--- eth_enum ---------------------------------------------------------------
1381 def eth_enum(self, tname, vals):
1383 if (self.eth_type[tname]['enum'] & EF_DEFINE):
1384 out += "/* enumerated values for %s */\n" % (tname)
1385 for (val, id) in vals:
1386 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
1388 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
1390 for (val, id) in vals:
1391 if (first_line == 1):
1395 out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val)
1396 out += "\n} %s;\n" % (self.eth_enum_nm(tname))
1399 #--- eth_bits ---------------------------------------------------------------
1400 def eth_bits(self, tname, bits):
1402 out += "static const "
1403 out += "asn_namedbit %(TABLE)s[] = {\n"
1404 for (val, id) in bits:
1405 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
1406 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
1409 #--- eth_type_fn_h ----------------------------------------------------------
1410 def eth_type_fn_h(self, tname):
1412 if (not self.eth_type[tname]['export'] & EF_TYPE):
1416 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)
1418 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)
1422 #--- eth_fn_call ------------------------------------------------------------
1423 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
1426 if (ret == 'return'):
1432 for i in range(len(par)):
1433 if (i>0): out += ind * ' '
1434 out += ', '.join(par[i])
1435 if (i<(len(par)-1)): out += ',\n'
1439 #--- eth_type_fn_hdr --------------------------------------------------------
1440 def eth_type_fn_hdr(self, tname):
1442 if (not self.eth_type[tname]['export'] & EF_TYPE):
1446 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)
1448 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)
1449 #if self.conform.get_fn_presence(tname):
1450 # out += self.conform.get_fn_text(tname, 'FN_HDR')
1452 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1453 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1456 #--- eth_type_fn_ftr --------------------------------------------------------
1457 def eth_type_fn_ftr(self, tname):
1459 #if self.conform.get_fn_presence(tname):
1460 # out += self.conform.get_fn_text(tname, 'FN_FTR')
1462 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1463 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1464 out += " return offset;\n"
1468 #--- eth_type_fn_body -------------------------------------------------------
1469 def eth_type_fn_body(self, tname, body, pars=None):
1471 #if self.conform.get_fn_body_presence(tname):
1472 # out = self.conform.get_fn_text(tname, 'FN_BODY')
1474 if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1475 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1483 #--- eth_out_pdu_decl ----------------------------------------------------------
1484 def eth_out_pdu_decl(self, f):
1485 t = self.eth_hf[f]['ethtype']
1486 is_new = self.eth_hf[f]['pdu']['new']
1488 if (not self.eth_hf[f]['pdu']['export']):
1494 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);\n'
1497 #--- eth_output_hf ----------------------------------------------------------
1498 def eth_output_hf (self):
1499 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1500 fx = self.output.file_open('hf')
1501 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1502 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1503 if (self.named_bit):
1504 fx.write('/* named bits */\n')
1505 for nb in self.named_bit:
1506 fx.write("static int %s = -1;\n" % (nb['ethname']))
1507 self.output.file_close(fx)
1509 #--- eth_output_hf_arr ------------------------------------------------------
1510 def eth_output_hf_arr (self):
1511 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1512 fx = self.output.file_open('hfarr')
1513 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1514 t = self.eth_hf[f]['ethtype']
1515 blurb = '"%s.%s"' % (self.eth_type[t]['proto'], t)
1516 attr = self.eth_hf[f]['attr'].copy()
1517 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1518 if 'BLURB' not in attr:
1519 attr['BLURB'] = blurb
1520 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1521 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1522 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1523 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1524 for nb in self.named_bit:
1525 fx.write(' { &%s,\n' % (nb['ethname']))
1526 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1527 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1528 fx.write(' NULL, HFILL }},\n')
1529 self.output.file_close(fx)
1531 #--- eth_output_ett ---------------------------------------------------------
1532 def eth_output_ett (self):
1533 fx = self.output.file_open('ett')
1535 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1536 for t in self.eth_type_ord:
1537 if self.eth_type[t]['tree']:
1538 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1540 self.output.file_close(fx, discard=fempty)
1542 #--- eth_output_ett_arr -----------------------------------------------------
1543 def eth_output_ett_arr(self):
1544 fx = self.output.file_open('ettarr')
1546 #fx.write(" &ett_%s,\n" % (self.eproto))
1547 for t in self.eth_type_ord:
1548 if self.eth_type[t]['tree']:
1549 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1551 self.output.file_close(fx, discard=fempty)
1553 #--- eth_output_export ------------------------------------------------------
1554 def eth_output_export(self):
1555 if (not len(self.eth_export_ord)): return
1556 fx = self.output.file_open('exp', ext='h')
1557 for t in self.eth_export_ord: # vals
1558 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1559 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1560 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1561 if not self.eth_type[t]['export'] & EF_TABLE:
1562 if self.eth_type[t]['export'] & EF_WS_VAR:
1563 fx.write("WS_VAR_IMPORT ")
1566 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1568 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1569 for t in self.eth_export_ord: # functions
1570 if (self.eth_type[t]['export'] & EF_TYPE):
1571 if self.eth_type[t]['export'] & EF_EXTERN:
1573 fx.write(self.eth_type_fn_h(t))
1574 for f in self.eth_hfpdu_ord: # PDUs
1575 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']):
1576 fx.write(self.eth_out_pdu_decl(f))
1577 self.output.file_close(fx)
1579 #--- eth_output_expcnf ------------------------------------------------------
1580 def eth_output_expcnf(self):
1581 fx = self.output.file_open('exp', ext='cnf')
1582 fx.write('#.MODULE\n')
1584 for (m, p) in self.modules:
1585 if (len(m) > maxw): maxw = len(m)
1586 for (m, p) in self.modules:
1587 fx.write("%-*s %s\n" % (maxw, m, p))
1588 fx.write('#.END\n\n')
1589 for cls in self.objectclass_ord:
1590 if self.objectclass[cls]['export']:
1592 if self.objectclass[cls]['export'] & EF_MODULE:
1593 cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm)
1594 fx.write('#.CLASS %s\n' % (cnm))
1596 for fld in self.objectclass[cls]['val'].fields:
1597 w = len(fld.fld_repr()[0])
1598 if (w > maxw): maxw = w
1599 for fld in self.objectclass[cls]['val'].fields:
1600 repr = fld.fld_repr()
1601 fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:])))
1602 fx.write('#.END\n\n')
1604 fx.write('#.IMPORT_TAG\n')
1605 for t in self.eth_export_ord: # tags
1606 if (self.eth_type[t]['export'] & EF_TYPE):
1607 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1608 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1609 fx.write('#.END\n\n')
1610 fx.write('#.TYPE_ATTR\n')
1611 for t in self.eth_export_ord: # attributes
1612 if (self.eth_type[t]['export'] & EF_TYPE):
1613 tnm = self.eth_type[t]['ref'][0]
1614 if self.eth_type[t]['export'] & EF_MODULE:
1615 tnm = "$%s$%s" % (self.type[tnm]['module'], tnm)
1616 fx.write('%-24s ' % tnm)
1617 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1618 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1619 fx.write('#.END\n\n')
1620 self.output.file_close(fx, keep_anyway=True)
1622 #--- eth_output_val ------------------------------------------------------
1623 def eth_output_val(self):
1624 fx = self.output.file_open('val', ext='h')
1625 for v in self.eth_value_ord1:
1626 vv = self.eth_value[v]['value']
1627 if isinstance (vv, Value):
1628 vv = vv.to_str(self)
1629 fx.write("#define %-30s %s\n" % (v, vv))
1630 for t in self.eth_type_ord1:
1631 if self.eth_type[t]['import']:
1633 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1634 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1635 self.output.file_close(fx)
1637 #--- eth_output_valexp ------------------------------------------------------
1638 def eth_output_valexp(self):
1639 if (not len(self.eth_vexport_ord)): return
1640 fx = self.output.file_open('valexp', ext='h')
1641 for v in self.eth_vexport_ord:
1642 vv = self.eth_value[v]['value']
1643 if isinstance (vv, Value):
1644 vv = vv.to_str(self)
1645 fx.write("#define %-30s %s\n" % (v, vv))
1646 self.output.file_close(fx)
1648 #--- eth_output_types -------------------------------------------------------
1649 def eth_output_types(self):
1651 t = self.eth_hf[f]['ethtype']
1652 is_new = self.eth_hf[f]['pdu']['new']
1655 if (not self.eth_hf[f]['pdu']['export']):
1661 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1663 out += ' int offset = 0;\n'
1670 if (self.Aligned()):
1674 out += " asn1_ctx_t asn1_ctx;\n"
1675 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1677 out += " asn1_ctx_t asn1_ctx;\n"
1678 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
1679 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1681 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1684 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1685 if (self.Per() and is_new):
1686 out += ' offset += 7; offset >>= 3;\n'
1688 out += ' return offset;\n'
1692 fx = self.output.file_open('fn')
1694 if (len(self.eth_hfpdu_ord)):
1696 for f in self.eth_hfpdu_ord:
1697 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
1699 fx.write('/*--- PDUs declarations ---*/\n')
1701 fx.write(self.eth_out_pdu_decl(f))
1704 if self.eth_dep_cycle:
1705 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1707 while i < len(self.eth_dep_cycle):
1708 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1709 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1710 fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]]))
1711 fx.write(self.eth_type_fn_h(t))
1715 for t in self.eth_type_ord1:
1716 if self.eth_type[t]['import']:
1718 if self.eth_type[t]['val'].eth_has_vals():
1719 if self.eth_type[t]['no_emit'] & EF_VALS:
1721 elif self.eth_type[t]['user_def'] & EF_VALS:
1722 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1723 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1726 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1727 if self.eth_type[t]['no_emit'] & EF_TYPE:
1729 elif self.eth_type[t]['user_def'] & EF_TYPE:
1730 fx.write(self.eth_type_fn_h(t))
1732 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1734 if (len(self.eth_hfpdu_ord)):
1735 fx.write('/*--- PDUs ---*/\n\n')
1736 for f in self.eth_hfpdu_ord:
1737 if (self.eth_hf[f]['pdu']):
1738 if (f in self.emitted_pdu):
1739 fx.write(" /* %s already emitted */\n" % (f))
1741 fx.write(out_pdu(f))
1742 self.emitted_pdu[f] = True
1744 fempty = pos == fx.tell()
1745 self.output.file_close(fx, discard=fempty)
1747 #--- eth_output_dis_hnd -----------------------------------------------------
1748 def eth_output_dis_hnd(self):
1749 fx = self.output.file_open('dis-hnd')
1751 for f in self.eth_hfpdu_ord:
1752 pdu = self.eth_hf[f]['pdu']
1753 if (pdu and pdu['reg'] and not pdu['hidden']):
1755 if (pdu['reg'] != '.'):
1756 dis += '.' + pdu['reg']
1757 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1760 self.output.file_close(fx, discard=fempty)
1762 #--- eth_output_dis_reg -----------------------------------------------------
1763 def eth_output_dis_reg(self):
1764 fx = self.output.file_open('dis-reg')
1766 for f in self.eth_hfpdu_ord:
1767 pdu = self.eth_hf[f]['pdu']
1768 if (pdu and pdu['reg']):
1770 if (pdu['new']): new_prefix = 'new_'
1772 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1773 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1774 if (not pdu['hidden']):
1775 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1778 self.output.file_close(fx, discard=fempty)
1780 #--- eth_output_dis_tab -----------------------------------------------------
1781 def eth_output_dis_tab(self):
1782 fx = self.output.file_open('dis-tab')
1784 for k in self.conform.get_order('REGISTER'):
1785 reg = self.conform.use_item('REGISTER', k)
1786 if reg['pdu'] not in self.field: continue
1787 f = self.field[reg['pdu']]['ethname']
1788 pdu = self.eth_hf[f]['pdu']
1790 if (pdu['new']): new_prefix = 'new_'
1791 if (reg['rtype'] in ('NUM', 'STR')):
1793 if (reg['rtype'] == 'STR'): rstr = '_string'
1796 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1797 if (not pdu['hidden']):
1798 hnd = '%s_handle' % (asn2c(dis))
1800 hnd = 'find_dissector("%s")' % (dis)
1802 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1803 rport = self.value_get_eth(reg['rport'])
1804 fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
1805 elif (reg['rtype'] in ('BER', 'PER')):
1806 roid = self.value_get_eth(reg['roid'])
1807 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
1810 self.output.file_close(fx, discard=fempty)
1812 #--- eth_output_table -----------------------------------------------------
1813 def eth_output_table(self):
1814 for num in list(self.conform.report.keys()):
1815 fx = self.output.file_open('table' + num)
1816 for rep in self.conform.report[num]:
1817 if rep['type'] == 'HDR':
1821 var_list = var.split('.')
1824 if (cls in self.oassign_cls):
1825 for ident in self.oassign_cls[cls]:
1826 obj = self.get_obj_repr(ident, var_list)
1830 obj['_DICT'] = str(obj)
1832 text = rep['text'] % obj
1834 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)
1837 fx.write("/* Unknown or empty loop list %s */\n" % (var))
1839 fx.write(rep['text'])
1840 if rep['type'] == 'FTR':
1842 self.output.file_close(fx)
1844 #--- dupl_report -----------------------------------------------------
1845 def dupl_report(self):
1847 tmplist = sorted(self.eth_type_dupl.keys())
1849 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
1851 for tt in self.eth_type_dupl[t]:
1852 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
1853 warnings.warn_explicit(msg, UserWarning, '', 0)
1855 tmplist = list(self.eth_hf_dupl.keys())
1858 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
1860 for tt in list(self.eth_hf_dupl[f].keys()):
1861 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
1862 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
1864 warnings.warn_explicit(msg, UserWarning, '', 0)
1866 #--- eth_do_output ------------------------------------------------------------
1867 def eth_do_output(self):
1869 print "\n# Assignments"
1870 for a in self.assign_ord:
1872 if (self.assign[a]['virt']): v = '*'
1874 print "\n# Value assignments"
1875 for a in self.vassign_ord:
1877 print "\n# Information object assignments"
1878 for a in self.oassign_ord:
1879 print " %-12s (%s)" % (a, self.oassign[a].cls)
1881 print "\n# Imported Types"
1882 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1884 for t in self.type_imp:
1885 print "%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])
1886 print "\n# Imported Values"
1887 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1889 for t in self.value_imp:
1890 print "%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])
1891 print "\n# Imported Object Classes"
1892 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1894 for t in self.objectclass_imp:
1895 print "%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto'])
1896 print "\n# Exported Types"
1897 print "%-31s %s" % ("Wireshark type", "Export Flag")
1899 for t in self.eth_export_ord:
1900 print "%-31s 0x%02X" % (t, self.eth_type[t]['export'])
1901 print "\n# Exported Values"
1902 print "%-40s %s" % ("Wireshark name", "Value")
1904 for v in self.eth_vexport_ord:
1905 vv = self.eth_value[v]['value']
1906 if isinstance (vv, Value):
1907 vv = vv.to_str(self)
1908 print "%-40s %s" % (v, vv)
1909 print "\n# ASN.1 Object Classes"
1910 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1912 for t in self.objectclass_ord:
1913 print "%-40s " % (t)
1914 print "\n# ASN.1 Types"
1915 print "%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")
1917 for t in self.type_ord:
1918 print "%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])
1919 print "\n# Wireshark Types"
1920 print "Wireshark type References (ASN.1 types)"
1922 for t in self.eth_type_ord:
1923 print "%-31s %d" % (t, len(self.eth_type[t]['ref'])),
1924 print ', '.join(self.eth_type[t]['ref'])
1925 print "\n# ASN.1 Values"
1926 print "%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value")
1928 for v in self.value_ord:
1929 vv = self.value[v]['value']
1930 if isinstance (vv, Value):
1931 vv = vv.to_str(self)
1932 print "%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname'])
1933 #print "\n# Wireshark Values"
1934 #print "%-40s %s" % ("Wireshark name", "Value")
1936 #for v in self.eth_value_ord:
1937 # vv = self.eth_value[v]['value']
1938 # if isinstance (vv, Value):
1939 # vv = vv.to_str(self)
1940 # print "%-40s %s" % (v, vv)
1941 print "\n# ASN.1 Fields"
1942 print "ASN.1 unique name Wireshark name ASN.1 type"
1944 for f in (self.pdu_ord + self.field_ord):
1945 print "%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])
1946 print "\n# Wireshark Fields"
1947 print "Wireshark name Wireshark type References (ASN.1 fields)"
1949 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1950 print "%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])),
1951 print ', '.join(self.eth_hf[f]['ref'])
1952 #print "\n# Order after dependencies"
1953 #print '\n'.join(self.eth_type_ord1)
1954 print "\n# Cyclic dependencies"
1955 for c in self.eth_dep_cycle:
1956 print ' -> '.join(c)
1958 self.output.outnm = self.outnm_opt
1959 if (not self.output.outnm):
1960 self.output.outnm = self.proto
1961 self.output.outnm = self.output.outnm.replace('.', '-')
1962 if not self.justexpcnf:
1963 self.eth_output_hf()
1964 self.eth_output_ett()
1965 self.eth_output_types()
1966 self.eth_output_hf_arr()
1967 self.eth_output_ett_arr()
1968 self.eth_output_export()
1969 self.eth_output_val()
1970 self.eth_output_valexp()
1971 self.eth_output_dis_hnd()
1972 self.eth_output_dis_reg()
1973 self.eth_output_dis_tab()
1974 self.eth_output_table()
1976 self.eth_output_expcnf()
1978 def dbg_modules(self):
1980 print "%-30s " % (m),
1981 dep = self.module[m][:]
1982 for i in range(len(dep)):
1983 if dep[i] not in self.module:
1984 dep[i] = '*' + dep[i]
1985 print ', '.join(dep)
1986 # end of print_mod()
1987 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module)
1988 print "\n# ASN.1 Moudules"
1989 print "Module name Dependency"
1992 for m in (self.module_ord):
1994 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
1996 print "\n# ASN.1 Moudules - in dependency order"
1997 print "Module name Dependency"
2002 print "\nCyclic dependencies:"
2003 for i in (range(len(mod_cyc))):
2004 print "%02d: %s" % (i + 1, str(mod_cyc[i]))
2007 #--- EthCnf -------------------------------------------------------------------
2016 self.suppress_line = False
2017 self.include_path = []
2018 # Value name Default value Duplicity check Usage check
2019 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2020 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2021 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2022 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2023 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2024 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2025 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2026 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2027 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2028 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2029 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2030 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2031 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2032 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2033 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2034 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2035 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2036 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2037 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2038 self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2039 self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2041 for k in list(self.tblcfg.keys()) :
2045 def add_item(self, table, key, fn, lineno, **kw):
2046 if self.tblcfg[table]['chk_dup'] and key in self.table[table]:
2047 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2048 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
2049 UserWarning, fn, lineno)
2051 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2052 self.table[table][key].update(kw)
2053 self.order[table].append(key)
2055 def update_item(self, table, key, fn, lineno, **kw):
2056 if key not in self.table[table]:
2057 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2058 self.order[table].append(key)
2059 self.table[table][key][self.tblcfg[table]['val_nm']] = {}
2060 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
2062 def get_order(self, table):
2063 return self.order[table]
2065 def check_item(self, table, key):
2066 return key in self.table[table]
2068 def copy_item(self, table, dst_key, src_key):
2069 if (src_key in self.table[table]):
2070 self.table[table][dst_key] = self.table[table][src_key]
2072 def check_item_value(self, table, key, **kw):
2073 return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key]
2075 def use_item(self, table, key, **kw):
2076 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
2077 if key not in self.table[table]: return vdflt
2078 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
2079 #print "use_item() - set used for %s %s" % (table, key)
2080 self.table[table][key]['used'] = True
2081 return self.table[table][key].get(vname, vdflt)
2083 def omit_assignment(self, type, ident, module):
2084 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
2086 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
2087 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2088 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
2089 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
2090 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
2093 def add_fn_line(self, name, ctx, line, fn, lineno):
2094 if name not in self.fn:
2095 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2096 if (self.fn[name][ctx]):
2097 self.fn[name][ctx]['text'] += line
2099 self.fn[name][ctx] = {'text' : line, 'used' : False,
2100 'fn' : fn, 'lineno' : lineno}
2101 def get_fn_presence(self, name):
2102 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2103 #if self.fn.has_key(name): print self.fn[name]
2104 return name in self.fn
2105 def get_fn_body_presence(self, name):
2106 return name in self.fn and self.fn[name]['FN_BODY']
2107 def get_fn_text(self, name, ctx):
2108 if (name not in self.fn):
2110 if (not self.fn[name][ctx]):
2112 self.fn[name][ctx]['used'] = True
2113 out = self.fn[name][ctx]['text']
2114 if (not self.suppress_line):
2115 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], os.path.basename(self.fn[name][ctx]['fn']), out);
2118 def add_pdu(self, par, is_new, fn, lineno):
2119 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2120 (reg, hidden) = (None, False)
2121 if (len(par) > 1): reg = par[1]
2122 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
2123 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False}
2124 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
2127 def add_register(self, pdu, par, fn, lineno):
2128 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2129 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
2130 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
2131 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
2132 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
2133 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
2134 if ((len(par)-1) < pmin):
2135 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
2137 if ((len(par)-1) > pmax):
2138 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
2139 attr = {'pdu' : pdu, 'rtype' : rtype}
2140 if (rtype in ('NUM', 'STR')):
2141 attr['rtable'] = par[1]
2142 attr['rport'] = par[2]
2143 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
2144 elif (rtype in ('BER', 'PER')):
2145 attr['roid'] = par[1]
2146 attr['roidname'] = '""'
2148 attr['roidname'] = par[2]
2149 elif attr['roid'][0] != '"':
2150 attr['roidname'] = '"' + attr['roid'] + '"'
2151 rkey = '/'.join([rtype, attr['roid']])
2152 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
2154 def check_par(self, par, pmin, pmax, fn, lineno):
2155 for i in range(len(par)):
2159 if par[i][0] == '#':
2163 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2165 if (pmax >= 0) and (len(par) > pmax):
2166 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
2171 def get_par(line, pmin, pmax, fn, lineno):
2172 par = line.split(None, pmax)
2173 par = self.check_par(par, pmin, pmax, fn, lineno)
2176 def get_par_nm(line, pmin, pmax, fn, lineno):
2178 par = line.split(None, pmax)
2181 for i in range(len(par)):
2182 if par[i][0] == '#':
2186 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2193 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2194 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2195 nmpar_end = re.compile(r'\s*$')
2196 result = nmpar_first.search(nmpar)
2199 k = result.group('attr')
2201 result = nmpar_next.search(nmpar, pos)
2206 p2 = nmpar_end.search(nmpar, pos).start()
2216 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2217 report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2218 comment = re.compile(r'^\s*#[^.]')
2219 empty = re.compile(r'^\s*$')
2222 default_flags = 0x00
2235 fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import']
2239 if comment.search(line): continue
2240 result = directive.search(line)
2241 if result: # directive
2242 rep_result = report.search(result.group('name'))
2243 if result.group('name') == 'END_OF_CNF':
2245 elif result.group('name') == 'OPT':
2246 ctx = result.group('name')
2247 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
2248 if not par: continue
2249 self.set_opt(par[0], par[1:], fn, lineno)
2251 elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
2252 'MODULE', 'MODULE_IMPORT',
2253 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2254 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2255 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2256 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2257 ctx = result.group('name')
2258 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2259 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2260 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2261 ctx = result.group('name')
2263 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2265 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2267 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2270 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
2271 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2272 ctx = 'NO_OMIT_ASSGN'
2275 elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2276 ctx = result.group('name')
2277 default_flags = EF_TYPE|EF_VALS
2278 if ctx == 'MODULE_EXPORTS':
2280 default_flags |= EF_MODULE
2281 if ctx == 'EXPORTS':
2282 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
2284 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2285 if not par: continue
2287 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
2288 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
2289 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
2290 elif (ctx == 'EXPORTS'): p = 0
2291 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
2292 for i in range(p, len(par)):
2293 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
2294 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
2295 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
2296 elif (par[i] == 'WS_VAR'): default_flags |= EF_WS_VAR
2297 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
2298 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2299 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2300 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2301 ctx = result.group('name')
2302 default_flags = EF_ENUM
2303 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
2304 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2305 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
2306 for i in range(0, len(par)):
2307 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2308 elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT
2309 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
2310 elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE
2311 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
2312 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
2313 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2314 elif result.group('name') == 'FN_HDR':
2316 if (ctx in ('FN_PARS',)) and name: minp = 0
2317 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2318 if (not par) and (minp > 0): continue
2319 ctx = result.group('name')
2320 if par: name = par[0]
2321 elif result.group('name') == 'FN_FTR':
2323 if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0
2324 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2325 if (not par) and (minp > 0): continue
2326 ctx = result.group('name')
2327 if par: name = par[0]
2328 elif result.group('name') == 'FN_BODY':
2329 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2330 if not par: continue
2331 ctx = result.group('name')
2334 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
2335 elif result.group('name') == 'FN_PARS':
2336 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2337 ctx = result.group('name')
2342 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
2344 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2346 elif result.group('name') == 'CLASS':
2347 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2348 if not par: continue
2349 ctx = result.group('name')
2351 add_class_ident(name)
2352 if not name.split('$')[-1].isupper():
2353 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
2354 UserWarning, fn, lineno)
2355 elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2356 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2357 if not par: continue
2358 self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno)
2359 elif rep_result: # Reports
2360 num = rep_result.group('num')
2361 type = rep_result.group('type')
2363 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2364 if not par: continue
2366 par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno)
2367 rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno }
2370 self.report.setdefault(num, []).append(rep)
2373 elif result.group('name') in ('INCLUDE', 'IMPORT') :
2374 is_imp = result.group('name') == 'IMPORT'
2375 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2377 warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno)
2380 #print "Try include: %s" % (fname)
2381 if (not os.path.exists(fname)):
2382 fname = os.path.join(os.path.split(fn)[0], par[0])
2383 #print "Try include: %s" % (fname)
2385 while not os.path.exists(fname) and (i < len(self.include_path)):
2386 fname = os.path.join(self.include_path[i], par[0])
2387 #print "Try include: %s" % (fname)
2389 if (not os.path.exists(fname)):
2391 continue # just ignore
2393 fname = par[0] # report error
2394 fnew = open(fname, "r")
2395 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import})
2396 fn, f, lineno, is_import = par[0], fnew, 0, is_imp
2397 elif result.group('name') == 'END':
2400 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
2403 if not empty.match(line):
2404 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
2406 if empty.match(line): continue
2407 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
2408 if not par: continue
2409 self.set_opt(par[0], par[1:], fn, lineno)
2410 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2411 if empty.match(line): continue
2412 if ctx == 'EXPORTS':
2413 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
2415 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2416 if not par: continue
2417 flags = default_flags
2420 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
2421 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
2422 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
2423 elif (ctx == 'EXPORTS'): p = 1
2424 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
2425 for i in range(p, len(par)):
2426 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
2427 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
2428 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
2429 elif (par[i] == 'WS_VAR'): flags |= EF_WS_VAR
2430 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
2431 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2432 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2433 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
2434 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
2435 if empty.match(line): continue
2436 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
2437 if not par: continue
2438 flags = default_flags
2439 for i in range(1, len(par)):
2440 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2441 elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT
2442 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
2443 elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE
2444 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
2445 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
2446 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2447 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
2448 elif ctx in ('PDU', 'PDU_NEW'):
2449 if empty.match(line): continue
2450 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
2451 if not par: continue
2453 if (ctx == 'PDU_NEW'): is_new = True
2454 self.add_pdu(par[0:2], is_new, fn, lineno)
2456 self.add_register(par[0], par[2:5], fn, lineno)
2457 elif ctx in ('REGISTER', 'REGISTER_NEW'):
2458 if empty.match(line): continue
2459 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
2460 if not par: continue
2461 if not self.check_item('PDU', par[0]):
2463 if (ctx == 'REGISTER_NEW'): is_new = True
2464 self.add_pdu(par[0:1], is_new, fn, lineno)
2465 self.add_register(par[0], par[1:4], fn, lineno)
2466 elif ctx in ('MODULE', 'MODULE_IMPORT'):
2467 if empty.match(line): continue
2468 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2469 if not par: continue
2470 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
2471 elif ctx == 'IMPORT_TAG':
2472 if empty.match(line): continue
2473 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
2474 if not par: continue
2475 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
2476 elif ctx == 'OMIT_ASSIGNMENT':
2477 if empty.match(line): continue
2478 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2479 if not par: continue
2480 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
2481 elif ctx == 'NO_OMIT_ASSGN':
2482 if empty.match(line): continue
2483 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2484 if not par: continue
2485 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
2486 elif ctx == 'VIRTUAL_ASSGN':
2487 if empty.match(line): continue
2488 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
2489 if not par: continue
2490 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
2491 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
2492 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
2494 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
2495 if not par[0][0].isupper():
2496 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
2497 UserWarning, fn, lineno)
2498 elif ctx == 'SET_TYPE':
2499 if empty.match(line): continue
2500 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2501 if not par: continue
2502 if not self.check_item('VIRTUAL_ASSGN', par[0]):
2503 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
2504 if not par[1][0].isupper():
2505 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
2506 UserWarning, fn, lineno)
2507 elif ctx == 'ASSIGN_VALUE_TO_TYPE':
2508 if empty.match(line): continue
2509 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2510 if not par: continue
2511 self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno)
2512 elif ctx == 'TYPE_RENAME':
2513 if empty.match(line): continue
2514 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2515 if not par: continue
2516 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2517 if not par[1][0].isupper():
2518 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2519 UserWarning, fn, lineno)
2520 elif ctx == 'FIELD_RENAME':
2521 if empty.match(line): continue
2522 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2523 if not par: continue
2524 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2525 if not par[1][0].islower():
2526 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2527 UserWarning, fn, lineno)
2528 elif ctx == 'TF_RENAME':
2529 if empty.match(line): continue
2530 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2531 if not par: continue
2532 tmpu = par[1][0].upper() + par[1][1:]
2533 tmpl = par[1][0].lower() + par[1][1:]
2534 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
2535 if not tmpu[0].isupper():
2536 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2537 UserWarning, fn, lineno)
2538 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
2539 if not tmpl[0].islower():
2540 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2541 UserWarning, fn, lineno)
2542 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2543 if empty.match(line): continue
2544 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2545 if not par: continue
2546 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
2547 elif ctx == 'FN_PARS':
2548 if empty.match(line): continue
2550 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
2552 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2553 if not par: continue
2555 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
2557 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2558 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2559 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
2560 elif ctx == 'CLASS':
2561 if empty.match(line): continue
2562 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
2563 if not par: continue
2564 if not set_type_to_class(name, par[0], par[1:]):
2565 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
2566 UserWarning, fn, lineno)
2567 elif ctx == 'TABLE':
2568 self.report[name][-1]['text'] += line
2570 def set_opt(self, opt, par, fn, lineno):
2571 #print "set_opt: %s, %s" % (opt, par)
2573 par = self.check_par(par, 1, 1, fn, lineno)
2575 self.include_path.append(par[0])
2576 elif opt in ("-b", "BER", "CER", "DER"):
2577 par = self.check_par(par, 0, 0, fn, lineno)
2578 self.ectx.encoding = 'ber'
2579 elif opt in ("PER",):
2580 par = self.check_par(par, 0, 0, fn, lineno)
2581 self.ectx.encoding = 'per'
2582 elif opt in ("-p", "PROTO"):
2583 par = self.check_par(par, 1, 1, fn, lineno)
2585 self.ectx.proto_opt = par[0]
2586 self.ectx.merge_modules = True
2587 elif opt in ("ALIGNED",):
2588 par = self.check_par(par, 0, 0, fn, lineno)
2589 self.ectx.aligned = True
2590 elif opt in ("-u", "UNALIGNED"):
2591 par = self.check_par(par, 0, 0, fn, lineno)
2592 self.ectx.aligned = False
2593 elif opt in ("-d",):
2594 par = self.check_par(par, 1, 1, fn, lineno)
2596 self.ectx.dbgopt = par[0]
2597 elif opt in ("-e",):
2598 par = self.check_par(par, 0, 0, fn, lineno)
2599 self.ectx.expcnf = True
2600 elif opt in ("-S",):
2601 par = self.check_par(par, 0, 0, fn, lineno)
2602 self.ectx.merge_modules = True
2603 elif opt in ("GROUP_BY_PROT",):
2604 par = self.check_par(par, 0, 0, fn, lineno)
2605 self.ectx.group_by_prot = True
2606 elif opt in ("-o",):
2607 par = self.check_par(par, 1, 1, fn, lineno)
2609 self.ectx.outnm_opt = par[0]
2610 elif opt in ("-O",):
2611 par = self.check_par(par, 1, 1, fn, lineno)
2613 self.ectx.output.outdir = par[0]
2614 elif opt in ("-s",):
2615 par = self.check_par(par, 1, 1, fn, lineno)
2617 self.ectx.output.single_file = par[0]
2618 elif opt in ("-k",):
2619 par = self.check_par(par, 0, 0, fn, lineno)
2620 self.ectx.output.keep = True
2621 elif opt in ("-L",):
2622 par = self.check_par(par, 0, 0, fn, lineno)
2623 self.suppress_line = True
2624 elif opt in ("EMBEDDED_PDV_CB",):
2625 par = self.check_par(par, 1, 1, fn, lineno)
2627 self.ectx.default_embedded_pdv_cb = par[0]
2628 elif opt in ("EXTERNAL_TYPE_CB",):
2629 par = self.check_par(par, 1, 1, fn, lineno)
2631 self.ectx.default_external_type_cb = par[0]
2633 warnings.warn_explicit("Unknown option %s" % (opt),
2634 UserWarning, fn, lineno)
2636 def dbg_print(self):
2637 print "\n# Conformance values"
2638 print "%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")
2640 tbls = sorted(self.table.keys())
2642 keys = sorted(self.table[t].keys())
2644 print "%-15s %4s %-15s %-20s %s" % (
2645 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))
2647 def unused_report(self):
2648 tbls = sorted(self.table.keys())
2650 if not self.tblcfg[t]['chk_use']: continue
2651 keys = sorted(self.table[t].keys())
2653 if not self.table[t][k]['used']:
2654 warnings.warn_explicit("Unused %s for %s" % (t, k),
2655 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2656 fnms = list(self.fn.keys())
2659 keys = sorted(self.fn[f].keys())
2661 if not self.fn[f][k]: continue
2662 if not self.fn[f][k]['used']:
2663 warnings.warn_explicit("Unused %s for %s" % (k, f),
2664 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2666 #--- EthOut -------------------------------------------------------------------
2672 self.single_file = None
2673 self.created_files = {}
2674 self.created_files_ord = []
2677 def outcomment(self, ln, comment=None):
2679 return '%s %s\n' % (comment, ln)
2681 return '/* %-74s */\n' % (ln)
2683 def created_file_add(self, name, keep_anyway):
2684 name = os.path.normcase(os.path.abspath(name))
2685 if name not in self.created_files:
2686 self.created_files_ord.append(name)
2687 self.created_files[name] = keep_anyway
2689 self.created_files[name] = self.created_files[name] or keep_anyway
2691 def created_file_exists(self, name):
2692 name = os.path.normcase(os.path.abspath(name))
2693 return name in self.created_files
2695 #--- output_fname -------------------------------------------------------
2696 def output_fname(self, ftype, ext='c'):
2698 if not ext in ('cnf',):
2705 #--- output_fullname -------------------------------------------------------
2706 def output_fullname(self, ftype, ext='c'):
2707 return os.path.join(self.outdir, self.output_fname(ftype, ext=ext))
2708 #--- file_open -------------------------------------------------------
2709 def file_open(self, ftype, ext='c'):
2710 fn = self.output_fullname(ftype, ext=ext)
2711 if self.created_file_exists(fn):
2718 fx.write(self.fhdr(fn, comment = comment))
2720 if (not self.single_file and not self.created_file_exists(fn)):
2721 fx.write(self.fhdr(fn))
2722 if not self.ectx.merge_modules:
2725 if self.ectx.groups():
2727 if (len(self.ectx.modules) > 1):
2729 for (m, p) in self.ectx.modules:
2732 mstr += "Module %s" % (self.ectx.Module())
2733 mstr += " --- --- ---"
2734 fx.write(self.outcomment(mstr, comment))
2737 #--- file_close -------------------------------------------------------
2738 def file_close(self, fx, discard=False, keep_anyway=False):
2740 if discard and not self.created_file_exists(fx.name):
2743 self.created_file_add(fx.name, keep_anyway)
2744 #--- fhdr -------------------------------------------------------
2745 def fhdr(self, fn, comment=None):
2747 out += self.outcomment('Do not modify this file.', comment)
2748 out += self.outcomment('It is created automatically by the ASN.1 to Wireshark dissector compiler', comment)
2749 out += self.outcomment(os.path.basename(fn), comment)
2750 out += self.outcomment(' '.join(sys.argv), comment)
2752 # Make Windows path separator look like Unix path separator
2753 return out.replace('\\', '/')
2755 #--- dbg_print -------------------------------------------------------
2756 def dbg_print(self):
2757 print "\n# Output files"
2758 print "\n".join(self.created_files_ord)
2761 #--- make_single_file -------------------------------------------------------
2762 def make_single_file(self):
2763 if (not self.single_file): return
2764 in_nm = self.single_file + '.c'
2765 out_nm = self.output_fullname('')
2766 self.do_include(out_nm, in_nm)
2767 in_nm = self.single_file + '.h'
2768 if (os.path.exists(in_nm)):
2769 out_nm = self.output_fullname('', ext='h')
2770 self.do_include(out_nm, in_nm)
2772 for fn in self.created_files_ord:
2773 if not self.created_files[fn]:
2776 #--- do_include -------------------------------------------------------
2777 def do_include(self, out_nm, in_nm):
2778 def check_file(fn, fnlist):
2779 fnfull = os.path.normcase(os.path.abspath(fn))
2780 if (fnfull in fnlist and os.path.exists(fnfull)):
2781 return os.path.normpath(fn)
2783 fin = file(in_nm, "r")
2784 fout = file(out_nm, "w")
2785 fout.write(self.fhdr(out_nm))
2786 fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n')
2788 fout.write('#line %u "%s"\n' % (1, os.path.basename(in_nm)))
2790 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2795 cont_linenum = cont_linenum + 1;
2796 line = fin.readline()
2797 if (line == ''): break
2799 result = include.search(line)
2800 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2802 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2804 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2806 ifile = check_file(result.group('fname'), self.created_files)
2809 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
2810 fout.write('#line %u "%s"\n' % (1, os.path.basename(ifile)))
2811 finc = file(ifile, "r")
2812 fout.write(finc.read())
2814 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
2815 fout.write('#line %u "%s"\n' % (cont_linenum+1, os.path.basename(in_nm)) )
2824 #--- Node ---------------------------------------------------------------------
2826 def __init__(self,*args, **kw):
2828 self.type = self.__class__.__name__
2830 assert (len(args) == 1)
2832 self.__dict__.update (kw)
2833 def str_child (self, key, child, depth):
2834 indent = " " * (2 * depth)
2835 keystr = indent + key + ": "
2836 if key == 'type': # already processed in str_depth
2838 if isinstance (child, Node): # ugh
2839 return keystr + "\n" + child.str_depth (depth+1)
2840 if isinstance(child, type ([])):
2843 if isinstance (x, Node):
2844 l.append (x.str_depth (depth+1))
2846 l.append (indent + " " + str(x) + "\n")
2847 return keystr + "[\n" + ''.join(l) + indent + "]\n"
2849 return keystr + str (child) + "\n"
2850 def str_depth (self, depth): # ugh
2851 indent = " " * (2 * depth)
2852 l = ["%s%s" % (indent, self.type)]
2853 l.append ("".join (map (lambda (k,v): self.str_child (k, v, depth + 1),
2854 list(self.__dict__.items ()))))
2855 return "\n".join (l)
2857 return "\n" + self.str_depth (0)
2858 def to_python (self, ctx):
2859 return self.str_depth (ctx.indent_lev)
2861 def eth_reg(self, ident, ectx):
2864 def fld_obj_repr(self, ectx):
2865 return "/* TO DO %s */" % (str(self))
2867 #--- ValueAssignment -------------------------------------------------------------
2868 class ValueAssignment (Node):
2869 def __init__(self,*args, **kw) :
2870 Node.__init__ (self,*args, **kw)
2872 def eth_reg(self, ident, ectx):
2873 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
2874 ectx.eth_reg_vassign(self)
2875 ectx.eth_reg_value(self.ident, self.typ, self.val)
2877 #--- ObjectAssignment -------------------------------------------------------------
2878 class ObjectAssignment (Node):
2879 def __init__(self,*args, **kw) :
2880 Node.__init__ (self,*args, **kw)
2882 def __eq__(self, other):
2883 if self.cls != other.cls:
2885 if len(self.val) != len(other.val):
2887 for f in (list(self.val.keys())):
2888 if f not in other.val:
2890 if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
2891 if not self.val[f].fld_obj_eq(other.val[f]):
2894 if str(self.val[f]) != str(other.val[f]):
2898 def eth_reg(self, ident, ectx):
2899 def make_virtual_type(cls, field, prefix):
2900 if isinstance(self.val, str): return
2901 if field in self.val and not isinstance(self.val[field], Type_Ref):
2902 vnm = prefix + '-' + self.ident
2903 virtual_tr = Type_Ref(val = vnm)
2905 self.val[field] = virtual_tr
2906 ectx.eth_reg_assign(vnm, t, virt=True)
2907 ectx.eth_reg_type(vnm, t)
2908 t.eth_reg_sub(vnm, ectx)
2909 if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field):
2910 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))
2912 # end of make_virtual_type()
2913 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
2914 self.module = ectx.Module()
2915 ectx.eth_reg_oassign(self)
2916 if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
2917 make_virtual_type(self.cls, '&Type', 'TYPE')
2918 if (self.cls == 'OPERATION'):
2919 make_virtual_type(self.cls, '&ArgumentType', 'ARG')
2920 make_virtual_type(self.cls, '&ResultType', 'RES')
2921 if (self.cls == 'ERROR'):
2922 make_virtual_type(self.cls, '&ParameterType', 'PAR')
2925 #--- Type ---------------------------------------------------------------------
2927 def __init__(self,*args, **kw) :
2931 self.named_list = None
2932 Node.__init__ (self,*args, **kw)
2935 if self.name is None :
2940 def HasConstraint(self):
2941 if self.constr is None :
2946 def HasSizeConstraint(self):
2947 return self.HasConstraint() and self.constr.IsSize()
2949 def HasValueConstraint(self):
2950 return self.HasConstraint() and self.constr.IsValue()
2952 def HasPermAlph(self):
2953 return self.HasConstraint() and self.constr.IsPermAlph()
2955 def HasContentsConstraint(self):
2956 return self.HasConstraint() and self.constr.IsContents()
2958 def HasOwnTag(self):
2959 return len(self.tags) > 0
2961 def HasImplicitTag(self, ectx):
2962 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
2964 def IndetermTag(self, ectx):
2967 def AddTag(self, tag):
2968 self.tags[0:0] = [tag]
2970 def GetTag(self, ectx):
2971 #print "GetTag(%s)\n" % self.name;
2972 if (self.HasOwnTag()):
2973 return self.tags[0].GetTag(ectx)
2975 return self.GetTTag(ectx)
2977 def GetTTag(self, ectx):
2978 print "#Unhandled GetTTag() in %s" % (self.type)
2979 print self.str_depth(1)
2980 return ('BER_CLASS_unknown', 'TAG_unknown')
2982 def SetName(self, name):
2985 def AddConstraint(self, constr):
2986 if not self.HasConstraint():
2987 self.constr = constr
2989 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
2991 def eth_tname(self):
2992 return '#' + self.type + '_' + str(id(self))
2994 def eth_ftype(self, ectx):
2995 return ('FT_NONE', 'BASE_NONE')
2997 def eth_strings(self):
3000 def eth_need_tree(self):
3003 def eth_has_vals(self):
3006 def eth_has_enum(self, tname, ectx):
3007 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
3009 def eth_need_pdu(self, ectx):
3012 def eth_named_bits(self):
3015 def eth_reg_sub(self, ident, ectx):
3018 def get_components(self, ectx):
3019 print "#Unhandled get_components() in %s" % (self.type)
3020 print self.str_depth(1)
3023 def sel_req(self, sel, ectx):
3024 print "#Selection '%s' required for non-CHOICE type %s" % (sel, self.type)
3025 print self.str_depth(1)
3027 def fld_obj_eq(self, other):
3028 return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
3030 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
3031 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3033 if (ectx.Tag() and (len(self.tags) > tstrip)):
3035 for i in range(len(self.tags)-1, tstrip-1, -1):
3036 tagged_type = TaggedType(val=tagged_type, tstrip=i)
3037 tagged_type.AddTag(self.tags[i])
3038 if not tagflag: # 1st tagged level
3039 if self.IsNamed() and not selflag:
3040 tagged_type.SetName(self.name)
3041 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
3044 if ident and self.IsNamed() and not tagflag and not selflag:
3045 nm = ident + '/' + self.name
3048 elif self.IsNamed():
3050 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
3051 if not ident: # Assignment
3052 ectx.eth_reg_assign(nm, self)
3053 if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx):
3054 ectx.eth_reg_type(nm, self)
3055 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
3056 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
3057 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
3058 if ectx.conform.check_item('SET_TYPE', nm):
3059 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
3061 ectx.eth_reg_type(nm, self) # new type
3063 elif ectx.conform.check_item('SET_TYPE', nm):
3064 trnm = ectx.conform.use_item('SET_TYPE', nm)
3065 elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx):
3066 ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints
3071 ectx.eth_reg_type(nm, self)
3073 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
3074 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
3075 ectx.eth_reg_assign(vnm, self, virt=True)
3076 ectx.eth_reg_type(vnm, self)
3077 self.eth_reg_sub(vnm, ectx)
3078 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
3079 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
3080 if ident and not tagflag:
3081 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
3082 if ectx.conform.check_item('SET_TYPE', nm):
3083 virtual_tr.eth_reg_sub(nm, ectx)
3085 self.eth_reg_sub(nm, ectx)
3087 def eth_get_size_constr(self, ectx):
3088 (minv, maxv, ext) = ('MIN', 'MAX', False)
3089 if self.HasSizeConstraint():
3090 if self.constr.IsSize():
3091 (minv, maxv, ext) = self.constr.GetSize(ectx)
3092 if (self.constr.type == 'Intersection'):
3093 if self.constr.subtype[0].IsSize():
3094 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
3095 elif self.constr.subtype[1].IsSize():
3096 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
3097 if minv == 'MIN': minv = 'NO_BOUND'
3098 if maxv == 'MAX': maxv = 'NO_BOUND'
3099 if (ext): ext = 'TRUE'
3101 return (minv, maxv, ext)
3103 def eth_get_value_constr(self, ectx):
3104 (minv, maxv, ext) = ('MIN', 'MAX', False)
3105 if self.HasValueConstraint():
3106 (minv, maxv, ext) = self.constr.GetValue(ectx)
3107 if minv == 'MIN': minv = 'NO_BOUND'
3108 if maxv == 'MAX': maxv = 'NO_BOUND'
3109 if str(minv).isdigit(): minv += 'U'
3110 if str(maxv).isdigit():
3111 if (long(maxv) >= 2**32):
3112 maxv = "G_GINT64_CONSTANT(%sU)" % (str(maxv))
3115 if (ext): ext = 'TRUE'
3117 return (minv, maxv, ext)
3119 def eth_get_alphabet_constr(self, ectx):
3120 (alph, alphlen) = ('NULL', '0')
3121 if self.HasPermAlph():
3122 alph = self.constr.GetPermAlph(ectx)
3125 if (alph != 'NULL'):
3126 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
3127 alphlen = str(len(alph) - 2)
3129 alphlen = 'strlen(%s)' % (alph)
3130 return (alph, alphlen)
3132 def eth_type_vals(self, tname, ectx):
3133 if self.eth_has_vals():
3134 print "#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)
3135 print self.str_depth(1)
3138 def eth_type_enum(self, tname, ectx):
3139 if self.eth_has_enum(tname, ectx):
3140 print "#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)
3141 print self.str_depth(1)
3144 def eth_type_default_table(self, ectx, tname):
3147 def eth_type_default_body(self, ectx):
3148 print "#Unhandled eth_type_default_body() in %s" % (self.type)
3149 print self.str_depth(1)
3152 def eth_type_default_pars(self, ectx, tname):
3159 'OFFSET' : 'offset',
3161 'HF_INDEX' : 'hf_index',
3163 'IMPLICIT_TAG' : 'implicit_tag',
3165 if (ectx.eth_type[tname]['tree']):
3166 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
3167 if (ectx.merge_modules):
3170 pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
3173 def eth_type_fn(self, proto, tname, ectx):
3174 body = self.eth_type_default_body(ectx, tname)
3175 pars = self.eth_type_default_pars(ectx, tname)
3176 if ectx.conform.check_item('FN_PARS', tname):
3177 pars.update(ectx.conform.use_item('FN_PARS', tname))
3178 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
3179 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
3180 pars['DEFAULT_BODY'] = body
3182 for k in list(pars.keys()):
3184 pars[k] = pars[k] % pars
3186 raise sys.exc_info()[0], "%s\n%s" % (str(pars), sys.exc_info()[1])
3188 out += self.eth_type_default_table(ectx, tname) % pars
3189 out += ectx.eth_type_fn_hdr(tname)
3190 out += ectx.eth_type_fn_body(tname, body, pars=pars)
3191 out += ectx.eth_type_fn_ftr(tname)
3194 #--- Value --------------------------------------------------------------------
3196 def __init__(self,*args, **kw) :
3198 Node.__init__ (self,*args, **kw)
3200 def SetName(self, name) :
3203 def to_str(self, ectx):
3204 return str(self.val)
3209 def fld_obj_repr(self, ectx):
3210 return self.to_str(ectx)
3212 #--- Value_Ref -----------------------------------------------------------------
3213 class Value_Ref (Value):
3214 def to_str(self, ectx):
3215 return asn2c(self.val)
3217 #--- ObjectClass ---------------------------------------------------------------------
3218 class ObjectClass (Node):
3219 def __init__(self,*args, **kw) :
3221 Node.__init__ (self,*args, **kw)
3223 def SetName(self, name):
3225 add_class_ident(self.name)
3227 def eth_reg(self, ident, ectx):
3228 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
3229 ectx.eth_reg_objectclass(self.name, self)
3231 #--- Class_Ref -----------------------------------------------------------------
3232 class Class_Ref (ObjectClass):
3235 #--- ObjectClassDefn ---------------------------------------------------------------------
3236 class ObjectClassDefn (ObjectClass):
3237 def reg_types(self):
3238 for fld in self.fields:
3239 repr = fld.fld_repr()
3240 set_type_to_class(self.name, repr[0], repr[1:])
3243 #--- Tag ---------------------------------------------------------------
3245 def to_python (self, ctx):
3246 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
3249 self.typ.to_python (ctx))
3250 def IsImplicit(self, ectx):
3251 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
3253 def GetTag(self, ectx):
3255 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
3256 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
3257 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
3258 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
3259 return (tc, self.num)
3261 def eth_tname(self):
3263 if (self.cls == 'UNIVERSAL'): n = 'U'
3264 elif (self.cls == 'APPLICATION'): n = 'A'
3265 elif (self.cls == 'CONTEXT'): n = 'C'
3266 elif (self.cls == 'PRIVATE'): n = 'P'
3267 return n + str(self.num)
3269 #--- Constraint ---------------------------------------------------------------
3270 class Constraint (Node):
3271 def to_python (self, ctx):
3272 print "Ignoring constraint:", self.type
3273 return self.subtype.typ.to_python (ctx)
3275 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
3277 def eth_tname(self):
3278 return '#' + self.type + '_' + str(id(self))
3281 return (self.type == 'Size' and self.subtype.IsValue()) \
3282 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
3284 def GetSize(self, ectx):
3285 (minv, maxv, ext) = ('MIN', 'MAX', False)
3287 if self.type == 'Size':
3288 (minv, maxv, ext) = self.subtype.GetValue(ectx)
3289 elif self.type == 'Intersection':
3290 if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
3291 (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
3292 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
3293 (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
3294 return (minv, maxv, ext)
3297 return self.type == 'SingleValue' \
3298 or self.type == 'ValueRange' \
3299 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
3300 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
3302 def GetValue(self, ectx):
3303 (minv, maxv, ext) = ('MIN', 'MAX', False)
3305 if self.type == 'SingleValue':
3306 minv = ectx.value_get_eth(self.subtype)
3307 maxv = ectx.value_get_eth(self.subtype)
3308 ext = hasattr(self, 'ext') and self.ext
3309 elif self.type == 'ValueRange':
3310 minv = ectx.value_get_eth(self.subtype[0])
3311 maxv = ectx.value_get_eth(self.subtype[1])
3312 ext = hasattr(self, 'ext') and self.ext
3313 elif self.type == 'Intersection':
3314 if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
3315 (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
3316 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
3317 (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
3318 elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
3319 v0 = self.subtype[0].GetValue(ectx)
3320 v1 = self.subtype[1].GetValue(ectx)
3321 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
3322 elif self.type == 'Union':
3323 if self.subtype[0].IsValue() and self.subtype[1].IsValue():
3324 v0 = self.subtype[0].GetValue(ectx)
3325 v1 = self.subtype[1].GetValue(ectx)
3326 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
3327 return (minv, maxv, ext)
3329 def IsAlphabet(self):
3330 return self.type == 'SingleValue' \
3331 or self.type == 'ValueRange' \
3332 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
3333 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
3335 def GetAlphabet(self, ectx):
3337 if self.IsAlphabet():
3338 if self.type == 'SingleValue':
3339 alph = ectx.value_get_eth(self.subtype)
3340 elif self.type == 'ValueRange':
3341 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
3342 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
3344 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
3347 elif self.type == 'Union':
3348 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
3349 a0 = self.subtype[0].GetAlphabet(ectx)
3350 a1 = self.subtype[1].GetAlphabet(ectx)
3351 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
3352 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
3353 alph = '"' + a0[1:-1] + a1[1:-1] + '"'
3355 alph = a0 + ' ' + a1
3358 def IsPermAlph(self):
3359 return self.type == 'From' and self.subtype.IsAlphabet() \
3360 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
3362 def GetPermAlph(self, ectx):
3364 if self.IsPermAlph():
3365 if self.type == 'From':
3366 alph = self.subtype.GetAlphabet(ectx)
3367 elif self.type == 'Intersection':
3368 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
3369 alph = self.subtype[0].GetPermAlph(ectx)
3370 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
3371 alph = self.subtype[1].GetPermAlph(ectx)
3374 def IsContents(self):
3375 return self.type == 'Contents' \
3376 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
3378 def GetContents(self, ectx):
3380 if self.IsContents():
3381 if self.type == 'Contents':
3382 if self.subtype.type == 'Type_Ref':
3383 contents = self.subtype.val
3384 elif self.type == 'Intersection':
3385 if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
3386 contents = self.subtype[0].GetContents(ectx)
3387 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
3388 contents = self.subtype[1].GetContents(ectx)
3391 def IsNegativ(self):
3393 return isinstance(sval, str) and (sval[0] == '-')
3394 if self.type == 'SingleValue':
3395 return is_neg(self.subtype)
3396 elif self.type == 'ValueRange':
3397 if self.subtype[0] == 'MIN': return True
3398 return is_neg(self.subtype[0])
3401 def eth_constrname(self):
3403 if isinstance(val, Value_Ref):
3404 return asn2c(val.val)
3407 return 'M' + str(-int(val))
3410 except (ValueError, TypeError):
3411 return asn2c(str(val))
3414 if hasattr(self, 'ext') and self.ext:
3416 if self.type == 'SingleValue':
3417 return int2str(self.subtype) + ext
3418 elif self.type == 'ValueRange':
3419 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
3420 elif self.type == 'Size':
3421 return 'SIZE_' + self.subtype.eth_constrname() + ext
3423 return 'CONSTR' + str(id(self)) + ext
3426 class Module (Node):
3427 def to_python (self, ctx):
3428 ctx.tag_def = self.tag_def.dfl_tag
3430 %s""" % (self.ident, self.body.to_python (ctx))
3433 return self.ident.val
3435 def get_proto(self, ectx):
3439 prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name())
3442 def to_eth(self, ectx):
3443 ectx.tags_def = 'EXPLICIT' # default = explicit
3444 ectx.proto = self.get_proto(ectx)
3445 ectx.tag_def = self.tag_def.dfl_tag
3446 ectx.eth_reg_module(self)
3447 self.body.to_eth(ectx)
3449 class Module_Body (Node):
3450 def to_python (self, ctx):
3451 # XXX handle exports, imports.
3452 l = [x.to_python (ctx) for x in self.assign_list]
3453 l = [a for a in l if a != '']
3454 return "\n".join (l)
3456 def to_eth(self, ectx):
3458 ectx.eth_exports(self.exports)
3460 for i in self.imports:
3462 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
3463 ectx.eth_module_dep_add(ectx.Module(), mod)
3464 for s in i.symbol_list:
3465 if isinstance(s, Type_Ref):
3466 ectx.eth_import_type(s.val, mod, proto)
3467 elif isinstance(s, Value_Ref):
3468 ectx.eth_import_value(s.val, mod, proto)
3469 elif isinstance(s, Class_Ref):
3470 ectx.eth_import_class(s.val, mod, proto)
3472 msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
3473 warnings.warn_explicit(msg, UserWarning, '', 0)
3475 for a in self.assign_list:
3478 class Default_Tags (Node):
3479 def to_python (self, ctx): # not to be used directly
3482 # XXX should just calculate dependencies as we go along.
3483 def calc_dependencies (node, dict, trace = 0):
3484 if not hasattr (node, '__dict__'):
3485 if trace: print "#returning, node=", node
3487 if isinstance (node, Type_Ref):
3489 if trace: print "#Setting", node.val
3491 for (a, val) in list(node.__dict__.items ()):
3492 if trace: print "# Testing node ", node, "attr", a, " val", val
3495 elif isinstance (val, Node):
3496 calc_dependencies (val, dict, trace)
3497 elif isinstance (val, type ([])):
3499 calc_dependencies (v, dict, trace)
3502 class Type_Assign (Node):
3503 def __init__ (self, *args, **kw):
3504 Node.__init__ (self, *args, **kw)
3505 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3506 to_test = self.val.typ
3509 if isinstance (to_test, SequenceType):
3510 to_test.sequence_name = self.name.name
3512 def to_python (self, ctx):
3514 calc_dependencies (self.val, dep_dict, 0)
3515 depend_list = list(dep_dict.keys ())
3516 return ctx.register_assignment (self.name.name,
3517 self.val.to_python (ctx),
3520 class PyQuote (Node):
3521 def to_python (self, ctx):
3522 return ctx.register_pyquote (self.val)
3524 #--- Type_Ref -----------------------------------------------------------------
3525 class Type_Ref (Type):
3526 def to_python (self, ctx):
3529 def eth_reg_sub(self, ident, ectx):
3530 ectx.eth_dep_add(ident, self.val)
3532 def eth_tname(self):
3533 if self.HasSizeConstraint():
3534 return asn2c(self.val) + '_' + self.constr.eth_constrname()
3536 return asn2c(self.val)
3538 def tr_need_own_fn(self, ectx):
3539 return ectx.Per() and self.HasSizeConstraint()
3541 def fld_obj_repr(self, ectx):
3544 def get_components(self, ectx):
3545 if self.val not in ectx.type or ectx.type[self.val]['import']:
3546 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
3547 warnings.warn_explicit(msg, UserWarning, '', 0)
3550 return ectx.type[self.val]['val'].get_components(ectx)
3552 def GetTTag(self, ectx):
3553 #print "GetTTag(%s)\n" % self.val;
3554 if (ectx.type[self.val]['import']):
3555 if 'ttag' not in ectx.type[self.val]:
3556 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
3557 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
3558 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
3559 warnings.warn_explicit(msg, UserWarning, '', 0)
3560 ttag = ('-1/*imported*/', '-1/*imported*/')
3561 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
3562 return ectx.type[self.val]['ttag']
3564 return ectx.type[self.val]['val'].GetTag(ectx)
3566 def IndetermTag(self, ectx):
3567 if (ectx.type[self.val]['import']):
3570 return ectx.type[self.val]['val'].IndetermTag(ectx)
3572 def eth_type_default_pars(self, ectx, tname):
3574 pars = Type.eth_type_default_pars(self, ectx, tname)
3577 t = ectx.type[self.val]['ethname']
3578 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3579 pars['TYPE_REF_TNAME'] = t
3580 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3581 if self.HasSizeConstraint():
3582 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3585 def eth_type_default_body(self, ectx, tname):
3587 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3588 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3590 if self.HasSizeConstraint():
3591 body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset',
3592 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3593 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3595 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3596 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3598 body = '#error Can not decode %s' % (tname)
3601 #--- SelectionType ------------------------------------------------------------
3602 class SelectionType (Type):
3603 def to_python (self, ctx):
3606 def sel_of_typeref(self):
3607 return self.typ.type == 'Type_Ref'
3609 def eth_reg_sub(self, ident, ectx):
3610 if not self.sel_of_typeref():
3613 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
3614 ectx.eth_dep_add(ident, self.seltype)
3616 def eth_ftype(self, ectx):
3617 (ftype, display) = ('FT_NONE', 'BASE_NONE')
3618 if self.sel_of_typeref() and not ectx.type[self.seltype]['import']:
3619 (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx)
3620 return (ftype, display)
3622 def GetTTag(self, ectx):
3623 #print "GetTTag(%s)\n" % self.seltype;
3624 if (ectx.type[self.seltype]['import']):
3625 if 'ttag' not in ectx.type[self.seltype]:
3626 if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
3627 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
3628 warnings.warn_explicit(msg, UserWarning, '', 0)
3629 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
3630 return ectx.type[self.seltype]['ttag']
3632 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
3634 def eth_type_default_pars(self, ectx, tname):
3635 pars = Type.eth_type_default_pars(self, ectx, tname)
3636 if self.sel_of_typeref():
3637 t = ectx.type[self.seltype]['ethname']
3638 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3639 pars['TYPE_REF_TNAME'] = t
3640 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3643 def eth_type_default_body(self, ectx, tname):
3644 if not self.sel_of_typeref():
3645 body = '#error Can not decode %s' % (tname)
3647 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3648 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3650 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3651 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3653 body = '#error Can not decode %s' % (tname)
3656 #--- TaggedType -----------------------------------------------------------------
3657 class TaggedType (Type):
3658 def eth_tname(self):
3660 for i in range(self.tstrip, len(self.val.tags)):
3661 tn += self.val.tags[i].eth_tname()
3663 tn += self.val.eth_tname()
3666 def eth_set_val_name(self, ident, val_name, ectx):
3667 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3668 self.val_name = val_name
3669 ectx.eth_dep_add(ident, self.val_name)
3671 def eth_reg_sub(self, ident, ectx):
3672 self.val_name = ident + '/' + '_untag'
3673 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
3675 def GetTTag(self, ectx):
3676 #print "GetTTag(%s)\n" % self.seltype;
3677 return self.GetTag(ectx)
3679 def eth_ftype(self, ectx):
3680 return self.val.eth_ftype(ectx)
3682 def eth_type_default_pars(self, ectx, tname):
3683 pars = Type.eth_type_default_pars(self, ectx, tname)
3684 t = ectx.type[self.val_name]['ethname']
3685 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3686 pars['TYPE_REF_TNAME'] = t
3687 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3688 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
3689 if self.HasImplicitTag(ectx):
3690 pars['TAG_IMPL'] = 'TRUE'
3692 pars['TAG_IMPL'] = 'FALSE'
3695 def eth_type_default_body(self, ectx, tname):
3697 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
3698 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3699 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
3701 body = '#error Can not decode %s' % (tname)
3704 #--- SqType -----------------------------------------------------------
3705 class SqType (Type):
3706 def out_item(self, f, val, optional, ext, ectx):
3707 ef = ectx.field[f]['ethname']
3708 t = ectx.eth_hf[ef]['ethtype']
3710 if (ectx.Ber() and ectx.field[f]['impl']):
3713 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
3714 #print val.str_depth(1)
3717 opt = 'BER_FLAGS_OPTIONAL'
3718 if (not val.HasOwnTag()):
3719 if (opt): opt += '|'
3720 opt += 'BER_FLAGS_NOOWNTAG'
3721 elif (val.HasImplicitTag(ectx)):
3722 if (opt): opt += '|'
3723 opt += 'BER_FLAGS_IMPLTAG'
3724 if (val.IndetermTag(ectx)):
3725 if (opt): opt += '|'
3726 opt += 'BER_FLAGS_NOTCHKTAG'
3727 if (not opt): opt = '0'
3730 opt = 'ASN1_OPTIONAL'
3732 opt = 'ASN1_NOT_OPTIONAL'
3734 (tc, tn) = val.GetTag(ectx)
3735 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3736 % ('&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
3738 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
3739 % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
3744 #--- SeqType -----------------------------------------------------------
3745 class SeqType (SqType):
3747 def need_components(self):
3748 lst = self.elt_list[:]
3749 if hasattr(self, 'ext_list'):
3750 lst.extend(self.ext_list)
3751 if hasattr(self, 'elt_list2'):
3752 lst.extend(self.elt_list2)
3754 if e.type == 'components_of':
3758 def expand_components(self, ectx):
3759 while self.need_components():
3760 for i in range(len(self.elt_list)):
3761 if self.elt_list[i].type == 'components_of':
3762 comp = self.elt_list[i].typ.get_components(ectx)
3763 self.elt_list[i:i+1] = comp
3765 if hasattr(self, 'ext_list'):
3766 for i in range(len(self.ext_list)):
3767 if self.ext_list[i].type == 'components_of':
3768 comp = self.ext_list[i].typ.get_components(ectx)
3769 self.ext_list[i:i+1] = comp
3771 if hasattr(self, 'elt_list2'):
3772 for i in range(len(self.elt_list2)):
3773 if self.elt_list2[i].type == 'components_of':
3774 comp = self.elt_list2[i].typ.get_components(ectx)
3775 self.elt_list2[i:i+1] = comp
3778 def get_components(self, ectx):
3779 lst = self.elt_list[:]
3780 if hasattr(self, 'elt_list2'):
3781 lst.extend(self.elt_list2)
3784 def eth_type_default_table(self, ectx, tname):
3785 #print "eth_type_default_table(tname='%s')" % (tname)
3786 fname = ectx.eth_type[tname]['ref'][0]
3787 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
3788 if hasattr(self, 'ext_list'):
3789 ext = 'ASN1_EXTENSION_ROOT'
3791 ext = 'ASN1_NO_EXTENSIONS'
3792 for e in (self.elt_list):
3793 f = fname + '/' + e.val.name
3794 table += self.out_item(f, e.val, e.optional, ext, ectx)
3795 if hasattr(self, 'ext_list'):
3796 for e in (self.ext_list):
3797 f = fname + '/' + e.val.name
3798 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
3799 if hasattr(self, 'elt_list2'):
3800 for e in (self.elt_list2):
3801 f = fname + '/' + e.val.name
3802 table += self.out_item(f, e.val, e.optional, ext, ectx)
3804 table += " { NULL, 0, 0, 0, NULL }\n};\n"
3806 table += " { NULL, 0, 0, NULL }\n};\n"
3809 #--- SeqOfType -----------------------------------------------------------
3810 class SeqOfType (SqType):
3811 def eth_type_default_table(self, ectx, tname):
3812 #print "eth_type_default_table(tname='%s')" % (tname)
3813 fname = ectx.eth_type[tname]['ref'][0]
3814 if self.val.IsNamed ():
3815 f = fname + '/' + self.val.name
3817 f = fname + '/' + '_item'
3818 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
3819 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
3823 #--- SequenceOfType -----------------------------------------------------------
3824 class SequenceOfType (SeqOfType):
3825 def to_python (self, ctx):
3826 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3827 # or '' + (1,) for optional
3829 if self.size_constr != None:
3830 print "#Ignoring size constraint:", self.size_constr.subtype
3831 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
3832 self.val.to_python (ctx),
3835 def eth_reg_sub(self, ident, ectx):
3837 if not self.val.IsNamed ():
3838 itmnm += '/' + '_item'
3839 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
3841 def eth_tname(self):
3842 if self.val.type != 'Type_Ref':
3843 return '#' + self.type + '_' + str(id(self))
3844 if not self.HasConstraint():
3845 return "SEQUENCE_OF_" + self.val.eth_tname()
3846 elif self.constr.IsSize():
3847 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
3849 return '#' + self.type + '_' + str(id(self))
3851 def eth_ftype(self, ectx):
3852 return ('FT_UINT32', 'BASE_DEC')
3854 def eth_need_tree(self):
3857 def GetTTag(self, ectx):
3858 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
3860 def eth_type_default_pars(self, ectx, tname):
3861 pars = Type.eth_type_default_pars(self, ectx, tname)
3862 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3863 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
3866 def eth_type_default_body(self, ectx, tname):
3868 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
3869 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3870 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3871 elif (ectx.Per() and not self.HasConstraint()):
3872 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
3873 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3874 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3875 elif (ectx.Per() and self.constr.type == 'Size'):
3876 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
3877 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3878 ('%(ETT_INDEX)s', '%(TABLE)s',),
3879 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
3881 body = '#error Can not decode %s' % (tname)
3885 #--- SetOfType ----------------------------------------------------------------
3886 class SetOfType (SeqOfType):
3887 def eth_reg_sub(self, ident, ectx):
3889 if not self.val.IsNamed ():
3890 itmnm += '/' + '_item'
3891 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
3893 def eth_tname(self):
3894 if self.val.type != 'Type_Ref':
3895 return '#' + self.type + '_' + str(id(self))
3896 if not self.HasConstraint():
3897 return "SET_OF_" + self.val.eth_tname()
3898 elif self.constr.IsSize():
3899 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
3901 return '#' + self.type + '_' + str(id(self))
3903 def eth_ftype(self, ectx):
3904 return ('FT_UINT32', 'BASE_DEC')
3906 def eth_need_tree(self):
3909 def GetTTag(self, ectx):
3910 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
3912 def eth_type_default_pars(self, ectx, tname):
3913 pars = Type.eth_type_default_pars(self, ectx, tname)
3914 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3915 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
3918 def eth_type_default_body(self, ectx, tname):
3920 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
3921 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3922 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3923 elif (ectx.Per() and not self.HasConstraint()):
3924 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
3925 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3926 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3927 elif (ectx.Per() and self.constr.type == 'Size'):
3928 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
3929 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3930 ('%(ETT_INDEX)s', '%(TABLE)s',),
3931 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),))
3933 body = '#error Can not decode %s' % (tname)
3936 def mk_tag_str (ctx, cls, typ, num):
3938 # XXX should do conversion to int earlier!
3941 if typ == 'DEFAULT':
3943 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
3945 #--- SequenceType -------------------------------------------------------------
3946 class SequenceType (SeqType):
3947 def to_python (self, ctx):
3948 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3949 # or '' + (1,) for optional
3950 # XXX should also collect names for SEQUENCE inside SEQUENCE or
3951 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
3952 # from? for others, element or arm name would be fine)
3953 seq_name = getattr (self, 'sequence_name', None)
3954 if seq_name == None:
3957 seq_name = "'" + seq_name + "'"
3958 if 'ext_list' in self.__dict__:
3959 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
3960 self.elts_to_py (self.elt_list, ctx),
3961 self.elts_to_py (self.ext_list, ctx), seq_name)
3963 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
3964 self.elts_to_py (self.elt_list, ctx), seq_name)
3965 def elts_to_py (self, list, ctx):
3966 # we have elt_type, val= named_type, maybe default=, optional=
3967 # named_type node: either ident = or typ =
3968 # need to dismember these in order to generate Python output syntax.
3971 assert (e.type == 'elt_type')
3973 optflag = e.optional
3974 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
3975 assert (nt.type == 'named_type')
3978 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
3979 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
3980 nt.typ.tag.tag_typ,nt.typ.tag.num)
3984 return "('%s',%s,%s,%d)" % (identstr, tagstr,
3985 nt.typ.to_python (ctx), optflag)
3986 indentstr = ",\n" + ctx.spaces ()
3987 rv = indentstr.join ([elt_to_py (e) for e in list])
3991 def eth_reg_sub(self, ident, ectx, components_available=False):
3992 if self.need_components():
3993 if components_available:
3994 self.expand_components(ectx)
3996 ectx.eth_comp_req(ident)
3998 for e in (self.elt_list):
3999 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4000 if hasattr(self, 'ext_list'):
4001 for e in (self.ext_list):
4002 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4003 if hasattr(self, 'elt_list2'):
4004 for e in (self.elt_list2):
4005 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4007 def eth_need_tree(self):
4010 def GetTTag(self, ectx):
4011 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4013 def eth_type_default_pars(self, ectx, tname):
4014 pars = Type.eth_type_default_pars(self, ectx, tname)
4015 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4018 def eth_type_default_body(self, ectx, tname):
4020 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4021 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4022 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4024 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4025 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4026 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4028 body = '#error Can not decode %s' % (tname)
4031 #--- SetType ------------------------------------------------------------------
4032 class SetType(SeqType):
4034 def eth_reg_sub(self, ident, ectx, components_available=False):
4035 if self.need_components():
4036 if components_available:
4037 self.expand_components(ectx)
4039 ectx.eth_comp_req(ident)
4041 for e in (self.elt_list):
4042 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4043 if hasattr(self, 'ext_list'):
4044 for e in (self.ext_list):
4045 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4047 def eth_need_tree(self):
4050 def GetTTag(self, ectx):
4051 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4053 def eth_type_default_pars(self, ectx, tname):
4054 pars = Type.eth_type_default_pars(self, ectx, tname)
4055 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4058 def eth_type_default_body(self, ectx, tname):
4060 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4061 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4062 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4064 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4065 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4066 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4068 body = '#error Can not decode %s' % (tname)
4071 #--- ChoiceType ---------------------------------------------------------------
4072 class ChoiceType (Type):
4073 def to_python (self, ctx):
4074 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4075 # or '' + (1,) for optional
4076 if 'ext_list' in self.__dict__:
4077 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
4078 self.elts_to_py (self.elt_list, ctx),
4079 self.elts_to_py (self.ext_list, ctx))
4081 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
4082 def elts_to_py (self, list, ctx):
4085 assert (nt.type == 'named_type')
4087 if hasattr (nt, 'ident'):
4090 if hasattr (nt.typ, 'val'):
4091 identstr = nt.typ.val # XXX, making up name
4092 elif hasattr (nt.typ, 'name'):
4093 identstr = nt.typ.name
4095 identstr = ctx.make_new_name ()
4097 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4098 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4099 nt.typ.tag.tag_typ,nt.typ.tag.num)
4103 return "('%s',%s,%s)" % (identstr, tagstr,
4104 nt.typ.to_python (ctx))
4105 indentstr = ",\n" + ctx.spaces ()
4106 rv = indentstr.join ([elt_to_py (e) for e in list])
4110 def eth_reg_sub(self, ident, ectx):
4111 #print "eth_reg_sub(ident='%s')" % (ident)
4112 for e in (self.elt_list):
4113 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4114 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4115 ectx.eth_sel_req(ident, e.name)
4116 if hasattr(self, 'ext_list'):
4117 for e in (self.ext_list):
4118 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4119 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4120 ectx.eth_sel_req(ident, e.name)
4122 def sel_item(self, ident, sel, ectx):
4123 lst = self.elt_list[:]
4124 if hasattr(self, 'ext_list'):
4125 lst.extend(self.ext_list)
4127 for e in (self.elt_list):
4128 if e.IsNamed() and (e.name == sel):
4132 print "#CHOICE %s does not contain item %s" % (ident, sel)
4135 def sel_req(self, ident, sel, ectx):
4136 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4137 ee = self.sel_item(ident, sel, ectx)
4139 ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
4141 def eth_ftype(self, ectx):
4142 return ('FT_UINT32', 'BASE_DEC')
4144 def eth_ftype_sel(self, sel, ectx):
4145 ee = self.sel_item('', sel, ectx)
4147 return ee.eth_ftype(ectx)
4149 return ('FT_NONE', 'BASE_NONE')
4151 def eth_strings(self):
4154 def eth_need_tree(self):
4157 def eth_has_vals(self):
4160 def GetTTag(self, ectx):
4162 cls = 'BER_CLASS_ANY/*choice*/'
4163 #if hasattr(self, 'ext_list'):
4164 # lst.extend(self.ext_list)
4166 # cls = lst[0].GetTag(ectx)[0]
4168 # if (e.GetTag(ectx)[0] != cls):
4169 # cls = '-1/*choice*/'
4170 return (cls, '-1/*choice*/')
4172 def GetTTagSel(self, sel, ectx):
4173 ee = self.sel_item('', sel, ectx)
4175 return ee.GetTag(ectx)
4177 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4179 def IndetermTag(self, ectx):
4180 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4181 return not self.HasOwnTag()
4183 def detect_tagval(self, ectx):
4185 lst = self.elt_list[:]
4186 if hasattr(self, 'ext_list'):
4187 lst.extend(self.ext_list)
4188 if (len(lst) > 0) and (not ectx.Per() or lst[0].HasOwnTag()):
4189 t = lst[0].GetTag(ectx)[0]
4194 if (t == 'BER_CLASS_UNI'):
4197 if not ectx.Per() or e.HasOwnTag():
4198 tt = e.GetTag(ectx)[0]
4206 def get_vals(self, ectx):
4207 tagval = self.detect_tagval(ectx)
4210 for e in (self.elt_list):
4211 if (tagval): val = e.GetTag(ectx)[1]
4212 else: val = str(cnt)
4213 vals.append((val, e.name))
4215 if hasattr(self, 'ext_list'):
4216 for e in (self.ext_list):
4217 if (tagval): val = e.GetTag(ectx)[1]
4218 else: val = str(cnt)
4219 vals.append((val, e.name))
4223 def eth_type_vals(self, tname, ectx):
4225 vals = self.get_vals(ectx)
4226 out += ectx.eth_vals(tname, vals)
4229 def reg_enum_vals(self, tname, ectx):
4230 vals = self.get_vals(ectx)
4231 for (val, id) in vals:
4232 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4234 def eth_type_enum(self, tname, ectx):
4236 vals = self.get_vals(ectx)
4237 out += ectx.eth_enum(tname, vals)
4240 def eth_type_default_pars(self, ectx, tname):
4241 pars = Type.eth_type_default_pars(self, ectx, tname)
4242 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4245 def eth_type_default_table(self, ectx, tname):
4246 def out_item(val, e, ext, ectx):
4247 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
4249 vval = ectx.eth_enum_item(tname, e.name)
4252 f = fname + '/' + e.name
4253 ef = ectx.field[f]['ethname']
4254 t = ectx.eth_hf[ef]['ethtype']
4256 if (ectx.field[f]['impl']):
4260 if (not e.HasOwnTag()):
4261 opt = 'BER_FLAGS_NOOWNTAG'
4262 elif (e.HasImplicitTag(ectx)):
4263 if (opt): opt += '|'
4264 opt += 'BER_FLAGS_IMPLTAG'
4265 if (not opt): opt = '0'
4267 (tc, tn) = e.GetTag(ectx)
4268 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4269 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
4271 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4272 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
4277 #print "eth_type_default_table(tname='%s')" % (tname)
4278 fname = ectx.eth_type[tname]['ref'][0]
4279 tagval = self.detect_tagval(ectx)
4280 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4282 if hasattr(self, 'ext_list'):
4283 ext = 'ASN1_EXTENSION_ROOT'
4285 ext = 'ASN1_NO_EXTENSIONS'
4286 for e in (self.elt_list):
4287 if (tagval): val = e.GetTag(ectx)[1]
4288 else: val = str(cnt)
4289 table += out_item(val, e, ext, ectx)
4291 if hasattr(self, 'ext_list'):
4292 for e in (self.ext_list):
4293 if (tagval): val = e.GetTag(ectx)[1]
4294 else: val = str(cnt)
4295 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4298 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4300 table += " { 0, NULL, 0, NULL }\n};\n"
4303 def eth_type_default_body(self, ectx, tname):
4305 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4306 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4307 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4310 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4311 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4312 ('%(ETT_INDEX)s', '%(TABLE)s',),
4315 body = '#error Can not decode %s' % (tname)
4318 #--- ChoiceValue ----------------------------------------------------
4319 class ChoiceValue (Value):
4320 def to_str(self, ectx):
4321 return self.val.to_str(ectx)
4323 def fld_obj_eq(self, other):
4324 return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
4326 #--- EnumeratedType -----------------------------------------------------------
4327 class EnumeratedType (Type):
4328 def to_python (self, ctx):
4329 def strify_one (named_num):
4330 return "%s=%s" % (named_num.ident, named_num.val)
4331 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
4333 def eth_ftype(self, ectx):
4334 return ('FT_UINT32', 'BASE_DEC')
4336 def eth_strings(self):
4339 def eth_has_vals(self):
4342 def GetTTag(self, ectx):
4343 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4345 def get_vals_etc(self, ectx):
4353 for e in (self.val):
4354 if e.type == 'NamedNumber':
4355 used[int(e.val)] = True
4356 for e in (self.val):
4357 if e.type == 'NamedNumber':
4360 while lastv in used:
4364 vals.append((val, e.ident))
4365 map_table.append(val)
4369 if self.ext is not None:
4370 for e in (self.ext):
4371 if e.type == 'NamedNumber':
4372 used[int(e.val)] = True
4373 for e in (self.ext):
4374 if e.type == 'NamedNumber':
4377 while lastv in used:
4381 vals.append((val, e.ident))
4382 map_table.append(val)
4387 for i in range(len(map_table)):
4388 need_map = need_map or (map_table[i] != i)
4391 return (vals, root_num, ext_num, map_table)
4393 def eth_type_vals(self, tname, ectx):
4395 vals = self.get_vals_etc(ectx)[0]
4396 out += ectx.eth_vals(tname, vals)
4399 def reg_enum_vals(self, tname, ectx):
4400 vals = self.get_vals_etc(ectx)[0]
4401 for (val, id) in vals:
4402 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4404 def eth_type_enum(self, tname, ectx):
4406 vals = self.get_vals_etc(ectx)[0]
4407 out += ectx.eth_enum(tname, vals)
4410 def eth_type_default_pars(self, ectx, tname):
4411 pars = Type.eth_type_default_pars(self, ectx, tname)
4412 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
4413 if (self.ext != None):
4417 pars['ROOT_NUM'] = str(root_num)
4419 pars['EXT_NUM'] = str(ext_num)
4421 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4423 pars['TABLE'] = 'NULL'
4426 def eth_type_default_table(self, ectx, tname):
4427 if (not ectx.Per()): return ''
4428 map_table = self.get_vals_etc(ectx)[3]
4429 if (map_table == None): return ''
4430 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4431 table += ", ".join([str(v) for v in map_table])
4435 def eth_type_default_body(self, ectx, tname):
4437 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4438 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4441 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
4442 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4443 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4445 body = '#error Can not decode %s' % (tname)
4448 #--- EmbeddedPDVType -----------------------------------------------------------
4449 class EmbeddedPDVType (Type):
4450 def eth_tname(self):
4451 return 'EMBEDDED_PDV'
4453 def eth_ftype(self, ectx):
4454 return ('FT_NONE', 'BASE_NONE')
4456 def GetTTag(self, ectx):
4457 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4459 def eth_type_default_pars(self, ectx, tname):
4460 pars = Type.eth_type_default_pars(self, ectx, tname)
4461 if ectx.default_embedded_pdv_cb:
4462 pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb
4464 pars['TYPE_REF_FN'] = 'NULL'
4467 def eth_type_default_body(self, ectx, tname):
4469 body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset',
4470 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4472 body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset',
4473 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4475 body = '#error Can not decode %s' % (tname)
4478 #--- ExternalType -----------------------------------------------------------
4479 class ExternalType (Type):
4480 def eth_tname(self):
4483 def eth_ftype(self, ectx):
4484 return ('FT_NONE', 'BASE_NONE')
4486 def GetTTag(self, ectx):
4487 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4489 def eth_type_default_pars(self, ectx, tname):
4490 pars = Type.eth_type_default_pars(self, ectx, tname)
4491 if ectx.default_external_type_cb:
4492 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4494 pars['TYPE_REF_FN'] = 'NULL'
4497 def eth_type_default_body(self, ectx, tname):
4499 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4500 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4502 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4503 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4505 body = '#error Can not decode %s' % (tname)
4508 #--- OpenType -----------------------------------------------------------
4509 class OpenType (Type):
4510 def to_python (self, ctx):
4513 def single_type(self):
4514 if (self.HasConstraint() and
4515 self.constr.type == 'Type' and
4516 self.constr.subtype.type == 'Type_Ref'):
4517 return self.constr.subtype.val
4520 def eth_reg_sub(self, ident, ectx):
4521 t = self.single_type()
4523 ectx.eth_dep_add(ident, t)
4525 def eth_tname(self):
4526 t = self.single_type()
4528 return 'OpenType_' + t
4530 return Type.eth_tname(self)
4532 def eth_ftype(self, ectx):
4533 return ('FT_NONE', 'BASE_NONE')
4535 def GetTTag(self, ectx):
4536 return ('BER_CLASS_ANY', '0')
4538 def eth_type_default_pars(self, ectx, tname):
4539 pars = Type.eth_type_default_pars(self, ectx, tname)
4540 pars['FN_VARIANT'] = ectx.default_opentype_variant
4541 t = self.single_type()
4543 t = ectx.type[t]['ethname']
4544 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4545 pars['TYPE_REF_TNAME'] = t
4546 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4548 pars['TYPE_REF_FN'] = 'NULL'
4551 def eth_type_default_body(self, ectx, tname):
4553 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
4554 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4556 body = '#error Can not decode %s' % (tname)
4559 #--- InstanceOfType -----------------------------------------------------------
4560 class InstanceOfType (Type):
4561 def eth_tname(self):
4562 return 'INSTANCE_OF'
4564 def eth_ftype(self, ectx):
4565 return ('FT_NONE', 'BASE_NONE')
4567 def GetTTag(self, ectx):
4568 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4570 def eth_type_default_pars(self, ectx, tname):
4571 pars = Type.eth_type_default_pars(self, ectx, tname)
4572 if ectx.default_external_type_cb:
4573 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4575 pars['TYPE_REF_FN'] = 'NULL'
4578 def eth_type_default_body(self, ectx, tname):
4580 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4581 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4583 body = '#error Can not decode %s' % (tname)
4585 body = '#error Can not decode %s' % (tname)
4588 #--- AnyType -----------------------------------------------------------
4589 class AnyType (Type):
4590 def to_python (self, ctx):
4593 def eth_ftype(self, ectx):
4594 return ('FT_NONE', 'BASE_NONE')
4596 def GetTTag(self, ectx):
4597 return ('BER_CLASS_ANY', '0')
4599 def eth_type_default_body(self, ectx, tname):
4600 body = '#error Can not decode %s' % (tname)
4603 class Literal (Node):
4604 def to_python (self, ctx):
4607 #--- NullType -----------------------------------------------------------------
4608 class NullType (Type):
4609 def to_python (self, ctx):
4612 def eth_tname(self):
4615 def GetTTag(self, ectx):
4616 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
4618 def eth_type_default_body(self, ectx, tname):
4620 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4621 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4623 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4624 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4626 body = '#error Can not decode %s' % (tname)
4629 #--- NullValue ----------------------------------------------------
4630 class NullValue (Value):
4631 def to_str(self, ectx):
4634 #--- RealType -----------------------------------------------------------------
4635 class RealType (Type):
4636 def to_python (self, ctx):
4639 def eth_tname(self):
4642 def GetTTag(self, ectx):
4643 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
4645 def eth_ftype(self, ectx):
4646 return ('FT_DOUBLE', 'BASE_NONE')
4648 def eth_type_default_body(self, ectx, tname):
4650 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4651 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4654 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4655 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4657 body = '#error Can not decode %s' % (tname)
4660 #--- BooleanType --------------------------------------------------------------
4661 class BooleanType (Type):
4662 def to_python (self, ctx):
4663 return 'asn1.BOOLEAN'
4665 def eth_tname(self):
4668 def GetTTag(self, ectx):
4669 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
4671 def eth_ftype(self, ectx):
4672 return ('FT_BOOLEAN', 'BASE_NONE')
4674 def eth_type_default_body(self, ectx, tname):
4676 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4677 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
4679 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4680 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4682 body = '#error Can not decode %s' % (tname)
4685 #--- OctetStringType ----------------------------------------------------------
4686 class OctetStringType (Type):
4687 def to_python (self, ctx):
4688 return 'asn1.OCTSTRING'
4690 def eth_tname(self):
4691 if not self.HasConstraint():
4692 return 'OCTET_STRING'
4693 elif self.constr.type == 'Size':
4694 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
4696 return '#' + self.type + '_' + str(id(self))
4698 def eth_ftype(self, ectx):
4699 return ('FT_BYTES', 'BASE_NONE')
4701 def GetTTag(self, ectx):
4702 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
4704 def eth_need_pdu(self, ectx):
4706 if self.HasContentsConstraint():
4707 t = self.constr.GetContents(ectx)
4708 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
4710 'new' : ectx.default_containing_variant == '_pdu_new' }
4713 def eth_type_default_pars(self, ectx, tname):
4714 pars = Type.eth_type_default_pars(self, ectx, tname)
4715 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4716 if self.HasContentsConstraint():
4717 pars['FN_VARIANT'] = ectx.default_containing_variant
4718 t = self.constr.GetContents(ectx)
4720 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
4721 t = ectx.field[t]['ethname']
4722 pars['TYPE_REF_PROTO'] = ''
4723 pars['TYPE_REF_TNAME'] = t
4724 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
4726 t = ectx.type[t]['ethname']
4727 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4728 pars['TYPE_REF_TNAME'] = t
4729 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4731 pars['TYPE_REF_FN'] = 'NULL'
4734 def eth_type_default_body(self, ectx, tname):
4736 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
4737 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4740 if self.HasContentsConstraint():
4741 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
4742 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4743 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
4745 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
4746 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4747 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
4749 body = '#error Can not decode %s' % (tname)
4752 #--- CharacterStringType ------------------------------------------------------
4753 class CharacterStringType (Type):
4754 def eth_tname(self):
4755 if not self.HasConstraint():
4756 return self.eth_tsname()
4757 elif self.constr.type == 'Size':
4758 return self.eth_tsname() + '_' + self.constr.eth_constrname()
4760 return '#' + self.type + '_' + str(id(self))
4762 def eth_ftype(self, ectx):
4763 return ('FT_STRING', 'BASE_NONE')
4765 class RestrictedCharacterStringType (CharacterStringType):
4766 def to_python (self, ctx):
4767 return 'asn1.' + self.eth_tsname()
4769 def GetTTag(self, ectx):
4770 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
4772 def eth_type_default_pars(self, ectx, tname):
4773 pars = Type.eth_type_default_pars(self, ectx, tname)
4774 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4775 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
4776 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
4779 def eth_type_default_body(self, ectx, tname):
4781 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
4782 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
4783 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4785 elif (ectx.Per() and self.HasPermAlph()):
4786 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
4787 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4788 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
4791 if (self.eth_tsname() == 'GeneralString'):
4792 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4793 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4794 elif (self.eth_tsname() == 'GeneralizedTime'):
4795 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
4796 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4797 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4798 elif (self.eth_tsname() == 'UTCTime'):
4799 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
4800 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4801 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4803 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4804 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4805 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4807 body = '#error Can not decode %s' % (tname)
4810 class BMPStringType (RestrictedCharacterStringType):
4811 def eth_tsname(self):
4814 class GeneralStringType (RestrictedCharacterStringType):
4815 def eth_tsname(self):
4816 return 'GeneralString'
4818 class GraphicStringType (RestrictedCharacterStringType):
4819 def eth_tsname(self):
4820 return 'GraphicString'
4822 class IA5StringType (RestrictedCharacterStringType):
4823 def eth_tsname(self):
4826 class NumericStringType (RestrictedCharacterStringType):
4827 def eth_tsname(self):
4828 return 'NumericString'
4830 class PrintableStringType (RestrictedCharacterStringType):
4831 def eth_tsname(self):
4832 return 'PrintableString'
4834 class TeletexStringType (RestrictedCharacterStringType):
4835 def eth_tsname(self):
4836 return 'TeletexString'
4838 class T61StringType (RestrictedCharacterStringType):
4839 def eth_tsname(self):
4841 def GetTTag(self, ectx):
4842 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
4844 class UniversalStringType (RestrictedCharacterStringType):
4845 def eth_tsname(self):
4846 return 'UniversalString'
4848 class UTF8StringType (RestrictedCharacterStringType):
4849 def eth_tsname(self):
4852 class VideotexStringType (RestrictedCharacterStringType):
4853 def eth_tsname(self):
4854 return 'VideotexString'
4856 class VisibleStringType (RestrictedCharacterStringType):
4857 def eth_tsname(self):
4858 return 'VisibleString'
4860 class ISO646StringType (RestrictedCharacterStringType):
4861 def eth_tsname(self):
4862 return 'ISO646String'
4863 def GetTTag(self, ectx):
4864 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
4866 class UnrestrictedCharacterStringType (CharacterStringType):
4867 def to_python (self, ctx):
4868 return 'asn1.UnrestrictedCharacterString'
4869 def eth_tsname(self):
4870 return 'CHARACTER_STRING'
4872 #--- UsefulType ---------------------------------------------------------------
4873 class GeneralizedTime (RestrictedCharacterStringType):
4874 def eth_tsname(self):
4875 return 'GeneralizedTime'
4877 def eth_type_default_body(self, ectx, tname):
4879 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4880 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4883 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4885 class UTCTime (RestrictedCharacterStringType):
4886 def eth_tsname(self):
4889 def eth_type_default_body(self, ectx, tname):
4891 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4892 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4895 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4897 class ObjectDescriptor (RestrictedCharacterStringType):
4898 def eth_tsname(self):
4899 return 'ObjectDescriptor'
4901 def eth_type_default_body(self, ectx, tname):
4903 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4905 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
4906 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4908 body = '#error Can not decode %s' % (tname)
4911 #--- ObjectIdentifierType -----------------------------------------------------
4912 class ObjectIdentifierType (Type):
4913 def to_python (self, ctx):
4914 return 'asn1.OBJECT_IDENTIFIER'
4916 def eth_tname(self):
4917 return 'OBJECT_IDENTIFIER'
4919 def eth_ftype(self, ectx):
4920 return ('FT_OID', 'BASE_NONE')
4922 def GetTTag(self, ectx):
4923 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
4925 def eth_type_default_pars(self, ectx, tname):
4926 pars = Type.eth_type_default_pars(self, ectx, tname)
4927 pars['FN_VARIANT'] = ectx.default_oid_variant
4930 def eth_type_default_body(self, ectx, tname):
4932 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
4933 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4935 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
4936 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4938 body = '#error Can not decode %s' % (tname)
4941 #--- ObjectIdentifierValue ----------------------------------------------------
4942 class ObjectIdentifierValue (Value):
4943 def get_num(self, path, val):
4944 return str(oid_names.get(path + '/' + val, val))
4946 def to_str(self, ectx):
4951 for v in self.comp_list:
4952 if isinstance(v, Node) and (v.type == 'name_and_number'):
4957 vstr = self.get_num(path, v)
4958 if not first and not vstr.isdigit():
4959 vstr = ectx.value_get_val(vstr)
4964 out += ectx.value_get_eth(vstr) + '"'
4974 v = self.comp_list[0]
4975 if isinstance(v, Node) and (v.type == 'name_and_number'):
4980 vstr = self.get_num('', v)
4986 class NamedNumber(Node):
4987 def to_python (self, ctx):
4988 return "('%s',%s)" % (self.ident, self.val)
4990 class NamedNumListBase(Node):
4991 def to_python (self, ctx):
4992 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
4993 [x.to_python (ctx) for x in self.named_list]))
4995 #--- RelativeOIDType ----------------------------------------------------------
4996 class RelativeOIDType (Type):
4998 def eth_tname(self):
4999 return 'RELATIVE_OID'
5001 def eth_ftype(self, ectx):
5002 return ('FT_BYTES', 'BASE_NONE')
5004 def GetTTag(self, ectx):
5005 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5007 def eth_type_default_pars(self, ectx, tname):
5008 pars = Type.eth_type_default_pars(self, ectx, tname)
5009 pars['FN_VARIANT'] = ectx.default_oid_variant
5012 def eth_type_default_body(self, ectx, tname):
5014 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5015 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5017 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5018 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5020 body = '#error Can not decode %s' % (tname)
5024 #--- IntegerType --------------------------------------------------------------
5025 class IntegerType (Type):
5026 def to_python (self, ctx):
5027 return "asn1.INTEGER_class ([%s])" % (",".join (
5028 [x.to_python (ctx) for x in self.named_list]))
5030 def add_named_value(self, ident, val):
5031 e = NamedNumber(ident = ident, val = val)
5032 if not self.named_list:
5033 self.named_list = []
5034 self.named_list.append(e)
5036 def eth_tname(self):
5038 return Type.eth_tname(self)
5039 if not self.HasConstraint():
5041 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
5042 return 'INTEGER' + '_' + self.constr.eth_constrname()
5044 return 'INTEGER' + '_' + self.constr.eth_tname()
5046 def GetTTag(self, ectx):
5047 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5050 def eth_ftype(self, ectx):
5051 if self.HasConstraint():
5052 if not self.constr.IsNegativ():
5053 return ('FT_UINT32', 'BASE_DEC')
5054 return ('FT_INT32', 'BASE_DEC')
5056 def eth_strings(self):
5057 if (self.named_list):
5062 def eth_has_vals(self):
5063 if (self.named_list):
5068 def get_vals(self, ectx):
5070 for e in (self.named_list):
5071 vals.append((int(e.val), e.ident))
5074 def eth_type_vals(self, tname, ectx):
5075 if not self.eth_has_vals(): return ''
5077 vals = self.get_vals(ectx)
5078 out += ectx.eth_vals(tname, vals)
5081 def reg_enum_vals(self, tname, ectx):
5082 vals = self.get_vals(ectx)
5083 for (val, id) in vals:
5084 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
5086 def eth_type_enum(self, tname, ectx):
5087 if not self.eth_has_enum(tname, ectx): return ''
5089 vals = self.get_vals(ectx)
5090 out += ectx.eth_enum(tname, vals)
5093 def eth_type_default_pars(self, ectx, tname):
5094 pars = Type.eth_type_default_pars(self, ectx, tname)
5095 if self.HasValueConstraint():
5096 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
5099 def eth_type_default_body(self, ectx, tname):
5101 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5102 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5104 elif (ectx.Per() and not self.HasValueConstraint()):
5105 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5106 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5107 elif (ectx.Per() and self.HasValueConstraint()):
5108 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5109 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5110 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5112 body = '#error Can not decode %s' % (tname)
5115 #--- BitStringType ------------------------------------------------------------
5116 class BitStringType (Type):
5117 def to_python (self, ctx):
5118 return "asn1.BITSTRING_class ([%s])" % (",".join (
5119 [x.to_python (ctx) for x in self.named_list]))
5121 def eth_tname(self):
5123 return Type.eth_tname(self)
5124 elif not self.HasConstraint():
5126 elif self.constr.IsSize():
5127 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
5129 return '#' + self.type + '_' + str(id(self))
5131 def GetTTag(self, ectx):
5132 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5134 def eth_ftype(self, ectx):
5135 return ('FT_BYTES', 'BASE_NONE')
5137 def eth_need_tree(self):
5138 return self.named_list
5140 def eth_need_pdu(self, ectx):
5142 if self.HasContentsConstraint():
5143 t = self.constr.GetContents(ectx)
5144 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5146 'new' : ectx.default_containing_variant == '_pdu_new' }
5149 def eth_named_bits(self):
5151 if (self.named_list):
5152 for e in (self.named_list):
5153 bits.append((int(e.val), e.ident))
5156 def eth_type_default_pars(self, ectx, tname):
5157 pars = Type.eth_type_default_pars(self, ectx, tname)
5158 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5159 if 'ETT_INDEX' not in pars:
5160 pars['ETT_INDEX'] = '-1'
5161 pars['TABLE'] = 'NULL'
5162 if self.eth_named_bits():
5163 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5164 if self.HasContentsConstraint():
5165 pars['FN_VARIANT'] = ectx.default_containing_variant
5166 t = self.constr.GetContents(ectx)
5168 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5169 t = ectx.field[t]['ethname']
5170 pars['TYPE_REF_PROTO'] = ''
5171 pars['TYPE_REF_TNAME'] = t
5172 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5174 t = ectx.type[t]['ethname']
5175 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5176 pars['TYPE_REF_TNAME'] = t
5177 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5179 pars['TYPE_REF_FN'] = 'NULL'
5182 def eth_type_default_table(self, ectx, tname):
5183 #print "eth_type_default_table(tname='%s')" % (tname)
5185 bits = self.eth_named_bits()
5186 if (bits and ectx.Ber()):
5187 table = ectx.eth_bits(tname, bits)
5190 def eth_type_default_body(self, ectx, tname):
5192 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
5193 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5194 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5197 if self.HasContentsConstraint():
5198 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
5199 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5200 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5202 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
5203 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5204 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s'),))
5206 body = '#error Can not decode %s' % (tname)
5209 #--- BStringValue ------------------------------------------------------------
5228 class BStringValue (Value):
5229 def to_str(self, ectx):
5232 v += '0' * (8 - len(v) % 8)
5234 for i in (range(0, len(v), 4)):
5235 vv += bstring_tab[v[i:i+4]]
5238 #--- HStringValue ------------------------------------------------------------
5239 class HStringValue (Value):
5240 def to_str(self, ectx):
5242 vv += self.val[1:-2]
5245 #--- FieldSpec ----------------------------------------------------------------
5246 class FieldSpec (Node):
5247 def __init__(self,*args, **kw) :
5249 Node.__init__ (self,*args, **kw)
5251 def SetName(self, name):
5255 return ['#UNSUPPORTED_' + self.type]
5259 repr.extend(self.get_repr())
5262 class TypeFieldSpec (FieldSpec):
5266 class FixedTypeValueFieldSpec (FieldSpec):
5268 if isinstance(self.typ, Type_Ref):
5269 repr = ['TypeReference', self.typ.val]
5271 repr = [self.typ.type]
5274 class VariableTypeValueFieldSpec (FieldSpec):
5276 return ['_' + self.type]
5278 class FixedTypeValueSetFieldSpec (FieldSpec):
5280 return ['_' + self.type]
5282 class ObjectFieldSpec (FieldSpec):
5284 return ['ClassReference', self.cls.val]
5286 class ObjectSetFieldSpec (FieldSpec):
5288 return ['ClassReference', self.cls.val]
5290 #==============================================================================
5292 def p_module_list_1 (t):
5293 'module_list : module_list ModuleDefinition'
5294 t[0] = t[1] + [t[2]]
5296 def p_module_list_2 (t):
5297 'module_list : ModuleDefinition'
5301 #--- ITU-T Recommendation X.680 -----------------------------------------------
5304 # 11 ASN.1 lexical items --------------------------------------------------------
5306 # 11.2 Type references
5308 'type_ref : UCASE_IDENT'
5309 t[0] = Type_Ref(val=t[1])
5312 def p_identifier (t):
5313 'identifier : LCASE_IDENT'
5316 # 11.4 Value references
5317 # cause reduce/reduce conflict
5318 #def p_valuereference (t):
5319 # 'valuereference : LCASE_IDENT'
5320 # t[0] = Value_Ref(val=t[1])
5322 # 11.5 Module references
5323 def p_modulereference (t):
5324 'modulereference : UCASE_IDENT'
5328 # 12 Module definition --------------------------------------------------------
5331 def p_ModuleDefinition (t):
5332 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5333 t[0] = Module (ident = t[1], tag_def = t[3], body = t[7])
5335 def p_ModuleBegin (t):
5337 if t[-4].val == 'Remote-Operations-Information-Objects':
5340 def p_TagDefault_1 (t):
5341 '''TagDefault : EXPLICIT TAGS
5344 t[0] = Default_Tags (dfl_tag = t[1])
5346 def p_TagDefault_2 (t):
5348 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5349 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
5351 def p_ModuleIdentifier_1 (t):
5352 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5353 t [0] = Node('module_ident', val = t[1], ident = t[2])
5355 def p_ModuleIdentifier_2 (t):
5356 'ModuleIdentifier : modulereference' # name, oid
5357 t [0] = Node('module_ident', val = t[1], ident = None)
5359 def p_DefinitiveIdentifier (t):
5360 'DefinitiveIdentifier : ObjectIdentifierValue'
5363 #def p_module_ref (t):
5364 # 'module_ref : UCASE_IDENT'
5367 def p_ModuleBody_1 (t):
5368 'ModuleBody : Exports Imports AssignmentList'
5369 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
5371 def p_ModuleBody_2 (t):
5373 t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
5375 def p_Exports_1 (t):
5376 'Exports : EXPORTS syms_exported SEMICOLON'
5379 def p_Exports_2 (t):
5380 'Exports : EXPORTS ALL SEMICOLON'
5383 def p_Exports_3 (t):
5387 def p_syms_exported_1 (t):
5388 'syms_exported : exp_sym_list'
5391 def p_syms_exported_2 (t):
5395 def p_exp_sym_list_1 (t):
5396 'exp_sym_list : Symbol'
5399 def p_exp_sym_list_2 (t):
5400 'exp_sym_list : exp_sym_list COMMA Symbol'
5401 t[0] = t[1] + [t[3]]
5404 def p_Imports_1 (t):
5405 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5407 global lcase_ident_assigned
5408 lcase_ident_assigned = {}
5410 def p_importsbegin (t):
5412 global lcase_ident_assigned
5414 lcase_ident_assigned = {}
5415 lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5417 def p_Imports_2 (t):
5421 def p_SymbolsImported_1(t):
5422 'SymbolsImported : '
5425 def p_SymbolsImported_2 (t):
5426 'SymbolsImported : SymbolsFromModuleList'
5429 def p_SymbolsFromModuleList_1 (t):
5430 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5431 t[0] = t[1] + [t[2]]
5433 def p_SymbolsFromModuleList_2 (t):
5434 'SymbolsFromModuleList : SymbolsFromModule'
5437 def p_SymbolsFromModule (t):
5438 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
5439 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
5440 for s in (t[0].symbol_list):
5441 if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
5442 import_symbols_from_module(t[0].module, t[0].symbol_list)
5444 def import_symbols_from_module(module, symbol_list):
5445 if module.val == 'Remote-Operations-Information-Objects':
5446 for i in range(len(symbol_list)):
5448 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
5450 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5451 symbol_list[i] = Class_Ref (val = s.val)
5453 for i in range(len(symbol_list)):
5455 if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)):
5456 import_class_from_module(module.val, s.val)
5457 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5458 symbol_list[i] = Class_Ref (val = s.val)
5460 def p_GlobalModuleReference (t):
5461 'GlobalModuleReference : modulereference AssignedIdentifier'
5462 t [0] = Node('module_ident', val = t[1], ident = t[2])
5464 def p_AssignedIdentifier_1 (t):
5465 'AssignedIdentifier : ObjectIdentifierValue'
5468 def p_AssignedIdentifier_2 (t):
5469 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5472 def p_AssignedIdentifier_3 (t):
5473 'AssignedIdentifier : '
5476 def p_SymbolList_1 (t):
5477 'SymbolList : Symbol'
5480 def p_SymbolList_2 (t):
5481 'SymbolList : SymbolList COMMA Symbol'
5482 t[0] = t[1] + [t[3]]
5485 '''Symbol : Reference
5486 | ParameterizedReference'''
5489 def p_Reference_1 (t):
5490 '''Reference : type_ref
5491 | objectclassreference '''
5494 def p_Reference_2 (t):
5495 '''Reference : LCASE_IDENT_ASSIGNED
5496 | identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5497 t[0] = Value_Ref(val=t[1])
5499 def p_AssignmentList_1 (t):
5500 'AssignmentList : AssignmentList Assignment'
5501 t[0] = t[1] + [t[2]]
5503 def p_AssignmentList_2 (t):
5504 'AssignmentList : Assignment SEMICOLON'
5507 def p_AssignmentList_3 (t):
5508 'AssignmentList : Assignment'
5511 def p_Assignment (t):
5512 '''Assignment : TypeAssignment
5514 | ValueSetTypeAssignment
5515 | ObjectClassAssignment
5517 | ObjectSetAssignment
5518 | ParameterizedAssignment
5523 # 13 Referencing type and value definitions -----------------------------------
5526 def p_DefinedType (t):
5527 '''DefinedType : ExternalTypeReference
5529 | ParameterizedType'''
5532 def p_DefinedValue_1(t):
5533 '''DefinedValue : ExternalValueReference'''
5536 def p_DefinedValue_2(t):
5537 '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5538 t[0] = Value_Ref(val=t[1])
5541 def p_ExternalTypeReference (t):
5542 'ExternalTypeReference : modulereference DOT type_ref'
5543 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
5545 def p_ExternalValueReference (t):
5546 'ExternalValueReference : modulereference DOT identifier'
5547 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
5550 # 15 Assigning types and values -----------------------------------------------
5553 def p_TypeAssignment (t):
5554 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
5559 def p_ValueAssignment (t):
5560 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
5561 t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
5563 # only "simple" types are supported to simplify grammer
5564 def p_ValueType (t):
5565 '''ValueType : type_ref
5568 | ObjectIdentifierType
5575 def p_ValueSetTypeAssignment (t):
5576 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
5577 t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4])
5581 'ValueSet : lbraceignore rbraceignore'
5585 # 16 Definition of types and values -------------------------------------------
5589 '''Type : BuiltinType
5591 | ConstrainedType'''
5595 def p_BuiltinType (t):
5596 '''BuiltinType : AnyType
5599 | CharacterStringType
5607 | ObjectClassFieldType
5608 | ObjectIdentifierType
5620 def p_ReferencedType (t):
5621 '''ReferencedType : DefinedType
5627 def p_NamedType (t):
5628 'NamedType : identifier Type'
5634 '''Value : BuiltinValue
5636 | ObjectClassFieldValue'''
5640 def p_BuiltinValue (t):
5641 '''BuiltinValue : BooleanValue
5644 | ObjectIdentifierValue
5649 | char_string''' # XXX we don't support {data} here
5653 def p_ReferencedValue (t):
5654 '''ReferencedValue : DefinedValue
5655 | ValueFromObject'''
5659 #def p_NamedValue (t):
5660 # 'NamedValue : identifier Value'
5661 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
5664 # 17 Notation for the boolean type --------------------------------------------
5667 def p_BooleanType (t):
5668 'BooleanType : BOOLEAN'
5669 t[0] = BooleanType ()
5672 def p_BooleanValue (t):
5673 '''BooleanValue : TRUE
5678 # 18 Notation for the integer type --------------------------------------------
5681 def p_IntegerType_1 (t):
5682 'IntegerType : INTEGER'
5683 t[0] = IntegerType (named_list = None)
5685 def p_IntegerType_2 (t):
5686 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
5687 t[0] = IntegerType(named_list = t[3])
5689 def p_NamedNumberList_1 (t):
5690 'NamedNumberList : NamedNumber'
5693 def p_NamedNumberList_2 (t):
5694 'NamedNumberList : NamedNumberList COMMA NamedNumber'
5695 t[0] = t[1] + [t[3]]
5697 def p_NamedNumber (t):
5698 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
5699 | identifier LPAREN DefinedValue RPAREN'''
5700 t[0] = NamedNumber(ident = t[1], val = t[3])
5702 def p_SignedNumber_1 (t):
5703 'SignedNumber : NUMBER'
5706 def p_SignedNumber_2 (t):
5707 'SignedNumber : MINUS NUMBER'
5711 def p_IntegerValue (t):
5712 'IntegerValue : SignedNumber'
5715 # 19 Notation for the enumerated type -----------------------------------------
5718 def p_EnumeratedType (t):
5719 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
5720 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
5722 def p_Enumerations_1 (t):
5723 'Enumerations : Enumeration'
5724 t[0] = { 'val' : t[1], 'ext' : None }
5726 def p_Enumerations_2 (t):
5727 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
5728 t[0] = { 'val' : t[1], 'ext' : [] }
5730 def p_Enumerations_3 (t):
5731 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
5732 t[0] = { 'val' : t[1], 'ext' : t[6] }
5734 def p_Enumeration_1 (t):
5735 'Enumeration : EnumerationItem'
5738 def p_Enumeration_2 (t):
5739 'Enumeration : Enumeration COMMA EnumerationItem'
5740 t[0] = t[1] + [t[3]]
5742 def p_EnumerationItem (t):
5743 '''EnumerationItem : Identifier
5747 def p_Identifier (t):
5748 'Identifier : identifier'
5749 t[0] = Node ('Identifier', ident = t[1])
5752 # 20 Notation for the real type -----------------------------------------------
5760 def p_RealValue (t):
5761 '''RealValue : REAL_NUMBER
5762 | SpecialRealValue'''
5765 def p_SpecialRealValue (t):
5766 '''SpecialRealValue : PLUS_INFINITY
5771 # 21 Notation for the bitstring type ------------------------------------------
5774 def p_BitStringType_1 (t):
5775 'BitStringType : BIT STRING'
5776 t[0] = BitStringType (named_list = None)
5778 def p_BitStringType_2 (t):
5779 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
5780 t[0] = BitStringType (named_list = t[4])
5782 def p_NamedBitList_1 (t):
5783 'NamedBitList : NamedBit'
5786 def p_NamedBitList_2 (t):
5787 'NamedBitList : NamedBitList COMMA NamedBit'
5788 t[0] = t[1] + [t[3]]
5791 '''NamedBit : identifier LPAREN NUMBER RPAREN
5792 | identifier LPAREN DefinedValue RPAREN'''
5793 t[0] = NamedNumber (ident = t[1], val = t[3])
5796 # 22 Notation for the octetstring type ----------------------------------------
5799 def p_OctetStringType (t):
5800 'OctetStringType : OCTET STRING'
5801 t[0] = OctetStringType ()
5804 # 23 Notation for the null type -----------------------------------------------
5812 def p_NullValue (t):
5817 # 24 Notation for sequence types ----------------------------------------------
5820 def p_SequenceType_1 (t):
5821 'SequenceType : SEQUENCE LBRACE RBRACE'
5822 t[0] = SequenceType (elt_list = [])
5824 def p_SequenceType_2 (t):
5825 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
5826 t[0] = SequenceType (elt_list = t[3]['elt_list'])
5827 if 'ext_list' in t[3]:
5828 t[0].ext_list = t[3]['ext_list']
5829 if 'elt_list2' in t[3]:
5830 t[0].ext_list = t[3]['elt_list2']
5832 def p_ExtensionAndException_1 (t):
5833 'ExtensionAndException : ELLIPSIS'
5836 def p_OptionalExtensionMarker_1 (t):
5837 'OptionalExtensionMarker : COMMA ELLIPSIS'
5840 def p_OptionalExtensionMarker_2 (t):
5841 'OptionalExtensionMarker : '
5844 def p_ComponentTypeLists_1 (t):
5845 'ComponentTypeLists : ComponentTypeList'
5846 t[0] = {'elt_list' : t[1]}
5848 def p_ComponentTypeLists_2 (t):
5849 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
5850 t[0] = {'elt_list' : t[1], 'ext_list' : []}
5852 def p_ComponentTypeLists_3 (t):
5853 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
5854 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
5856 def p_ComponentTypeLists_4 (t):
5857 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
5858 t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]}
5860 def p_ComponentTypeLists_5 (t):
5861 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
5862 t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]}
5864 def p_ComponentTypeLists_6 (t):
5865 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
5866 t[0] = {'elt_list' : [], 'ext_list' : []}
5868 def p_ComponentTypeLists_7 (t):
5869 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
5870 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
5872 #def p_RootComponentTypeList (t):
5873 # 'RootComponentTypeList : ComponentTypeList'
5876 def p_ExtensionEndMarker (t):
5877 'ExtensionEndMarker : COMMA ELLIPSIS'
5880 #def p_extension_additions_1 (t):
5881 # 'extension_additions : extension_addition_list'
5884 #def p_extension_additions_2 (t):
5885 # 'extension_additions : '
5888 def p_ExtensionAdditionList_1 (t):
5889 'ExtensionAdditionList : COMMA extension_addition'
5892 def p_ExtensionAdditionList_2 (t):
5893 'ExtensionAdditionList : ExtensionAdditionList COMMA extension_addition'
5894 t[0] = t[1] + [t[3]]
5896 def p_extension_addition_1 (t):
5897 'extension_addition : ComponentType'
5900 def p_ComponentTypeList_1 (t):
5901 'ComponentTypeList : ComponentType'
5904 def p_ComponentTypeList_2 (t):
5905 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
5906 t[0] = t[1] + [t[3]]
5908 def p_ComponentType_1 (t):
5909 'ComponentType : NamedType'
5910 t[0] = Node ('elt_type', val = t[1], optional = 0)
5912 def p_ComponentType_2 (t):
5913 'ComponentType : NamedType OPTIONAL'
5914 t[0] = Node ('elt_type', val = t[1], optional = 1)
5916 def p_ComponentType_3 (t):
5917 'ComponentType : NamedType DEFAULT DefaultValue'
5918 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
5920 def p_ComponentType_4 (t):
5921 'ComponentType : COMPONENTS OF Type'
5922 t[0] = Node ('components_of', typ = t[3])
5924 def p_DefaultValue_1 (t):
5925 '''DefaultValue : ReferencedValue
5933 | ObjectClassFieldValue'''
5936 def p_DefaultValue_2 (t):
5937 'DefaultValue : lbraceignore rbraceignore'
5941 def p_SequenceValue_1 (t):
5942 'SequenceValue : LBRACE RBRACE'
5946 #def p_SequenceValue_2 (t):
5947 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
5950 #def p_ComponentValueList_1 (t):
5951 # 'ComponentValueList : NamedValue'
5954 #def p_ComponentValueList_2 (t):
5955 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
5956 # t[0] = t[1] + [t[3]]
5959 # 25 Notation for sequence-of types -------------------------------------------
5962 def p_SequenceOfType (t):
5963 '''SequenceOfType : SEQUENCE OF Type
5964 | SEQUENCE OF NamedType'''
5965 t[0] = SequenceOfType (val = t[3], size_constr = None)
5968 # 26 Notation for set types ---------------------------------------------------
5971 def p_SetType_1 (t):
5972 'SetType : SET LBRACE RBRACE'
5973 t[0] = SetType (elt_list = [])
5975 def p_SetType_2 (t):
5976 'SetType : SET LBRACE ComponentTypeLists RBRACE'
5977 if 'ext_list' in t[3]:
5978 t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
5980 t[0] = SetType (elt_list = t[3]['elt_list'])
5983 # 27 Notation for set-of types ------------------------------------------------
5986 def p_SetOfType (t):
5987 '''SetOfType : SET OF Type
5988 | SET OF NamedType'''
5989 t[0] = SetOfType (val = t[3])
5991 # 28 Notation for choice types ------------------------------------------------
5994 def p_ChoiceType (t):
5995 'ChoiceType : CHOICE LBRACE alternative_type_lists RBRACE'
5996 if 'ext_list' in t[3]:
5997 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
5999 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
6001 def p_alternative_type_lists_1 (t):
6002 'alternative_type_lists : alternative_type_list'
6003 t[0] = {'elt_list' : t[1]}
6005 def p_alternative_type_lists_2 (t):
6006 '''alternative_type_lists : alternative_type_list COMMA ExtensionAndException extension_addition_alternatives OptionalExtensionMarker'''
6007 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6009 def p_extension_addition_alternatives_1 (t):
6010 'extension_addition_alternatives : extension_addition_alternatives_list'
6013 def p_extension_addition_alternatives_2 (t):
6014 'extension_addition_alternatives : '
6017 def p_extension_addition_alternatives_list_1 (t):
6018 'extension_addition_alternatives_list : COMMA extension_addition_alternative'
6021 def p_extension_addition_alternatives_list_2 (t):
6022 'extension_addition_alternatives_list : extension_addition_alternatives_list COMMA extension_addition_alternative'
6023 t[0] = t[1] + [t[3]]
6025 def p_extension_addition_alternative_1 (t):
6026 'extension_addition_alternative : NamedType'
6029 def p_alternative_type_list_1 (t):
6030 'alternative_type_list : NamedType'
6033 def p_alternative_type_list_2 (t):
6034 'alternative_type_list : alternative_type_list COMMA NamedType'
6035 t[0] = t[1] + [t[3]]
6038 def p_ChoiceValue_1 (t):
6039 '''ChoiceValue : identifier COLON Value
6040 | identifier COLON NullValue '''
6042 if not isinstance(val, Value):
6043 val = Value(val=val)
6044 t[0] = ChoiceValue (choice = t[1], val = val)
6046 # 29 Notation for selection types
6049 def p_SelectionType (t): #
6050 'SelectionType : identifier LT Type'
6051 t[0] = SelectionType (typ = t[3], sel = t[1])
6053 # 30 Notation for tagged types ------------------------------------------------
6056 def p_TaggedType_1 (t):
6057 'TaggedType : Tag Type'
6058 t[1].mode = 'default'
6062 def p_TaggedType_2 (t):
6063 '''TaggedType : Tag IMPLICIT Type
6064 | Tag EXPLICIT Type'''
6070 'Tag : LBRACK Class ClassNumber RBRACK'
6071 t[0] = Tag(cls = t[2], num = t[3])
6073 def p_ClassNumber_1 (t):
6074 'ClassNumber : number'
6077 def p_ClassNumber_2 (t):
6078 'ClassNumber : DefinedValue'
6082 '''Class : UNIVERSAL
6092 # 31 Notation for the object identifier type ----------------------------------
6095 def p_ObjectIdentifierType (t):
6096 'ObjectIdentifierType : OBJECT IDENTIFIER'
6097 t[0] = ObjectIdentifierType()
6100 def p_ObjectIdentifierValue (t):
6101 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6102 t[0] = ObjectIdentifierValue (comp_list=t[2])
6104 def p_oid_comp_list_1 (t):
6105 'oid_comp_list : oid_comp_list ObjIdComponents'
6106 t[0] = t[1] + [t[2]]
6108 def p_oid_comp_list_2 (t):
6109 'oid_comp_list : ObjIdComponents'
6112 def p_ObjIdComponents (t):
6113 '''ObjIdComponents : NameForm
6115 | NameAndNumberForm'''
6119 '''NameForm : LCASE_IDENT
6120 | LCASE_IDENT_ASSIGNED'''
6123 def p_NumberForm (t):
6124 '''NumberForm : NUMBER'''
6128 def p_NameAndNumberForm (t):
6129 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6130 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6131 t[0] = Node('name_and_number', ident = t[1], number = t[3])
6133 # 32 Notation for the relative object identifier type -------------------------
6136 def p_RelativeOIDType (t):
6137 'RelativeOIDType : RELATIVE_OID'
6138 t[0] = RelativeOIDType()
6140 # 33 Notation for the embedded-pdv type ---------------------------------------
6143 def p_EmbeddedPDVType (t):
6144 'EmbeddedPDVType : EMBEDDED PDV'
6145 t[0] = EmbeddedPDVType()
6147 # 34 Notation for the external type -------------------------------------------
6150 def p_ExternalType (t):
6151 'ExternalType : EXTERNAL'
6152 t[0] = ExternalType()
6154 # 36 Notation for character string types --------------------------------------
6157 def p_CharacterStringType (t):
6158 '''CharacterStringType : RestrictedCharacterStringType
6159 | UnrestrictedCharacterStringType'''
6163 # 37 Definition of restricted character string types --------------------------
6165 def p_RestrictedCharacterStringType_1 (t):
6166 'RestrictedCharacterStringType : BMPString'
6167 t[0] = BMPStringType ()
6168 def p_RestrictedCharacterStringType_2 (t):
6169 'RestrictedCharacterStringType : GeneralString'
6170 t[0] = GeneralStringType ()
6171 def p_RestrictedCharacterStringType_3 (t):
6172 'RestrictedCharacterStringType : GraphicString'
6173 t[0] = GraphicStringType ()
6174 def p_RestrictedCharacterStringType_4 (t):
6175 'RestrictedCharacterStringType : IA5String'
6176 t[0] = IA5StringType ()
6177 def p_RestrictedCharacterStringType_5 (t):
6178 'RestrictedCharacterStringType : ISO646String'
6179 t[0] = ISO646StringType ()
6180 def p_RestrictedCharacterStringType_6 (t):
6181 'RestrictedCharacterStringType : NumericString'
6182 t[0] = NumericStringType ()
6183 def p_RestrictedCharacterStringType_7 (t):
6184 'RestrictedCharacterStringType : PrintableString'
6185 t[0] = PrintableStringType ()
6186 def p_RestrictedCharacterStringType_8 (t):
6187 'RestrictedCharacterStringType : TeletexString'
6188 t[0] = TeletexStringType ()
6189 def p_RestrictedCharacterStringType_9 (t):
6190 'RestrictedCharacterStringType : T61String'
6191 t[0] = T61StringType ()
6192 def p_RestrictedCharacterStringType_10 (t):
6193 'RestrictedCharacterStringType : UniversalString'
6194 t[0] = UniversalStringType ()
6195 def p_RestrictedCharacterStringType_11 (t):
6196 'RestrictedCharacterStringType : UTF8String'
6197 t[0] = UTF8StringType ()
6198 def p_RestrictedCharacterStringType_12 (t):
6199 'RestrictedCharacterStringType : VideotexString'
6200 t[0] = VideotexStringType ()
6201 def p_RestrictedCharacterStringType_13 (t):
6202 'RestrictedCharacterStringType : VisibleString'
6203 t[0] = VisibleStringType ()
6206 # 40 Definition of unrestricted character string types ------------------------
6209 def p_UnrestrictedCharacterStringType (t):
6210 'UnrestrictedCharacterStringType : CHARACTER STRING'
6211 t[0] = UnrestrictedCharacterStringType ()
6214 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6216 # 42 Generalized time ---------------------------------------------------------
6218 def p_UsefulType_1 (t):
6219 'UsefulType : GeneralizedTime'
6220 t[0] = GeneralizedTime()
6222 # 43 Universal time -----------------------------------------------------------
6224 def p_UsefulType_2 (t):
6225 'UsefulType : UTCTime'
6228 # 44 The object descriptor type -----------------------------------------------
6230 def p_UsefulType_3 (t):
6231 'UsefulType : ObjectDescriptor'
6232 t[0] = ObjectDescriptor()
6235 # 45 Constrained types --------------------------------------------------------
6238 def p_ConstrainedType_1 (t):
6239 'ConstrainedType : Type Constraint'
6241 t[0].AddConstraint(t[2])
6243 def p_ConstrainedType_2 (t):
6244 'ConstrainedType : TypeWithConstraint'
6248 def p_TypeWithConstraint_1 (t):
6249 '''TypeWithConstraint : SET Constraint OF Type
6250 | SET SizeConstraint OF Type'''
6251 t[0] = SetOfType (val = t[4], constr = t[2])
6253 def p_TypeWithConstraint_2 (t):
6254 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6255 | SEQUENCE SizeConstraint OF Type'''
6256 t[0] = SequenceOfType (val = t[4], constr = t[2])
6258 def p_TypeWithConstraint_3 (t):
6259 '''TypeWithConstraint : SET Constraint OF NamedType
6260 | SET SizeConstraint OF NamedType'''
6261 t[0] = SetOfType (val = t[4], constr = t[2])
6263 def p_TypeWithConstraint_4 (t):
6264 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6265 | SEQUENCE SizeConstraint OF NamedType'''
6266 t[0] = SequenceOfType (val = t[4], constr = t[2])
6270 def p_Constraint (t):
6271 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6274 def p_ConstraintSpec (t):
6275 '''ConstraintSpec : ElementSetSpecs
6276 | GeneralConstraint'''
6279 # 46 Element set specification ------------------------------------------------
6282 def p_ElementSetSpecs_1 (t):
6283 'ElementSetSpecs : RootElementSetSpec'
6286 def p_ElementSetSpecs_2 (t):
6287 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6291 def p_ElementSetSpecs_3 (t):
6292 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6296 def p_RootElementSetSpec (t):
6297 'RootElementSetSpec : ElementSetSpec'
6300 def p_AdditionalElementSetSpec (t):
6301 'AdditionalElementSetSpec : ElementSetSpec'
6304 def p_ElementSetSpec (t):
6305 'ElementSetSpec : Unions'
6309 'Unions : Intersections'
6313 'Unions : UElems UnionMark Intersections'
6314 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
6320 def p_Intersections_1 (t):
6321 'Intersections : IntersectionElements'
6324 def p_Intersections_2 (t):
6325 'Intersections : IElems IntersectionMark IntersectionElements'
6326 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
6329 'IElems : Intersections'
6332 def p_IntersectionElements (t):
6333 'IntersectionElements : Elements'
6336 def p_UnionMark (t):
6340 def p_IntersectionMark (t):
6341 '''IntersectionMark : CIRCUMFLEX
6345 def p_Elements_1 (t):
6346 'Elements : SubtypeElements'
6349 def p_Elements_2 (t):
6350 'Elements : LPAREN ElementSetSpec RPAREN'
6353 # 47 Subtype elements ---------------------------------------------------------
6356 def p_SubtypeElements (t):
6357 '''SubtypeElements : SingleValue
6363 | InnerTypeConstraints
6364 | PatternConstraint'''
6369 def p_SingleValue (t):
6370 'SingleValue : Value'
6371 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
6373 # 47.3 Contained subtype
6375 def p_ContainedSubtype (t):
6376 'ContainedSubtype : Includes Type'
6377 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
6380 '''Includes : INCLUDES
6385 def p_ValueRange (t):
6386 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6387 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
6390 def p_LowerEndpoint_1 (t):
6391 'LowerEndpoint : LowerEndValue'
6394 def p_LowerEndpoint_2 (t):
6395 'LowerEndpoint : LowerEndValue LT'
6396 t[0] = t[1] # but not inclusive range
6398 def p_UpperEndpoint_1 (t):
6399 'UpperEndpoint : UpperEndValue'
6402 def p_UpperEndpoint_2 (t):
6403 'UpperEndpoint : LT UpperEndValue'
6404 t[0] = t[1] # but not inclusive range
6407 def p_LowerEndValue (t):
6408 '''LowerEndValue : Value
6412 def p_UpperEndValue (t):
6413 '''UpperEndValue : Value
6417 # 47.5 Size constraint
6419 def p_SizeConstraint (t):
6420 'SizeConstraint : SIZE Constraint'
6421 t[0] = Constraint (type = 'Size', subtype = t[2])
6423 # 47.6 Type constraint
6425 def p_TypeConstraint (t):
6426 'TypeConstraint : Type'
6427 t[0] = Constraint (type = 'Type', subtype = t[1])
6429 # 47.7 Permitted alphabet
6431 def p_PermittedAlphabet (t):
6432 'PermittedAlphabet : FROM Constraint'
6433 t[0] = Constraint (type = 'From', subtype = t[2])
6435 # 47.8 Inner subtyping
6437 def p_InnerTypeConstraints (t):
6438 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6439 | WITH COMPONENTS MultipleTypeConstraints'''
6440 pass # ignore PER invisible constraint
6443 def p_SingleTypeConstraint (t):
6444 'SingleTypeConstraint : Constraint'
6448 def p_MultipleTypeConstraints (t):
6449 '''MultipleTypeConstraints : FullSpecification
6450 | PartialSpecification'''
6453 def p_FullSpecification (t):
6454 'FullSpecification : LBRACE TypeConstraints RBRACE'
6457 def p_PartialSpecification (t):
6458 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6461 def p_TypeConstraints_1 (t):
6462 'TypeConstraints : named_constraint'
6465 def p_TypeConstraints_2 (t):
6466 'TypeConstraints : TypeConstraints COMMA named_constraint'
6467 t[0] = t[1] + [t[3]]
6469 def p_named_constraint_1 (t):
6470 'named_constraint : identifier constraint'
6471 return Node ('named_constraint', ident = t[1], constr = t[2])
6473 def p_named_constraint_2 (t):
6474 'named_constraint : constraint'
6475 return Node ('named_constraint', constr = t[1])
6477 def p_constraint (t):
6478 'constraint : value_constraint presence_constraint'
6479 t[0] = Node ('constraint', value = t[1], presence = t[2])
6481 def p_value_constraint_1 (t):
6482 'value_constraint : Constraint'
6485 def p_value_constraint_2 (t):
6486 'value_constraint : '
6489 def p_presence_constraint_1 (t):
6490 '''presence_constraint : PRESENT
6495 def p_presence_constraint_2 (t):
6496 '''presence_constraint : '''
6499 # 47.9 Pattern constraint
6501 def p_PatternConstraint (t):
6502 'PatternConstraint : PATTERN Value'
6503 t[0] = Constraint (type = 'Pattern', subtype = t[2])
6505 # 49 The exception identifier
6508 def p_ExceptionSpec_1 (t):
6509 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
6512 def p_ExceptionSpec_2 (t):
6516 def p_ExceptionIdentification (t):
6517 '''ExceptionIdentification : SignedNumber
6519 | Type COLON Value '''
6522 # /*-----------------------------------------------------------------------*/
6523 # /* Value Notation Productions */
6524 # /*-----------------------------------------------------------------------*/
6528 def p_binary_string (t):
6529 'binary_string : BSTRING'
6530 t[0] = BStringValue(val = t[1])
6532 def p_hex_string (t):
6533 'hex_string : HSTRING'
6534 t[0] = HStringValue(val = t[1])
6536 def p_char_string (t):
6537 'char_string : QSTRING'
6545 #--- ITU-T Recommendation X.208 -----------------------------------------------
6547 # 27 Notation for the any type ------------------------------------------------
6552 | ANY DEFINED BY identifier'''
6555 #--- ITU-T Recommendation X.681 -----------------------------------------------
6557 # 7 ASN.1 lexical items -------------------------------------------------------
6559 # 7.1 Information object class references
6561 def p_objectclassreference (t):
6562 'objectclassreference : CLASS_IDENT'
6563 t[0] = Class_Ref(val=t[1])
6565 # 7.2 Information object references
6567 def p_objectreference (t):
6568 'objectreference : LCASE_IDENT'
6571 # 7.3 Information object set references
6573 #def p_objectsetreference (t):
6574 # 'objectsetreference : UCASE_IDENT'
6577 # 7.4 Type field references
6578 # ucasefieldreference
6579 # 7.5 Value field references
6580 # lcasefieldreference
6581 # 7.6 Value set field references
6582 # ucasefieldreference
6583 # 7.7 Object field references
6584 # lcasefieldreference
6585 # 7.8 Object set field references
6586 # ucasefieldreference
6588 def p_ucasefieldreference (t):
6589 'ucasefieldreference : AMPERSAND UCASE_IDENT'
6592 def p_lcasefieldreference (t):
6593 'lcasefieldreference : AMPERSAND LCASE_IDENT'
6596 # 8 Referencing definitions
6599 def p_DefinedObjectClass (t):
6600 '''DefinedObjectClass : objectclassreference
6601 | UsefulObjectClassReference'''
6604 obj_class = t[0].val
6606 def p_DefinedObject (t):
6607 '''DefinedObject : objectreference'''
6611 def p_UsefulObjectClassReference (t):
6612 '''UsefulObjectClassReference : TYPE_IDENTIFIER
6613 | ABSTRACT_SYNTAX'''
6614 t[0] = Class_Ref(val=t[1])
6616 # 9 Information object class definition and assignment
6619 def p_ObjectClassAssignment (t):
6620 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
6621 | UCASE_IDENT ASSIGNMENT ObjectClass'''
6624 if isinstance(t[0], ObjectClassDefn):
6628 def p_ObjectClass (t):
6629 '''ObjectClass : DefinedObjectClass
6631 | ParameterizedObjectClass '''
6635 def p_ObjectClassDefn (t):
6636 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
6637 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
6638 t[0] = ObjectClassDefn(fields = t[3])
6640 def p_FieldSpecs_1 (t):
6641 'FieldSpecs : FieldSpec'
6644 def p_FieldSpecs_2 (t):
6645 'FieldSpecs : FieldSpecs COMMA FieldSpec'
6646 t[0] = t[1] + [t[3]]
6648 def p_WithSyntaxSpec (t):
6649 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
6653 def p_FieldSpec (t):
6654 '''FieldSpec : TypeFieldSpec
6655 | FixedTypeValueFieldSpec
6656 | VariableTypeValueFieldSpec
6657 | FixedTypeValueSetFieldSpec
6659 | ObjectSetFieldSpec '''
6663 def p_TypeFieldSpec (t):
6664 '''TypeFieldSpec : ucasefieldreference
6665 | ucasefieldreference TypeOptionalitySpec '''
6666 t[0] = TypeFieldSpec()
6669 def p_TypeOptionalitySpec_1 (t):
6670 'TypeOptionalitySpec ::= OPTIONAL'
6673 def p_TypeOptionalitySpec_2 (t):
6674 'TypeOptionalitySpec ::= DEFAULT Type'
6678 def p_FixedTypeValueFieldSpec (t):
6679 '''FixedTypeValueFieldSpec : lcasefieldreference Type
6680 | lcasefieldreference Type UNIQUE
6681 | lcasefieldreference Type ValueOptionalitySpec
6682 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
6683 t[0] = FixedTypeValueFieldSpec(typ = t[2])
6686 def p_ValueOptionalitySpec_1 (t):
6687 'ValueOptionalitySpec ::= OPTIONAL'
6690 def p_ValueOptionalitySpec_2 (t):
6691 'ValueOptionalitySpec ::= DEFAULT Value'
6696 def p_VariableTypeValueFieldSpec (t):
6697 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
6698 | lcasefieldreference FieldName ValueOptionalitySpec '''
6699 t[0] = VariableTypeValueFieldSpec()
6703 def p_FixedTypeValueSetFieldSpec (t):
6704 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
6705 | ucasefieldreference Type ValueSetOptionalitySpec '''
6706 t[0] = FixedTypeValueSetFieldSpec()
6709 def p_ValueSetOptionalitySpec_1 (t):
6710 'ValueSetOptionalitySpec ::= OPTIONAL'
6713 def p_ValueSetOptionalitySpec_2 (t):
6714 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
6718 def p_ObjectFieldSpec (t):
6719 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
6720 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
6721 t[0] = ObjectFieldSpec(cls=t[2])
6726 def p_ObjectOptionalitySpec_1 (t):
6727 'ObjectOptionalitySpec ::= OPTIONAL'
6730 def p_ObjectOptionalitySpec_2 (t):
6731 'ObjectOptionalitySpec ::= DEFAULT Object'
6735 def p_ObjectSetFieldSpec (t):
6736 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
6737 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
6738 t[0] = ObjectSetFieldSpec(cls=t[2])
6741 def p_ObjectSetOptionalitySpec_1 (t):
6742 'ObjectSetOptionalitySpec ::= OPTIONAL'
6745 def p_ObjectSetOptionalitySpec_2 (t):
6746 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
6750 def p_PrimitiveFieldName (t):
6751 '''PrimitiveFieldName : ucasefieldreference
6752 | lcasefieldreference '''
6756 def p_FieldName_1 (t):
6757 'FieldName : PrimitiveFieldName'
6760 def p_FieldName_2 (t):
6761 'FieldName : FieldName DOT PrimitiveFieldName'
6762 t[0] = t[1] + '.' + t[3]
6764 # 11 Information object definition and assignment
6767 def p_ObjectAssignment (t):
6768 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
6769 t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4])
6775 '''Object : DefinedObject
6777 | ParameterizedObject'''
6781 def p_ObjectDefn (t):
6782 'ObjectDefn : lbraceobject bodyobject rbraceobject'
6785 # {...} block of object definition
6786 def p_lbraceobject(t):
6787 'lbraceobject : braceobjectbegin LBRACE'
6790 def p_braceobjectbegin(t):
6791 'braceobjectbegin : '
6794 if set_class_syntax(obj_class):
6798 state = 'braceignore'
6799 lexer.push_state(state)
6801 def p_rbraceobject(t):
6802 'rbraceobject : braceobjectend RBRACE'
6805 def p_braceobjectend(t):
6809 set_class_syntax(None)
6811 def p_bodyobject_1 (t):
6815 def p_bodyobject_2 (t):
6816 'bodyobject : cls_syntax_list'
6819 def p_cls_syntax_list_1 (t):
6820 'cls_syntax_list : cls_syntax_list cls_syntax'
6824 def p_cls_syntax_list_2 (t):
6825 'cls_syntax_list : cls_syntax'
6829 def p_cls_syntax_1 (t):
6830 'cls_syntax : Type IDENTIFIED BY Value'
6831 t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
6833 def p_cls_syntax_2 (t):
6834 'cls_syntax : HAS PROPERTY Value'
6835 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
6838 def p_cls_syntax_3 (t):
6839 '''cls_syntax : ERRORS ObjectSet
6841 | RETURN RESULT BooleanValue
6842 | SYNCHRONOUS BooleanValue
6843 | INVOKE PRIORITY Value
6844 | RESULT_PRIORITY Value
6846 | ALWAYS RESPONDS BooleanValue
6847 | IDEMPOTENT BooleanValue '''
6848 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
6850 def p_cls_syntax_4 (t):
6851 '''cls_syntax : ARGUMENT Type
6855 t[0] = { get_class_fieled(t[1]) : t[2] }
6857 def p_cls_syntax_5 (t):
6858 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
6859 | RESULT Type OPTIONAL BooleanValue
6860 | PARAMETER Type OPTIONAL BooleanValue '''
6861 t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
6863 # 12 Information object set definition and assignment
6866 def p_ObjectSetAssignment (t):
6867 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
6868 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
6871 def p_ObjectSet (t):
6872 'ObjectSet : lbraceignore rbraceignore'
6875 # 14 Notation for the object class field type ---------------------------------
6878 def p_ObjectClassFieldType (t):
6879 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
6880 t[0] = get_type_from_class(t[1], t[3])
6883 def p_ObjectClassFieldValue (t):
6884 '''ObjectClassFieldValue : OpenTypeFieldVal'''
6887 def p_OpenTypeFieldVal (t):
6888 '''OpenTypeFieldVal : Type COLON Value
6889 | NullType COLON NullValue'''
6893 # 15 Information from objects -------------------------------------------------
6897 def p_ValueFromObject (t):
6898 'ValueFromObject : LCASE_IDENT DOT FieldName'
6899 t[0] = t[1] + '.' + t[3]
6902 # Annex C - The instance-of type ----------------------------------------------
6905 def p_InstanceOfType (t):
6906 'InstanceOfType : INSTANCE OF DefinedObjectClass'
6907 t[0] = InstanceOfType()
6912 useful_object_class_types = {
6914 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
6915 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
6917 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
6918 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
6919 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
6922 object_class_types = { }
6924 object_class_typerefs = { }
6926 object_class_classrefs = { }
6929 class _VariableTypeValueFieldSpec (AnyType):
6932 class _FixedTypeValueSetFieldSpec (AnyType):
6935 class_types_creator = {
6936 'BooleanType' : lambda : BooleanType(),
6937 'IntegerType' : lambda : IntegerType(),
6938 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
6939 'OpenType' : lambda : OpenType(),
6941 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
6942 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
6948 'TYPE-IDENTIFIER' : {
6950 'IDENTIFIED' : 'IDENTIFIED',
6952 'IDENTIFIED BY' : '&id',
6954 'ABSTRACT-SYNTAX' : {
6956 'IDENTIFIED' : 'IDENTIFIED',
6958 'IDENTIFIED BY' : '&id',
6960 'PROPERTY' : 'PROPERTY',
6961 'HAS PROPERTY' : '&property',
6965 class_syntaxes_enabled = {
6966 'TYPE-IDENTIFIER' : True,
6967 'ABSTRACT-SYNTAX' : True,
6971 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
6972 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
6975 class_current_syntax = None
6977 def get_syntax_tokens(syntaxes):
6979 for s in (syntaxes):
6980 for k in (list(syntaxes[s].keys())):
6983 tokens[k] = tokens[k].replace('-', '_')
6984 return list(tokens.values())
6986 tokens = tokens + get_syntax_tokens(x681_syntaxes)
6988 def set_class_syntax(syntax):
6989 global class_syntaxes_enabled
6990 global class_current_syntax
6991 #print "set_class_syntax", syntax, class_current_syntax
6992 if class_syntaxes_enabled.get(syntax, False):
6993 class_current_syntax = syntax
6996 class_current_syntax = None
6999 def is_class_syntax(name):
7000 global class_syntaxes
7001 global class_current_syntax
7002 #print "is_class_syntax", name, class_current_syntax
7003 if not class_current_syntax:
7005 return name in class_syntaxes[class_current_syntax]
7007 def get_class_fieled(name):
7008 if not class_current_syntax:
7010 return class_syntaxes[class_current_syntax][name]
7012 def is_class_ident(name):
7013 return name in class_names
7015 def add_class_ident(name):
7016 #print "add_class_ident", name
7017 class_names[name] = name
7019 def get_type_from_class(cls, fld):
7020 flds = fld.split('.')
7021 if (isinstance(cls, Class_Ref)):
7022 key = cls.val + '.' + flds[0]
7024 key = cls + '.' + flds[0]
7026 if key in object_class_classrefs:
7027 return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:]))
7029 if key in object_class_typerefs:
7030 return Type_Ref(val=object_class_typerefs[key])
7032 creator = lambda : AnyType()
7033 creator = useful_object_class_types.get(key, creator)
7034 creator = object_class_types.get(key, creator)
7037 def set_type_to_class(cls, fld, pars):
7038 #print "set_type_to_class", cls, fld, pars
7039 key = cls + '.' + fld
7040 typename = 'OpenType'
7044 pars.append(typename)
7047 if (isinstance(pars[1], Class_Ref)):
7048 pars[1] = pars[1].val
7052 if key in object_class_types:
7053 msg = object_class_types[key]().type
7054 if key in object_class_typerefs:
7055 msg = "TypeReference " + object_class_typerefs[key]
7056 if key in object_class_classrefs:
7057 msg = "ClassReference " + object_class_classrefs[key]
7059 if msg == ' '.join(pars):
7063 msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars))
7064 msg1 = "Already defined as '%s'" % (msg)
7065 raise CompError(msg0 + msg1)
7067 if (typename == 'ClassReference'):
7068 if not typeref: return False
7069 object_class_classrefs[key] = typeref
7072 if (typename == 'TypeReference'):
7073 if not typeref: return False
7074 object_class_typerefs[key] = typeref
7077 creator = class_types_creator.get(typename)
7079 object_class_types[key] = creator
7084 def import_class_from_module(mod, cls):
7085 add_class_ident(cls)
7086 mcls = "$%s$%s" % (mod, cls)
7087 for k in list(object_class_classrefs.keys()):
7088 kk = k.split('.', 1)
7090 object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k]
7091 for k in list(object_class_typerefs.keys()):
7092 kk = k.split('.', 1)
7094 object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k]
7095 for k in list(object_class_types.keys()):
7096 kk = k.split('.', 1)
7098 object_class_types[cls + '.' + kk[0]] = object_class_types[k]
7100 #--- ITU-T Recommendation X.682 -----------------------------------------------
7102 # 8 General constraint specification ------------------------------------------
7105 def p_GeneralConstraint (t):
7106 '''GeneralConstraint : UserDefinedConstraint
7108 | ContentsConstraint'''
7111 # 9 User-defined constraints --------------------------------------------------
7114 def p_UserDefinedConstraint (t):
7115 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7116 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
7118 def p_UserDefinedConstraintParameterList_1 (t):
7119 'UserDefinedConstraintParameterList : '
7122 def p_UserDefinedConstraintParameterList_2 (t):
7123 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7126 def p_UserDefinedConstraintParameterList_3 (t):
7127 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7128 t[0] = t[1] + [t[3]]
7131 def p_UserDefinedConstraintParameter (t):
7132 'UserDefinedConstraintParameter : Type'
7135 # 10 Table constraints, including component relation constraints --------------
7138 def p_TableConstraint (t):
7139 '''TableConstraint : SimpleTableConstraint
7140 | ComponentRelationConstraint'''
7141 t[0] = Constraint(type = 'Table', subtype = t[1])
7143 def p_SimpleTableConstraint (t):
7144 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7148 def p_ComponentRelationConstraint (t):
7149 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7150 t[0] = t[2] + str(t[5])
7152 def p_AtNotations_1 (t):
7153 'AtNotations : AtNotation'
7156 def p_AtNotations_2 (t):
7157 'AtNotations : AtNotations COMMA AtNotation'
7158 t[0] = t[1] + [t[3]]
7160 def p_AtNotation_1 (t):
7161 'AtNotation : AT ComponentIdList'
7164 def p_AtNotation_2 (t):
7165 'AtNotation : AT DOT Level ComponentIdList'
7166 t[0] = '@.' + t[3] + t[4]
7176 def p_ComponentIdList_1 (t):
7177 'ComponentIdList : LCASE_IDENT'
7180 def p_ComponentIdList_2 (t):
7181 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7182 t[0] = t[1] + '.' + t[3]
7184 # 11 Contents constraints -----------------------------------------------------
7187 def p_ContentsConstraint (t):
7188 'ContentsConstraint : CONTAINING type_ref'
7189 t[0] = Constraint(type = 'Contents', subtype = t[2])
7192 #--- ITU-T Recommendation X.683 -----------------------------------------------
7194 # 8 Parameterized assignments -------------------------------------------------
7197 def p_ParameterizedAssignment (t):
7198 '''ParameterizedAssignment : ParameterizedTypeAssignment
7199 | ParameterizedObjectClassAssignment
7200 | ParameterizedObjectAssignment
7201 | ParameterizedObjectSetAssignment'''
7205 def p_ParameterizedTypeAssignment (t):
7206 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7208 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
7210 def p_ParameterizedObjectClassAssignment (t):
7211 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7212 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7215 if isinstance(t[0], ObjectClassDefn):
7218 def p_ParameterizedObjectAssignment (t):
7219 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7220 t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
7224 def p_ParameterizedObjectSetAssignment (t):
7225 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7226 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
7229 def p_ParameterList (t):
7230 'ParameterList : lbraceignore rbraceignore'
7232 #def p_ParameterList (t):
7233 # 'ParameterList : LBRACE Parameters RBRACE'
7236 #def p_Parameters_1 (t):
7237 # 'Parameters : Parameter'
7240 #def p_Parameters_2 (t):
7241 # 'Parameters : Parameters COMMA Parameter'
7242 # t[0] = t[1] + [t[3]]
7244 #def p_Parameter_1 (t):
7245 # 'Parameter : Type COLON Reference'
7246 # t[0] = [t[1], t[3]]
7248 #def p_Parameter_2 (t):
7249 # 'Parameter : Reference'
7253 # 9 Referencing parameterized definitions -------------------------------------
7256 def p_ParameterizedReference (t):
7257 'ParameterizedReference : Reference LBRACE RBRACE'
7262 def p_ParameterizedType (t):
7263 'ParameterizedType : type_ref ActualParameterList'
7268 def p_ParameterizedObjectClass (t):
7269 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7273 def p_ParameterizedObject (t):
7274 'ParameterizedObject : DefinedObject ActualParameterList'
7279 def p_ActualParameterList (t):
7280 'ActualParameterList : lbraceignore rbraceignore'
7282 #def p_ActualParameterList (t):
7283 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7286 #def p_ActualParameters_1 (t):
7287 # 'ActualParameters : ActualParameter'
7290 #def p_ActualParameters_2 (t):
7291 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7292 # t[0] = t[1] + [t[3]]
7294 #def p_ActualParameter (t):
7295 # '''ActualParameter : Type
7300 #--- ITU-T Recommendation X.880 -----------------------------------------------
7304 '&ArgumentType' : [],
7305 '&argumentTypeOptional' : [ 'BooleanType' ],
7306 '&returnResult' : [ 'BooleanType' ],
7308 '&resultTypeOptional' : [ 'BooleanType' ],
7309 '&Errors' : [ 'ClassReference', 'ERROR' ],
7310 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7311 '&synchronous' : [ 'BooleanType' ],
7312 '&idempotent' : [ 'BooleanType' ],
7313 '&alwaysReturns' : [ 'BooleanType' ],
7314 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7315 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7316 '&operationCode' : [ 'TypeReference', 'Code' ],
7319 '&ParameterType' : [],
7320 '¶meterTypeOptional' : [ 'BooleanType' ],
7321 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7322 '&errorCode' : [ 'TypeReference', 'Code' ],
7324 'OPERATION-PACKAGE' : {
7325 '&Both' : [ 'ClassReference', 'OPERATION' ],
7326 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7327 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7328 '&id' : [ 'ObjectIdentifierType' ],
7330 'CONNECTION-PACKAGE' : {
7331 '&bind' : [ 'ClassReference', 'OPERATION' ],
7332 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7333 '&responderCanUnbind' : [ 'BooleanType' ],
7334 '&unbindCanFail' : [ 'BooleanType' ],
7335 '&id' : [ 'ObjectIdentifierType' ],
7338 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7339 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7340 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7341 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7342 '&id' : [ 'ObjectIdentifierType' ],
7344 'ROS-OBJECT-CLASS' : {
7345 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7346 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7347 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7348 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7349 '&id' : [ 'ObjectIdentifierType' ],
7355 'ARGUMENT' : '&ArgumentType',
7356 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7357 'RESULT' : '&ResultType',
7358 'RESULT OPTIONAL' : '&resultTypeOptional',
7359 'RETURN' : 'RETURN',
7360 'RETURN RESULT' : '&returnResult',
7361 'ERRORS' : '&Errors',
7362 'LINKED' : '&Linked',
7363 'SYNCHRONOUS' : '&synchronous',
7364 'IDEMPOTENT' : '&idempotent',
7365 'ALWAYS' : 'ALWAYS',
7366 'RESPONDS' : 'RESPONDS',
7367 'ALWAYS RESPONDS' : '&alwaysReturns',
7368 'INVOKE' : 'INVOKE',
7369 'PRIORITY' : 'PRIORITY',
7370 'INVOKE PRIORITY' : '&InvokePriority',
7371 'RESULT-PRIORITY': '&ResultPriority',
7372 'CODE' : '&operationCode',
7375 'PARAMETER' : '&ParameterType',
7376 'PARAMETER OPTIONAL' : '¶meterTypeOptional',
7377 'PRIORITY' : '&ErrorPriority',
7378 'CODE' : '&errorCode',
7380 # 'OPERATION-PACKAGE' : {
7382 # 'CONNECTION-PACKAGE' : {
7386 # 'ROS-OBJECT-CLASS' : {
7390 def x880_module_begin():
7391 #print "x880_module_begin()"
7392 for name in list(x880_classes.keys()):
7393 add_class_ident(name)
7395 def x880_import(name):
7396 if name in x880_syntaxes:
7397 class_syntaxes_enabled[name] = True
7398 class_syntaxes[name] = x880_syntaxes[name]
7399 if name in x880_classes:
7400 add_class_ident(name)
7401 for f in (list(x880_classes[name].keys())):
7402 set_type_to_class(name, f, x880_classes[name][f])
7404 tokens = tokens + get_syntax_tokens(x880_syntaxes)
7407 #def p_lbrace_oid(t):
7408 # 'lbrace_oid : brace_oid_begin LBRACE'
7411 #def p_brace_oid_begin(t):
7412 # 'brace_oid_begin : '
7416 #def p_rbrace_oid(t):
7417 # 'rbrace_oid : brace_oid_end RBRACE'
7420 #def p_brace_oid_end(t):
7421 # 'brace_oid_end : '
7425 # {...} block to be ignored
7426 def p_lbraceignore(t):
7427 'lbraceignore : braceignorebegin LBRACE'
7430 def p_braceignorebegin(t):
7431 'braceignorebegin : '
7434 lexer.push_state('braceignore')
7436 def p_rbraceignore(t):
7437 'rbraceignore : braceignoreend RBRACE'
7440 def p_braceignoreend(t):
7447 raise ParseError(t, input_file)
7450 '''pyquote : PYQUOTE'''
7451 t[0] = PyQuote (val = t[1])
7457 token = lexer.token ()
7463 def do_module (ast, defined_dict):
7464 assert (ast.type == 'Module')
7465 ctx = Ctx (defined_dict)
7466 print ast.to_python (ctx)
7467 print ctx.output_assignments ()
7468 print ctx.output_pyquotes ()
7470 def eth_do_module (ast, ectx):
7471 assert (ast.type == 'Module')
7472 if ectx.dbg('s'): print ast.str_depth(0)
7475 def testyacc(s, fn, defined_dict):
7476 ast = yacc.parse(s, debug=0)
7477 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
7478 print """#!/usr/bin/env python
7479 # Auto-generated from %s at %s
7480 from PyZ3950 import asn1""" % (fn, time_str)
7482 eth_do_module (module, defined_dict)
7485 # Wireshark compiler
7488 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
7490 -b : BER (default is PER)
7491 -u : Unaligned (default is aligned)
7492 -p proto : Protocol name (implies -S). Default is module-name
7493 from input_file (renamed by #.MODULE if present)
7494 -o name : Output files name core (default is <proto>)
7495 -O dir : Output directory
7496 -c cnf_file : Conformance file
7497 -I path : Path for conformance file includes
7498 -e : Create conformance file for exported types
7499 -E : Just create conformance file for exported types
7500 -S : Single output for multiple modules
7501 -s template : Single file output (template is input file
7502 without .c/.h extension)
7503 -k : Keep intermediate files though single file output is used
7504 -L : Suppress #line directive from .cnf file
7505 -D dir : Directory for input_file(s) (default: '.')
7507 input_file(s) : Input ASN.1 file(s)
7509 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
7513 s - internal ASN.1 structure
7514 a - list of assignments
7516 c - conformance values
7517 m - list of compiled modules with dependency
7518 o - list of output files
7525 print "ASN.1 to Wireshark dissector compiler";
7527 opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kL");
7528 except getopt.GetoptError:
7529 eth_usage(); sys.exit(2)
7531 eth_usage(); sys.exit(2)
7536 ectx = EthCtx(conform, output)
7537 ectx.encoding = 'per'
7538 ectx.proto_opt = None
7540 ectx.tag_opt = False
7541 ectx.outnm_opt = None
7546 ectx.justexpcnf = False
7547 ectx.merge_modules = False
7548 ectx.group_by_prot = False
7549 ectx.conform.last_group = 0
7550 ectx.conform.suppress_line = False;
7551 ectx.output.outnm = None
7552 ectx.output.single_file = None
7554 if o in ("-h", "-?"):
7555 eth_usage(); sys.exit(2)
7559 ectx.conform.include_path.append(a)
7562 ectx.justexpcnf = True
7566 warnings.warn("Command line option -X is obsolete and can be removed")
7568 warnings.warn("Command line option -T is obsolete and can be removed")
7571 ectx.conform.read(conf_to_read)
7574 if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-X", "-T"):
7575 pass # already processed
7579 ectx.conform.set_opt(o, par, "commandline", 0)
7581 (ld, yd, pd) = (0, 0, 0);
7582 if ectx.dbg('l'): ld = 1
7583 if ectx.dbg('y'): yd = 1
7584 if ectx.dbg('p'): pd = 2
7585 lexer = lex.lex(debug=ld)
7586 yacc.yacc(method='LALR', debug=yd)
7587 g_conform = ectx.conform
7592 if (ectx.srcdir): fn = ectx.srcdir + '/' + fn
7594 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
7597 if (ectx.merge_modules): # common output for all module
7600 eth_do_module(module, ectx)
7602 ectx.eth_do_output()
7603 elif (ectx.groups()): # group by protocols/group
7606 if (ectx.group_by_prot): # group by protocols
7608 prot = module.get_proto(ectx)
7609 if prot not in pr2gr:
7610 pr2gr[prot] = len(groups)
7612 groups[pr2gr[prot]].append(module)
7613 else: # group by groups
7618 eth_do_module(module, ectx)
7620 ectx.eth_do_output()
7621 else: # output for each module
7624 eth_do_module(module, ectx)
7626 ectx.eth_do_output()
7632 ectx.conform.dbg_print()
7633 if not ectx.justexpcnf:
7634 ectx.conform.unused_report()
7637 ectx.output.dbg_print()
7638 ectx.output.make_single_file()
7644 if len (sys.argv) == 1:
7646 s = raw_input ('Query: ')
7649 testfn (s, 'console', {})
7652 for fn in sys.argv [1:]:
7654 testfn (f.read (), fn, defined_dict)
7659 #--- BODY ---------------------------------------------------------------------
7661 if __name__ == '__main__':
7662 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
7667 #------------------------------------------------------------------------------