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 self.field[ident]['attr']['NAME'] = '"%s"' % ident.split('/')[-2]
989 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
991 self.field[ident]['attr']['NAME'] = '"%s"' % name
992 self.field[ident]['attr']['ABBREV'] = asn2c(name)
993 if self.conform.check_item('FIELD_ATTR', ident):
994 self.field[ident]['modified'] = '#' + str(id(self))
995 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
997 self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0)
998 self.pdu_ord.append(ident)
1000 self.field_ord.append(ident)
1002 self.eth_dep_add(parent, type)
1004 #--- eth_clean --------------------------------------------------------------
1005 def eth_clean(self):
1006 self.proto = self.proto_opt;
1007 #--- ASN.1 tables ----------------
1009 self.assign_ord = []
1018 self.sel_req_ord = []
1019 self.comp_req_ord = []
1021 self.vassign_ord = []
1025 self.objectclass = {}
1026 self.objectclass_ord = []
1027 self.objectclass_imp = []
1029 self.oassign_ord = []
1030 self.oassign_cls = {}
1031 #--- Modules ------------
1033 self.exports_all = False
1037 #--- types -------------------
1039 self.eth_type_ord = []
1040 self.eth_export_ord = []
1041 self.eth_type_dupl = {}
1043 #--- value dependencies -------------------
1045 #--- values -------------------
1047 self.eth_value_ord = []
1048 #--- fields -------------------------
1050 self.eth_hf_ord = []
1051 self.eth_hfpdu_ord = []
1052 self.eth_hf_dupl = {}
1053 #--- type dependencies -------------------
1054 self.eth_type_ord1 = []
1055 self.eth_dep_cycle = []
1056 self.dep_cycle_eth_type = {}
1057 #--- value dependencies and export -------------------
1058 self.eth_value_ord1 = []
1059 self.eth_vexport_ord = []
1061 #--- eth_prepare ------------------------------------------------------------
1062 def eth_prepare(self):
1063 self.eproto = asn2c(self.proto)
1065 #--- dummy types/fields for PDU registration ---
1067 if (self.conform.check_item('PDU', nm)):
1068 self.eth_reg_type('_dummy/'+nm, NullType())
1069 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
1071 #--- required PDUs ----------------------------
1072 for t in self.type_ord:
1073 pdu = self.type[t]['val'].eth_need_pdu(self)
1074 if not pdu: continue
1077 pdu['hidden'] = False
1078 pdu['need_decl'] = True
1079 if f not in self.field:
1080 self.eth_reg_field(f, f, pdu=pdu)
1082 #--- values -> named values -------------------
1084 for v in self.value_ord:
1085 if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1086 if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1087 tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v)
1089 tnm = self.value[v]['type'].val
1090 if tnm in self.type \
1091 and not self.type[tnm]['import'] \
1092 and (self.type[tnm]['val'].type == 'IntegerType'):
1093 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
1094 self.value[v]['no_emit'] = True
1095 t_for_update[tnm] = True
1096 for t in list(t_for_update.keys()):
1097 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
1098 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
1100 #--- required components of ---------------------------
1101 #print "self.comp_req_ord = ", self.comp_req_ord
1102 for t in self.comp_req_ord:
1103 self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
1105 #--- required selection types ---------------------------
1106 #print "self.sel_req_ord = ", self.sel_req_ord
1107 for t in self.sel_req_ord:
1108 tt = self.sel_req[t]['typ']
1109 if tt not in self.type:
1110 self.dummy_import_type(t)
1111 elif self.type[tt]['import']:
1112 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
1114 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
1116 #--- types -------------------
1117 for t in self.type_imp:
1119 self.eth_type[nm] = { 'import' : self.type[t]['import'],
1120 'proto' : asn2c(self.type[t]['proto']),
1121 'attr' : {}, 'ref' : []}
1122 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1123 self.type[t]['ethname'] = nm
1124 for t in self.type_ord:
1125 nm = self.type[t]['tname']
1126 if ((nm.find('#') >= 0) or
1127 ((len(t.split('/'))>1) and
1128 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or
1129 self.conform.get_fn_presence('/'.join((t,'_item'))) or self.conform.check_item('FN_PARS', '/'.join((t,'_item')))) and
1130 not self.conform.check_item('TYPE_RENAME', t))):
1131 if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequnce of type at the 1st level
1132 nm = t.split('/')[0] + t.split('/')[1]
1133 elif t.split('/')[-1] == '_item': # Sequnce/Set of type at next levels
1134 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
1135 elif t.split('/')[-1] == '_untag': # Untagged type
1136 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
1138 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
1140 if nm in self.eth_type:
1141 if nm in self.eth_type_dupl:
1142 self.eth_type_dupl[nm].append(t)
1144 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
1145 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
1146 if nm in self.eth_type:
1147 self.eth_type[nm]['ref'].append(t)
1149 self.eth_type_ord.append(nm)
1150 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
1151 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
1152 'val' : self.type[t]['val'],
1153 'attr' : {}, 'ref' : [t]}
1154 self.type[t]['ethname'] = nm
1155 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
1156 self.eth_export_ord.append(nm)
1157 self.eth_type[nm]['export'] |= self.type[t]['export']
1158 self.eth_type[nm]['enum'] |= self.type[t]['enum']
1159 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
1160 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
1161 if self.type[t]['attr'].get('STRINGS') == '$$':
1162 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
1163 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1164 for t in self.eth_type_ord:
1165 bits = self.eth_type[t]['val'].eth_named_bits()
1167 for (val, id) in bits:
1168 self.named_bit.append({'name' : id, 'val' : val,
1169 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
1170 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1172 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
1173 if self.eth_type[t]['val'].eth_need_tree():
1174 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
1176 self.eth_type[t]['tree'] = None
1178 #--- register values from enums ------------
1179 for t in self.eth_type_ord:
1180 if (self.eth_type[t]['val'].eth_has_enum(t, self)):
1181 self.eth_type[t]['val'].reg_enum_vals(t, self)
1183 #--- value dependencies -------------------
1184 for v in self.value_ord:
1185 if isinstance (self.value[v]['value'], Value):
1186 dep = self.value[v]['value'].get_dep()
1188 dep = self.value[v]['value']
1189 if dep and dep in self.value:
1190 self.value_dep.setdefault(v, []).append(dep)
1192 #--- exports all necessary values
1193 for v in self.value_ord:
1194 if not self.value[v]['export']: continue
1195 deparr = self.value_dep.get(v, [])
1198 if not self.value[d]['import']:
1199 if not self.value[d]['export']:
1200 self.value[d]['export'] = EF_TYPE
1201 deparr.extend(self.value_dep.get(d, []))
1203 #--- values -------------------
1204 for v in self.value_imp:
1206 self.eth_value[nm] = { 'import' : self.value[v]['import'],
1207 'proto' : asn2c(self.value[v]['proto']),
1209 self.value[v]['ethname'] = nm
1210 for v in self.value_ord:
1211 if (self.value[v]['ethname']):
1213 if (self.value[v]['no_emit']):
1216 self.eth_value[nm] = { 'import' : None,
1217 'proto' : asn2c(self.value[v]['proto']),
1218 'export' : self.value[v]['export'], 'ref' : [v] }
1219 self.eth_value[nm]['value'] = self.value[v]['value']
1220 self.eth_value_ord.append(nm)
1221 self.value[v]['ethname'] = nm
1223 #--- fields -------------------------
1224 for f in (self.pdu_ord + self.field_ord):
1225 if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequnce/Set of type
1226 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
1228 nm = f.split('/')[-1]
1229 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
1231 if (self.field[f]['pdu']):
1233 if (not self.merge_modules or self.field[f]['pdu']['export']):
1234 nm = self.eproto + '_' + nm
1235 t = self.field[f]['type']
1237 ethtype = self.type[t]['ethname']
1238 else: # undefined type
1239 ethtype = self.dummy_import_type(t)
1240 ethtypemod = ethtype + self.field[f]['modified']
1241 if nm in self.eth_hf:
1242 if nm in self.eth_hf_dupl:
1243 if ethtypemod in self.eth_hf_dupl[nm]:
1244 nm = self.eth_hf_dupl[nm][ethtypemod]
1245 self.eth_hf[nm]['ref'].append(f)
1246 self.field[f]['ethname'] = nm
1249 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
1250 self.eth_hf_dupl[nm][ethtype] = nmx
1253 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
1254 self.eth_hf[nm]['ref'].append(f)
1255 self.field[f]['ethname'] = nm
1259 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
1262 if (self.field[f]['pdu']):
1263 self.eth_hfpdu_ord.append(nm)
1265 self.eth_hf_ord.append(nm)
1266 fullname = 'hf_%s_%s' % (self.eproto, nm)
1267 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
1268 attr.update(self.field[f]['attr'])
1269 if (self.NAPI() and 'NAME' in attr):
1270 attr['NAME'] += self.field[f]['idx']
1271 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
1272 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
1273 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
1274 'attr' : attr.copy(),
1276 self.field[f]['ethname'] = nm
1277 #--- type dependencies -------------------
1278 (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'])
1280 while i < len(self.eth_dep_cycle):
1281 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1282 self.dep_cycle_eth_type.setdefault(t, []).append(i)
1285 #--- value dependencies and export -------------------
1286 for v in self.eth_value_ord:
1287 if self.eth_value[v]['export']:
1288 self.eth_vexport_ord.append(v)
1290 self.eth_value_ord1.append(v)
1292 #--- export tags, values, ... ---
1293 for t in self.exports:
1294 if t not in self.type:
1296 if self.type[t]['import']:
1298 m = self.type[t]['module']
1300 if m not in self.all_tags:
1301 self.all_tags[m] = {}
1302 self.all_tags[m][t] = self.type[t]['val'].GetTTag(self)
1303 if m not in self.all_type_attr:
1304 self.all_type_attr[m] = {}
1305 self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy()
1306 for v in self.vexports:
1307 if v not in self.value:
1309 if self.value[v]['import']:
1311 m = self.value[v]['module']
1312 if m not in self.all_vals:
1313 self.all_vals[m] = {}
1314 vv = self.value[v]['value']
1315 if isinstance (vv, Value):
1316 vv = vv.to_str(self)
1317 self.all_vals[m][v] = vv
1319 #--- eth_vals_nm ------------------------------------------------------------
1320 def eth_vals_nm(self, tname):
1322 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
1323 out += "%s_" % (self.eproto)
1324 out += "%s_vals" % (tname)
1327 #--- eth_vals ---------------------------------------------------------------
1328 def eth_vals(self, tname, vals):
1330 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
1331 if (not self.eth_type[tname]['export'] & EF_VALS):
1333 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
1335 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
1336 for (val, id) in vals:
1338 vval = self.eth_enum_item(tname, id)
1341 out += ' { %3s, "%s" },\n' % (vval, id)
1342 out += " { 0, NULL }\n};\n"
1345 #--- eth_enum_prefix ------------------------------------------------------------
1346 def eth_enum_prefix(self, tname, type=False):
1348 if (self.eth_type[tname]['export'] & EF_ENUM):
1349 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
1351 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
1354 if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type):
1355 if (out): out += '_'
1357 if (self.eth_type[tname]['enum'] & EF_UCASE):
1359 if (out): out += '_'
1362 #--- eth_enum_nm ------------------------------------------------------------
1363 def eth_enum_nm(self, tname):
1364 out = self.eth_enum_prefix(tname, type=True)
1368 #--- eth_enum_item ---------------------------------------------------------------
1369 def eth_enum_item(self, tname, ident):
1370 out = self.eth_enum_prefix(tname)
1372 if (self.eth_type[tname]['enum'] & EF_UCASE):
1376 #--- eth_enum ---------------------------------------------------------------
1377 def eth_enum(self, tname, vals):
1379 if (self.eth_type[tname]['enum'] & EF_DEFINE):
1380 out += "/* enumerated values for %s */\n" % (tname)
1381 for (val, id) in vals:
1382 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
1384 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
1386 for (val, id) in vals:
1387 if (first_line == 1):
1391 out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val)
1392 out += "\n} %s;\n" % (self.eth_enum_nm(tname))
1395 #--- eth_bits ---------------------------------------------------------------
1396 def eth_bits(self, tname, bits):
1398 out += "static const "
1399 out += "asn_namedbit %(TABLE)s[] = {\n"
1400 for (val, id) in bits:
1401 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
1402 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
1405 #--- eth_type_fn_h ----------------------------------------------------------
1406 def eth_type_fn_h(self, tname):
1408 if (not self.eth_type[tname]['export'] & EF_TYPE):
1412 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)
1414 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)
1418 #--- eth_fn_call ------------------------------------------------------------
1419 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
1422 if (ret == 'return'):
1428 for i in range(len(par)):
1429 if (i>0): out += ind * ' '
1430 out += ', '.join(par[i])
1431 if (i<(len(par)-1)): out += ',\n'
1435 #--- eth_type_fn_hdr --------------------------------------------------------
1436 def eth_type_fn_hdr(self, tname):
1438 if (not self.eth_type[tname]['export'] & EF_TYPE):
1442 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)
1444 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)
1445 #if self.conform.get_fn_presence(tname):
1446 # out += self.conform.get_fn_text(tname, 'FN_HDR')
1448 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1449 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1452 #--- eth_type_fn_ftr --------------------------------------------------------
1453 def eth_type_fn_ftr(self, tname):
1455 #if self.conform.get_fn_presence(tname):
1456 # out += self.conform.get_fn_text(tname, 'FN_FTR')
1458 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1459 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1460 out += " return offset;\n"
1464 #--- eth_type_fn_body -------------------------------------------------------
1465 def eth_type_fn_body(self, tname, body, pars=None):
1467 #if self.conform.get_fn_body_presence(tname):
1468 # out = self.conform.get_fn_text(tname, 'FN_BODY')
1470 if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1471 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1479 #--- eth_out_pdu_decl ----------------------------------------------------------
1480 def eth_out_pdu_decl(self, f):
1481 t = self.eth_hf[f]['ethtype']
1482 is_new = self.eth_hf[f]['pdu']['new']
1484 if (not self.eth_hf[f]['pdu']['export']):
1490 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);\n'
1493 #--- eth_output_hf ----------------------------------------------------------
1494 def eth_output_hf (self):
1495 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1496 fx = self.output.file_open('hf')
1497 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1498 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1499 if (self.named_bit):
1500 fx.write('/* named bits */\n')
1501 for nb in self.named_bit:
1502 fx.write("static int %s = -1;\n" % (nb['ethname']))
1503 self.output.file_close(fx)
1505 #--- eth_output_hf_arr ------------------------------------------------------
1506 def eth_output_hf_arr (self):
1507 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1508 fx = self.output.file_open('hfarr')
1509 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1510 t = self.eth_hf[f]['ethtype']
1511 blurb = '"%s.%s"' % (self.eth_type[t]['proto'], t)
1512 attr = self.eth_hf[f]['attr'].copy()
1513 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1514 if 'BLURB' not in attr:
1515 attr['BLURB'] = blurb
1516 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1517 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1518 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1519 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1520 for nb in self.named_bit:
1522 fx.write(' { &%s,\n' % (nb['ethname']))
1523 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1524 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1525 fx.write(' "%s", HFILL }},\n' % (blurb))
1526 self.output.file_close(fx)
1528 #--- eth_output_ett ---------------------------------------------------------
1529 def eth_output_ett (self):
1530 fx = self.output.file_open('ett')
1532 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1533 for t in self.eth_type_ord:
1534 if self.eth_type[t]['tree']:
1535 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1537 self.output.file_close(fx, discard=fempty)
1539 #--- eth_output_ett_arr -----------------------------------------------------
1540 def eth_output_ett_arr(self):
1541 fx = self.output.file_open('ettarr')
1543 #fx.write(" &ett_%s,\n" % (self.eproto))
1544 for t in self.eth_type_ord:
1545 if self.eth_type[t]['tree']:
1546 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1548 self.output.file_close(fx, discard=fempty)
1550 #--- eth_output_export ------------------------------------------------------
1551 def eth_output_export(self):
1552 if (not len(self.eth_export_ord)): return
1553 fx = self.output.file_open('exp', ext='h')
1554 for t in self.eth_export_ord: # vals
1555 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1556 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1557 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1558 if not self.eth_type[t]['export'] & EF_TABLE:
1559 if self.eth_type[t]['export'] & EF_WS_VAR:
1560 fx.write("WS_VAR_IMPORT ")
1563 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1565 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1566 for t in self.eth_export_ord: # functions
1567 if (self.eth_type[t]['export'] & EF_TYPE):
1568 if self.eth_type[t]['export'] & EF_EXTERN:
1570 fx.write(self.eth_type_fn_h(t))
1571 for f in self.eth_hfpdu_ord: # PDUs
1572 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']):
1573 fx.write(self.eth_out_pdu_decl(f))
1574 self.output.file_close(fx)
1576 #--- eth_output_expcnf ------------------------------------------------------
1577 def eth_output_expcnf(self):
1578 fx = self.output.file_open('exp', ext='cnf')
1579 fx.write('#.MODULE\n')
1581 for (m, p) in self.modules:
1582 if (len(m) > maxw): maxw = len(m)
1583 for (m, p) in self.modules:
1584 fx.write("%-*s %s\n" % (maxw, m, p))
1585 fx.write('#.END\n\n')
1586 for cls in self.objectclass_ord:
1587 if self.objectclass[cls]['export']:
1589 if self.objectclass[cls]['export'] & EF_MODULE:
1590 cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm)
1591 fx.write('#.CLASS %s\n' % (cnm))
1593 for fld in self.objectclass[cls]['val'].fields:
1594 w = len(fld.fld_repr()[0])
1595 if (w > maxw): maxw = w
1596 for fld in self.objectclass[cls]['val'].fields:
1597 repr = fld.fld_repr()
1598 fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:])))
1599 fx.write('#.END\n\n')
1601 fx.write('#.IMPORT_TAG\n')
1602 for t in self.eth_export_ord: # tags
1603 if (self.eth_type[t]['export'] & EF_TYPE):
1604 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1605 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1606 fx.write('#.END\n\n')
1607 fx.write('#.TYPE_ATTR\n')
1608 for t in self.eth_export_ord: # attributes
1609 if (self.eth_type[t]['export'] & EF_TYPE):
1610 tnm = self.eth_type[t]['ref'][0]
1611 if self.eth_type[t]['export'] & EF_MODULE:
1612 tnm = "$%s$%s" % (self.type[tnm]['module'], tnm)
1613 fx.write('%-24s ' % tnm)
1614 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1615 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1616 fx.write('#.END\n\n')
1617 self.output.file_close(fx, keep_anyway=True)
1619 #--- eth_output_val ------------------------------------------------------
1620 def eth_output_val(self):
1621 fx = self.output.file_open('val', ext='h')
1622 for v in self.eth_value_ord1:
1623 vv = self.eth_value[v]['value']
1624 if isinstance (vv, Value):
1625 vv = vv.to_str(self)
1626 fx.write("#define %-30s %s\n" % (v, vv))
1627 for t in self.eth_type_ord1:
1628 if self.eth_type[t]['import']:
1630 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1631 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1632 self.output.file_close(fx)
1634 #--- eth_output_valexp ------------------------------------------------------
1635 def eth_output_valexp(self):
1636 if (not len(self.eth_vexport_ord)): return
1637 fx = self.output.file_open('valexp', ext='h')
1638 for v in self.eth_vexport_ord:
1639 vv = self.eth_value[v]['value']
1640 if isinstance (vv, Value):
1641 vv = vv.to_str(self)
1642 fx.write("#define %-30s %s\n" % (v, vv))
1643 self.output.file_close(fx)
1645 #--- eth_output_types -------------------------------------------------------
1646 def eth_output_types(self):
1648 t = self.eth_hf[f]['ethtype']
1649 is_new = self.eth_hf[f]['pdu']['new']
1652 if (not self.eth_hf[f]['pdu']['export']):
1658 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1660 out += ' int offset = 0;\n'
1667 if (self.Aligned()):
1671 out += " asn1_ctx_t asn1_ctx;\n"
1672 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1674 out += " asn1_ctx_t asn1_ctx;\n"
1675 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
1676 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1678 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1681 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1682 if (self.Per() and is_new):
1683 out += ' offset += 7; offset >>= 3;\n'
1685 out += ' return offset;\n'
1689 fx = self.output.file_open('fn')
1691 if (len(self.eth_hfpdu_ord)):
1693 for f in self.eth_hfpdu_ord:
1694 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
1696 fx.write('/*--- PDUs declarations ---*/\n')
1698 fx.write(self.eth_out_pdu_decl(f))
1701 if self.eth_dep_cycle:
1702 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1704 while i < len(self.eth_dep_cycle):
1705 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1706 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1707 fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]]))
1708 fx.write(self.eth_type_fn_h(t))
1712 for t in self.eth_type_ord1:
1713 if self.eth_type[t]['import']:
1715 if self.eth_type[t]['val'].eth_has_vals():
1716 if self.eth_type[t]['no_emit'] & EF_VALS:
1718 elif self.eth_type[t]['user_def'] & EF_VALS:
1719 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1720 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1723 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1724 if self.eth_type[t]['no_emit'] & EF_TYPE:
1726 elif self.eth_type[t]['user_def'] & EF_TYPE:
1727 fx.write(self.eth_type_fn_h(t))
1729 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1731 if (len(self.eth_hfpdu_ord)):
1732 fx.write('/*--- PDUs ---*/\n\n')
1733 for f in self.eth_hfpdu_ord:
1734 if (self.eth_hf[f]['pdu']):
1735 if (f in self.emitted_pdu):
1736 fx.write(" /* %s already emitted */\n" % (f))
1738 fx.write(out_pdu(f))
1739 self.emitted_pdu[f] = True
1741 fempty = pos == fx.tell()
1742 self.output.file_close(fx, discard=fempty)
1744 #--- eth_output_dis_hnd -----------------------------------------------------
1745 def eth_output_dis_hnd(self):
1746 fx = self.output.file_open('dis-hnd')
1748 for f in self.eth_hfpdu_ord:
1749 pdu = self.eth_hf[f]['pdu']
1750 if (pdu and pdu['reg'] and not pdu['hidden']):
1752 if (pdu['reg'] != '.'):
1753 dis += '.' + pdu['reg']
1754 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1757 self.output.file_close(fx, discard=fempty)
1759 #--- eth_output_dis_reg -----------------------------------------------------
1760 def eth_output_dis_reg(self):
1761 fx = self.output.file_open('dis-reg')
1763 for f in self.eth_hfpdu_ord:
1764 pdu = self.eth_hf[f]['pdu']
1765 if (pdu and pdu['reg']):
1767 if (pdu['new']): new_prefix = 'new_'
1769 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1770 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1771 if (not pdu['hidden']):
1772 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1775 self.output.file_close(fx, discard=fempty)
1777 #--- eth_output_dis_tab -----------------------------------------------------
1778 def eth_output_dis_tab(self):
1779 fx = self.output.file_open('dis-tab')
1781 for k in self.conform.get_order('REGISTER'):
1782 reg = self.conform.use_item('REGISTER', k)
1783 if reg['pdu'] not in self.field: continue
1784 f = self.field[reg['pdu']]['ethname']
1785 pdu = self.eth_hf[f]['pdu']
1787 if (pdu['new']): new_prefix = 'new_'
1788 if (reg['rtype'] in ('NUM', 'STR')):
1790 if (reg['rtype'] == 'STR'): rstr = '_string'
1793 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1794 if (not pdu['hidden']):
1795 hnd = '%s_handle' % (asn2c(dis))
1797 hnd = 'find_dissector("%s")' % (dis)
1799 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1800 rport = self.value_get_eth(reg['rport'])
1801 fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
1802 elif (reg['rtype'] in ('BER', 'PER')):
1803 roid = self.value_get_eth(reg['roid'])
1804 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
1807 self.output.file_close(fx, discard=fempty)
1809 #--- eth_output_table -----------------------------------------------------
1810 def eth_output_table(self):
1811 for num in list(self.conform.report.keys()):
1812 fx = self.output.file_open('table' + num)
1813 for rep in self.conform.report[num]:
1814 if rep['type'] == 'HDR':
1818 var_list = var.split('.')
1821 if (cls in self.oassign_cls):
1822 for ident in self.oassign_cls[cls]:
1823 obj = self.get_obj_repr(ident, var_list)
1827 obj['_DICT'] = str(obj)
1829 text = rep['text'] % obj
1831 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)
1834 fx.write("/* Unknown or empty loop list %s */\n" % (var))
1836 fx.write(rep['text'])
1837 if rep['type'] == 'FTR':
1839 self.output.file_close(fx)
1841 #--- dupl_report -----------------------------------------------------
1842 def dupl_report(self):
1844 tmplist = sorted(self.eth_type_dupl.keys())
1846 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
1848 for tt in self.eth_type_dupl[t]:
1849 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
1850 warnings.warn_explicit(msg, UserWarning, '', 0)
1852 tmplist = list(self.eth_hf_dupl.keys())
1855 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
1857 for tt in list(self.eth_hf_dupl[f].keys()):
1858 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
1859 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
1861 warnings.warn_explicit(msg, UserWarning, '', 0)
1863 #--- eth_do_output ------------------------------------------------------------
1864 def eth_do_output(self):
1866 print "\n# Assignments"
1867 for a in self.assign_ord:
1869 if (self.assign[a]['virt']): v = '*'
1871 print "\n# Value assignments"
1872 for a in self.vassign_ord:
1874 print "\n# Information object assignments"
1875 for a in self.oassign_ord:
1876 print " %-12s (%s)" % (a, self.oassign[a].cls)
1878 print "\n# Imported Types"
1879 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1881 for t in self.type_imp:
1882 print "%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])
1883 print "\n# Imported Values"
1884 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1886 for t in self.value_imp:
1887 print "%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])
1888 print "\n# Imported Object Classes"
1889 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1891 for t in self.objectclass_imp:
1892 print "%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto'])
1893 print "\n# Exported Types"
1894 print "%-31s %s" % ("Wireshark type", "Export Flag")
1896 for t in self.eth_export_ord:
1897 print "%-31s 0x%02X" % (t, self.eth_type[t]['export'])
1898 print "\n# Exported Values"
1899 print "%-40s %s" % ("Wireshark name", "Value")
1901 for v in self.eth_vexport_ord:
1902 vv = self.eth_value[v]['value']
1903 if isinstance (vv, Value):
1904 vv = vv.to_str(self)
1905 print "%-40s %s" % (v, vv)
1906 print "\n# ASN.1 Object Classes"
1907 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1909 for t in self.objectclass_ord:
1910 print "%-40s " % (t)
1911 print "\n# ASN.1 Types"
1912 print "%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")
1914 for t in self.type_ord:
1915 print "%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])
1916 print "\n# Wireshark Types"
1917 print "Wireshark type References (ASN.1 types)"
1919 for t in self.eth_type_ord:
1920 print "%-31s %d" % (t, len(self.eth_type[t]['ref'])),
1921 print ', '.join(self.eth_type[t]['ref'])
1922 print "\n# ASN.1 Values"
1923 print "%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value")
1925 for v in self.value_ord:
1926 vv = self.value[v]['value']
1927 if isinstance (vv, Value):
1928 vv = vv.to_str(self)
1929 print "%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname'])
1930 #print "\n# Wireshark Values"
1931 #print "%-40s %s" % ("Wireshark name", "Value")
1933 #for v in self.eth_value_ord:
1934 # vv = self.eth_value[v]['value']
1935 # if isinstance (vv, Value):
1936 # vv = vv.to_str(self)
1937 # print "%-40s %s" % (v, vv)
1938 print "\n# ASN.1 Fields"
1939 print "ASN.1 unique name Wireshark name ASN.1 type"
1941 for f in (self.pdu_ord + self.field_ord):
1942 print "%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])
1943 print "\n# Wireshark Fields"
1944 print "Wireshark name Wireshark type References (ASN.1 fields)"
1946 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1947 print "%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])),
1948 print ', '.join(self.eth_hf[f]['ref'])
1949 #print "\n# Order after dependencies"
1950 #print '\n'.join(self.eth_type_ord1)
1951 print "\n# Cyclic dependencies"
1952 for c in self.eth_dep_cycle:
1953 print ' -> '.join(c)
1955 self.output.outnm = self.outnm_opt
1956 if (not self.output.outnm):
1957 self.output.outnm = self.proto
1958 self.output.outnm = self.output.outnm.replace('.', '-')
1959 if not self.justexpcnf:
1960 self.eth_output_hf()
1961 self.eth_output_ett()
1962 self.eth_output_types()
1963 self.eth_output_hf_arr()
1964 self.eth_output_ett_arr()
1965 self.eth_output_export()
1966 self.eth_output_val()
1967 self.eth_output_valexp()
1968 self.eth_output_dis_hnd()
1969 self.eth_output_dis_reg()
1970 self.eth_output_dis_tab()
1971 self.eth_output_table()
1973 self.eth_output_expcnf()
1975 def dbg_modules(self):
1977 print "%-30s " % (m),
1978 dep = self.module[m][:]
1979 for i in range(len(dep)):
1980 if dep[i] not in self.module:
1981 dep[i] = '*' + dep[i]
1982 print ', '.join(dep)
1983 # end of print_mod()
1984 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module)
1985 print "\n# ASN.1 Moudules"
1986 print "Module name Dependency"
1989 for m in (self.module_ord):
1991 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
1993 print "\n# ASN.1 Moudules - in dependency order"
1994 print "Module name Dependency"
1999 print "\nCyclic dependencies:"
2000 for i in (range(len(mod_cyc))):
2001 print "%02d: %s" % (i + 1, str(mod_cyc[i]))
2004 #--- EthCnf -------------------------------------------------------------------
2013 self.suppress_line = False
2014 self.include_path = []
2015 # Value name Default value Duplicity check Usage check
2016 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2017 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2018 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2019 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2020 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2021 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2022 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2023 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2024 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2025 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2026 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2027 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2028 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2029 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2030 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2031 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2032 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2033 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2034 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2035 self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2036 self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2038 for k in list(self.tblcfg.keys()) :
2042 def add_item(self, table, key, fn, lineno, **kw):
2043 if self.tblcfg[table]['chk_dup'] and key in self.table[table]:
2044 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2045 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
2046 UserWarning, fn, lineno)
2048 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2049 self.table[table][key].update(kw)
2050 self.order[table].append(key)
2052 def update_item(self, table, key, fn, lineno, **kw):
2053 if key not in self.table[table]:
2054 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2055 self.order[table].append(key)
2056 self.table[table][key][self.tblcfg[table]['val_nm']] = {}
2057 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
2059 def get_order(self, table):
2060 return self.order[table]
2062 def check_item(self, table, key):
2063 return key in self.table[table]
2065 def copy_item(self, table, dst_key, src_key):
2066 if (src_key in self.table[table]):
2067 self.table[table][dst_key] = self.table[table][src_key]
2069 def check_item_value(self, table, key, **kw):
2070 return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key]
2072 def use_item(self, table, key, **kw):
2073 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
2074 if key not in self.table[table]: return vdflt
2075 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
2076 #print "use_item() - set used for %s %s" % (table, key)
2077 self.table[table][key]['used'] = True
2078 return self.table[table][key].get(vname, vdflt)
2080 def omit_assignment(self, type, ident, module):
2081 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
2083 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
2084 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2085 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
2086 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
2087 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
2090 def add_fn_line(self, name, ctx, line, fn, lineno):
2091 if name not in self.fn:
2092 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2093 if (self.fn[name][ctx]):
2094 self.fn[name][ctx]['text'] += line
2096 self.fn[name][ctx] = {'text' : line, 'used' : False,
2097 'fn' : fn, 'lineno' : lineno}
2098 def get_fn_presence(self, name):
2099 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2100 #if self.fn.has_key(name): print self.fn[name]
2101 return name in self.fn
2102 def get_fn_body_presence(self, name):
2103 return name in self.fn and self.fn[name]['FN_BODY']
2104 def get_fn_text(self, name, ctx):
2105 if (name not in self.fn):
2107 if (not self.fn[name][ctx]):
2109 self.fn[name][ctx]['used'] = True
2110 out = self.fn[name][ctx]['text']
2111 if (not self.suppress_line):
2112 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], os.path.basename(self.fn[name][ctx]['fn']), out);
2115 def add_pdu(self, par, is_new, fn, lineno):
2116 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2117 (reg, hidden) = (None, False)
2118 if (len(par) > 1): reg = par[1]
2119 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
2120 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False}
2121 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
2124 def add_register(self, pdu, par, fn, lineno):
2125 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2126 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
2127 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
2128 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
2129 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
2130 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
2131 if ((len(par)-1) < pmin):
2132 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
2134 if ((len(par)-1) > pmax):
2135 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
2136 attr = {'pdu' : pdu, 'rtype' : rtype}
2137 if (rtype in ('NUM', 'STR')):
2138 attr['rtable'] = par[1]
2139 attr['rport'] = par[2]
2140 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
2141 elif (rtype in ('BER', 'PER')):
2142 attr['roid'] = par[1]
2143 attr['roidname'] = '""'
2145 attr['roidname'] = par[2]
2146 elif attr['roid'][0] != '"':
2147 attr['roidname'] = '"' + attr['roid'] + '"'
2148 rkey = '/'.join([rtype, attr['roid']])
2149 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
2151 def check_par(self, par, pmin, pmax, fn, lineno):
2152 for i in range(len(par)):
2156 if par[i][0] == '#':
2160 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2162 if (pmax >= 0) and (len(par) > pmax):
2163 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
2168 def get_par(line, pmin, pmax, fn, lineno):
2169 par = line.split(None, pmax)
2170 par = self.check_par(par, pmin, pmax, fn, lineno)
2173 def get_par_nm(line, pmin, pmax, fn, lineno):
2175 par = line.split(None, pmax)
2178 for i in range(len(par)):
2179 if par[i][0] == '#':
2183 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2190 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2191 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2192 nmpar_end = re.compile(r'\s*$')
2193 result = nmpar_first.search(nmpar)
2196 k = result.group('attr')
2198 result = nmpar_next.search(nmpar, pos)
2203 p2 = nmpar_end.search(nmpar, pos).start()
2213 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2214 report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2215 comment = re.compile(r'^\s*#[^.]')
2216 empty = re.compile(r'^\s*$')
2219 default_flags = 0x00
2232 fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import']
2236 if comment.search(line): continue
2237 result = directive.search(line)
2238 if result: # directive
2239 rep_result = report.search(result.group('name'))
2240 if result.group('name') == 'END_OF_CNF':
2242 elif result.group('name') == 'OPT':
2243 ctx = result.group('name')
2244 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
2245 if not par: continue
2246 self.set_opt(par[0], par[1:], fn, lineno)
2248 elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
2249 'MODULE', 'MODULE_IMPORT',
2250 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2251 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2252 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2253 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2254 ctx = result.group('name')
2255 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2256 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2257 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2258 ctx = result.group('name')
2260 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2262 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2264 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2267 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
2268 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2269 ctx = 'NO_OMIT_ASSGN'
2272 elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2273 ctx = result.group('name')
2274 default_flags = EF_TYPE|EF_VALS
2275 if ctx == 'MODULE_EXPORTS':
2277 default_flags |= EF_MODULE
2278 if ctx == 'EXPORTS':
2279 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
2281 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2282 if not par: continue
2284 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
2285 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
2286 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
2287 elif (ctx == 'EXPORTS'): p = 0
2288 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
2289 for i in range(p, len(par)):
2290 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
2291 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
2292 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
2293 elif (par[i] == 'WS_VAR'): default_flags |= EF_WS_VAR
2294 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
2295 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2296 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2297 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2298 ctx = result.group('name')
2299 default_flags = EF_ENUM
2300 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
2301 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2302 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
2303 for i in range(0, len(par)):
2304 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2305 elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT
2306 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
2307 elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE
2308 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
2309 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
2310 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2311 elif result.group('name') == 'FN_HDR':
2313 if (ctx in ('FN_PARS',)) and name: minp = 0
2314 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2315 if (not par) and (minp > 0): continue
2316 ctx = result.group('name')
2317 if par: name = par[0]
2318 elif result.group('name') == 'FN_FTR':
2320 if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0
2321 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2322 if (not par) and (minp > 0): continue
2323 ctx = result.group('name')
2324 if par: name = par[0]
2325 elif result.group('name') == 'FN_BODY':
2326 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2327 if not par: continue
2328 ctx = result.group('name')
2331 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
2332 elif result.group('name') == 'FN_PARS':
2333 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2334 ctx = result.group('name')
2339 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
2341 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2343 elif result.group('name') == 'CLASS':
2344 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2345 if not par: continue
2346 ctx = result.group('name')
2348 add_class_ident(name)
2349 if not name.split('$')[-1].isupper():
2350 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
2351 UserWarning, fn, lineno)
2352 elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2353 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2354 if not par: continue
2355 self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno)
2356 elif rep_result: # Reports
2357 num = rep_result.group('num')
2358 type = rep_result.group('type')
2360 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2361 if not par: continue
2363 par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno)
2364 rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno }
2367 self.report.setdefault(num, []).append(rep)
2370 elif result.group('name') in ('INCLUDE', 'IMPORT') :
2371 is_imp = result.group('name') == 'IMPORT'
2372 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2374 warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno)
2377 #print "Try include: %s" % (fname)
2378 if (not os.path.exists(fname)):
2379 fname = os.path.join(os.path.split(fn)[0], par[0])
2380 #print "Try include: %s" % (fname)
2382 while not os.path.exists(fname) and (i < len(self.include_path)):
2383 fname = os.path.join(self.include_path[i], par[0])
2384 #print "Try include: %s" % (fname)
2386 if (not os.path.exists(fname)):
2388 continue # just ignore
2390 fname = par[0] # report error
2391 fnew = open(fname, "r")
2392 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import})
2393 fn, f, lineno, is_import = par[0], fnew, 0, is_imp
2394 elif result.group('name') == 'END':
2397 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
2400 if not empty.match(line):
2401 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
2403 if empty.match(line): continue
2404 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
2405 if not par: continue
2406 self.set_opt(par[0], par[1:], fn, lineno)
2407 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2408 if empty.match(line): continue
2409 if ctx == 'EXPORTS':
2410 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
2412 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2413 if not par: continue
2414 flags = default_flags
2417 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
2418 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
2419 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
2420 elif (ctx == 'EXPORTS'): p = 1
2421 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
2422 for i in range(p, len(par)):
2423 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
2424 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
2425 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
2426 elif (par[i] == 'WS_VAR'): flags |= EF_WS_VAR
2427 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
2428 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2429 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2430 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
2431 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
2432 if empty.match(line): continue
2433 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
2434 if not par: continue
2435 flags = default_flags
2436 for i in range(1, len(par)):
2437 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2438 elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT
2439 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
2440 elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE
2441 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
2442 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
2443 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2444 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
2445 elif ctx in ('PDU', 'PDU_NEW'):
2446 if empty.match(line): continue
2447 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
2448 if not par: continue
2450 if (ctx == 'PDU_NEW'): is_new = True
2451 self.add_pdu(par[0:2], is_new, fn, lineno)
2453 self.add_register(par[0], par[2:5], fn, lineno)
2454 elif ctx in ('REGISTER', 'REGISTER_NEW'):
2455 if empty.match(line): continue
2456 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
2457 if not par: continue
2458 if not self.check_item('PDU', par[0]):
2460 if (ctx == 'REGISTER_NEW'): is_new = True
2461 self.add_pdu(par[0:1], is_new, fn, lineno)
2462 self.add_register(par[0], par[1:4], fn, lineno)
2463 elif ctx in ('MODULE', 'MODULE_IMPORT'):
2464 if empty.match(line): continue
2465 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2466 if not par: continue
2467 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
2468 elif ctx == 'IMPORT_TAG':
2469 if empty.match(line): continue
2470 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
2471 if not par: continue
2472 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
2473 elif ctx == 'OMIT_ASSIGNMENT':
2474 if empty.match(line): continue
2475 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2476 if not par: continue
2477 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
2478 elif ctx == 'NO_OMIT_ASSGN':
2479 if empty.match(line): continue
2480 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2481 if not par: continue
2482 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
2483 elif ctx == 'VIRTUAL_ASSGN':
2484 if empty.match(line): continue
2485 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
2486 if not par: continue
2487 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
2488 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
2489 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
2491 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
2492 if not par[0][0].isupper():
2493 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
2494 UserWarning, fn, lineno)
2495 elif ctx == 'SET_TYPE':
2496 if empty.match(line): continue
2497 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2498 if not par: continue
2499 if not self.check_item('VIRTUAL_ASSGN', par[0]):
2500 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
2501 if not par[1][0].isupper():
2502 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
2503 UserWarning, fn, lineno)
2504 elif ctx == 'ASSIGN_VALUE_TO_TYPE':
2505 if empty.match(line): continue
2506 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2507 if not par: continue
2508 self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno)
2509 elif ctx == 'TYPE_RENAME':
2510 if empty.match(line): continue
2511 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2512 if not par: continue
2513 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2514 if not par[1][0].isupper():
2515 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2516 UserWarning, fn, lineno)
2517 elif ctx == 'FIELD_RENAME':
2518 if empty.match(line): continue
2519 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2520 if not par: continue
2521 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2522 if not par[1][0].islower():
2523 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2524 UserWarning, fn, lineno)
2525 elif ctx == 'TF_RENAME':
2526 if empty.match(line): continue
2527 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2528 if not par: continue
2529 tmpu = par[1][0].upper() + par[1][1:]
2530 tmpl = par[1][0].lower() + par[1][1:]
2531 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
2532 if not tmpu[0].isupper():
2533 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2534 UserWarning, fn, lineno)
2535 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
2536 if not tmpl[0].islower():
2537 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2538 UserWarning, fn, lineno)
2539 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2540 if empty.match(line): continue
2541 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2542 if not par: continue
2543 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
2544 elif ctx == 'FN_PARS':
2545 if empty.match(line): continue
2547 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
2549 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2550 if not par: continue
2552 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
2554 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2555 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2556 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
2557 elif ctx == 'CLASS':
2558 if empty.match(line): continue
2559 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
2560 if not par: continue
2561 if not set_type_to_class(name, par[0], par[1:]):
2562 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
2563 UserWarning, fn, lineno)
2564 elif ctx == 'TABLE':
2565 self.report[name][-1]['text'] += line
2567 def set_opt(self, opt, par, fn, lineno):
2568 #print "set_opt: %s, %s" % (opt, par)
2570 par = self.check_par(par, 1, 1, fn, lineno)
2572 self.include_path.append(par[0])
2573 elif opt in ("-b", "BER", "CER", "DER"):
2574 par = self.check_par(par, 0, 0, fn, lineno)
2575 self.ectx.encoding = 'ber'
2576 elif opt in ("PER",):
2577 par = self.check_par(par, 0, 0, fn, lineno)
2578 self.ectx.encoding = 'per'
2579 elif opt in ("-p", "PROTO"):
2580 par = self.check_par(par, 1, 1, fn, lineno)
2582 self.ectx.proto_opt = par[0]
2583 self.ectx.merge_modules = True
2584 elif opt in ("ALIGNED",):
2585 par = self.check_par(par, 0, 0, fn, lineno)
2586 self.ectx.aligned = True
2587 elif opt in ("-u", "UNALIGNED"):
2588 par = self.check_par(par, 0, 0, fn, lineno)
2589 self.ectx.aligned = False
2590 elif opt in ("-d",):
2591 par = self.check_par(par, 1, 1, fn, lineno)
2593 self.ectx.dbgopt = par[0]
2594 elif opt in ("-e",):
2595 par = self.check_par(par, 0, 0, fn, lineno)
2596 self.ectx.expcnf = True
2597 elif opt in ("-S",):
2598 par = self.check_par(par, 0, 0, fn, lineno)
2599 self.ectx.merge_modules = True
2600 elif opt in ("GROUP_BY_PROT",):
2601 par = self.check_par(par, 0, 0, fn, lineno)
2602 self.ectx.group_by_prot = True
2603 elif opt in ("-o",):
2604 par = self.check_par(par, 1, 1, fn, lineno)
2606 self.ectx.outnm_opt = par[0]
2607 elif opt in ("-O",):
2608 par = self.check_par(par, 1, 1, fn, lineno)
2610 self.ectx.output.outdir = par[0]
2611 elif opt in ("-s",):
2612 par = self.check_par(par, 1, 1, fn, lineno)
2614 self.ectx.output.single_file = par[0]
2615 elif opt in ("-k",):
2616 par = self.check_par(par, 0, 0, fn, lineno)
2617 self.ectx.output.keep = True
2618 elif opt in ("-L",):
2619 par = self.check_par(par, 0, 0, fn, lineno)
2620 self.suppress_line = True
2621 elif opt in ("EMBEDDED_PDV_CB",):
2622 par = self.check_par(par, 1, 1, fn, lineno)
2624 self.ectx.default_embedded_pdv_cb = par[0]
2625 elif opt in ("EXTERNAL_TYPE_CB",):
2626 par = self.check_par(par, 1, 1, fn, lineno)
2628 self.ectx.default_external_type_cb = par[0]
2630 warnings.warn_explicit("Unknown option %s" % (opt),
2631 UserWarning, fn, lineno)
2633 def dbg_print(self):
2634 print "\n# Conformance values"
2635 print "%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")
2637 tbls = sorted(self.table.keys())
2639 keys = sorted(self.table[t].keys())
2641 print "%-15s %4s %-15s %-20s %s" % (
2642 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))
2644 def unused_report(self):
2645 tbls = sorted(self.table.keys())
2647 if not self.tblcfg[t]['chk_use']: continue
2648 keys = sorted(self.table[t].keys())
2650 if not self.table[t][k]['used']:
2651 warnings.warn_explicit("Unused %s for %s" % (t, k),
2652 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2653 fnms = list(self.fn.keys())
2656 keys = sorted(self.fn[f].keys())
2658 if not self.fn[f][k]: continue
2659 if not self.fn[f][k]['used']:
2660 warnings.warn_explicit("Unused %s for %s" % (k, f),
2661 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2663 #--- EthOut -------------------------------------------------------------------
2669 self.single_file = None
2670 self.created_files = {}
2671 self.created_files_ord = []
2674 def outcomment(self, ln, comment=None):
2676 return '%s %s\n' % (comment, ln)
2678 return '/* %-74s */\n' % (ln)
2680 def created_file_add(self, name, keep_anyway):
2681 name = os.path.normcase(os.path.abspath(name))
2682 if name not in self.created_files:
2683 self.created_files_ord.append(name)
2684 self.created_files[name] = keep_anyway
2686 self.created_files[name] = self.created_files[name] or keep_anyway
2688 def created_file_exists(self, name):
2689 name = os.path.normcase(os.path.abspath(name))
2690 return name in self.created_files
2692 #--- output_fname -------------------------------------------------------
2693 def output_fname(self, ftype, ext='c'):
2695 if not ext in ('cnf',):
2702 #--- output_fullname -------------------------------------------------------
2703 def output_fullname(self, ftype, ext='c'):
2704 return os.path.join(self.outdir, self.output_fname(ftype, ext=ext))
2705 #--- file_open -------------------------------------------------------
2706 def file_open(self, ftype, ext='c'):
2707 fn = self.output_fullname(ftype, ext=ext)
2708 if self.created_file_exists(fn):
2715 fx.write(self.fhdr(fn, comment = comment))
2717 if (not self.single_file and not self.created_file_exists(fn)):
2718 fx.write(self.fhdr(fn))
2719 if not self.ectx.merge_modules:
2722 if self.ectx.groups():
2724 if (len(self.ectx.modules) > 1):
2726 for (m, p) in self.ectx.modules:
2729 mstr += "Module %s" % (self.ectx.Module())
2730 mstr += " --- --- ---"
2731 fx.write(self.outcomment(mstr, comment))
2734 #--- file_close -------------------------------------------------------
2735 def file_close(self, fx, discard=False, keep_anyway=False):
2737 if discard and not self.created_file_exists(fx.name):
2740 self.created_file_add(fx.name, keep_anyway)
2741 #--- fhdr -------------------------------------------------------
2742 def fhdr(self, fn, comment=None):
2744 out += self.outcomment('Do not modify this file.', comment)
2745 out += self.outcomment('It is created automatically by the ASN.1 to Wireshark dissector compiler', comment)
2746 out += self.outcomment(os.path.basename(fn), comment)
2747 out += self.outcomment(' '.join(sys.argv), comment)
2749 # Make Windows path separator look like Unix path separator
2750 return out.replace('\\', '/')
2752 #--- dbg_print -------------------------------------------------------
2753 def dbg_print(self):
2754 print "\n# Output files"
2755 print "\n".join(self.created_files_ord)
2758 #--- make_single_file -------------------------------------------------------
2759 def make_single_file(self):
2760 if (not self.single_file): return
2761 in_nm = self.single_file + '.c'
2762 out_nm = self.output_fullname('')
2763 self.do_include(out_nm, in_nm)
2764 in_nm = self.single_file + '.h'
2765 if (os.path.exists(in_nm)):
2766 out_nm = self.output_fullname('', ext='h')
2767 self.do_include(out_nm, in_nm)
2769 for fn in self.created_files_ord:
2770 if not self.created_files[fn]:
2773 #--- do_include -------------------------------------------------------
2774 def do_include(self, out_nm, in_nm):
2775 def check_file(fn, fnlist):
2776 fnfull = os.path.normcase(os.path.abspath(fn))
2777 if (fnfull in fnlist and os.path.exists(fnfull)):
2778 return os.path.normpath(fn)
2780 fin = file(in_nm, "r")
2781 fout = file(out_nm, "w")
2782 fout.write(self.fhdr(out_nm))
2783 fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n')
2785 fout.write('#line %u "%s"\n' % (1, os.path.basename(in_nm)))
2787 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2792 cont_linenum = cont_linenum + 1;
2793 line = fin.readline()
2794 if (line == ''): break
2796 result = include.search(line)
2797 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2799 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2801 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2803 ifile = check_file(result.group('fname'), self.created_files)
2806 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
2807 fout.write('#line %u "%s"\n' % (1, os.path.basename(ifile)))
2808 finc = file(ifile, "r")
2809 fout.write(finc.read())
2811 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
2812 fout.write('#line %u "%s"\n' % (cont_linenum+1, os.path.basename(in_nm)) )
2821 #--- Node ---------------------------------------------------------------------
2823 def __init__(self,*args, **kw):
2825 self.type = self.__class__.__name__
2827 assert (len(args) == 1)
2829 self.__dict__.update (kw)
2830 def str_child (self, key, child, depth):
2831 indent = " " * (2 * depth)
2832 keystr = indent + key + ": "
2833 if key == 'type': # already processed in str_depth
2835 if isinstance (child, Node): # ugh
2836 return keystr + "\n" + child.str_depth (depth+1)
2837 if isinstance(child, type ([])):
2840 if isinstance (x, Node):
2841 l.append (x.str_depth (depth+1))
2843 l.append (indent + " " + str(x) + "\n")
2844 return keystr + "[\n" + ''.join(l) + indent + "]\n"
2846 return keystr + str (child) + "\n"
2847 def str_depth (self, depth): # ugh
2848 indent = " " * (2 * depth)
2849 l = ["%s%s" % (indent, self.type)]
2850 l.append ("".join (map (lambda (k,v): self.str_child (k, v, depth + 1),
2851 list(self.__dict__.items ()))))
2852 return "\n".join (l)
2854 return "\n" + self.str_depth (0)
2855 def to_python (self, ctx):
2856 return self.str_depth (ctx.indent_lev)
2858 def eth_reg(self, ident, ectx):
2861 def fld_obj_repr(self, ectx):
2862 return "/* TO DO %s */" % (str(self))
2864 #--- ValueAssignment -------------------------------------------------------------
2865 class ValueAssignment (Node):
2866 def __init__(self,*args, **kw) :
2867 Node.__init__ (self,*args, **kw)
2869 def eth_reg(self, ident, ectx):
2870 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
2871 ectx.eth_reg_vassign(self)
2872 ectx.eth_reg_value(self.ident, self.typ, self.val)
2874 #--- ObjectAssignment -------------------------------------------------------------
2875 class ObjectAssignment (Node):
2876 def __init__(self,*args, **kw) :
2877 Node.__init__ (self,*args, **kw)
2879 def __eq__(self, other):
2880 if self.cls != other.cls:
2882 if len(self.val) != len(other.val):
2884 for f in (list(self.val.keys())):
2885 if f not in other.val:
2887 if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
2888 if not self.val[f].fld_obj_eq(other.val[f]):
2891 if str(self.val[f]) != str(other.val[f]):
2895 def eth_reg(self, ident, ectx):
2896 def make_virtual_type(cls, field, prefix):
2897 if isinstance(self.val, str): return
2898 if field in self.val and not isinstance(self.val[field], Type_Ref):
2899 vnm = prefix + '-' + self.ident
2900 virtual_tr = Type_Ref(val = vnm)
2902 self.val[field] = virtual_tr
2903 ectx.eth_reg_assign(vnm, t, virt=True)
2904 ectx.eth_reg_type(vnm, t)
2905 t.eth_reg_sub(vnm, ectx)
2906 if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field):
2907 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))
2909 # end of make_virtual_type()
2910 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
2911 self.module = ectx.Module()
2912 ectx.eth_reg_oassign(self)
2913 if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
2914 make_virtual_type(self.cls, '&Type', 'TYPE')
2915 if (self.cls == 'OPERATION'):
2916 make_virtual_type(self.cls, '&ArgumentType', 'ARG')
2917 make_virtual_type(self.cls, '&ResultType', 'RES')
2918 if (self.cls == 'ERROR'):
2919 make_virtual_type(self.cls, '&ParameterType', 'PAR')
2922 #--- Type ---------------------------------------------------------------------
2924 def __init__(self,*args, **kw) :
2928 self.named_list = None
2929 Node.__init__ (self,*args, **kw)
2932 if self.name is None :
2937 def HasConstraint(self):
2938 if self.constr is None :
2943 def HasSizeConstraint(self):
2944 return self.HasConstraint() and self.constr.IsSize()
2946 def HasValueConstraint(self):
2947 return self.HasConstraint() and self.constr.IsValue()
2949 def HasPermAlph(self):
2950 return self.HasConstraint() and self.constr.IsPermAlph()
2952 def HasContentsConstraint(self):
2953 return self.HasConstraint() and self.constr.IsContents()
2955 def HasOwnTag(self):
2956 return len(self.tags) > 0
2958 def HasImplicitTag(self, ectx):
2959 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
2961 def IndetermTag(self, ectx):
2964 def AddTag(self, tag):
2965 self.tags[0:0] = [tag]
2967 def GetTag(self, ectx):
2968 #print "GetTag(%s)\n" % self.name;
2969 if (self.HasOwnTag()):
2970 return self.tags[0].GetTag(ectx)
2972 return self.GetTTag(ectx)
2974 def GetTTag(self, ectx):
2975 print "#Unhandled GetTTag() in %s" % (self.type)
2976 print self.str_depth(1)
2977 return ('BER_CLASS_unknown', 'TAG_unknown')
2979 def SetName(self, name):
2982 def AddConstraint(self, constr):
2983 if not self.HasConstraint():
2984 self.constr = constr
2986 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
2988 def eth_tname(self):
2989 return '#' + self.type + '_' + str(id(self))
2991 def eth_ftype(self, ectx):
2992 return ('FT_NONE', 'BASE_NONE')
2994 def eth_strings(self):
2997 def eth_need_tree(self):
3000 def eth_has_vals(self):
3003 def eth_has_enum(self, tname, ectx):
3004 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
3006 def eth_need_pdu(self, ectx):
3009 def eth_named_bits(self):
3012 def eth_reg_sub(self, ident, ectx):
3015 def get_components(self, ectx):
3016 print "#Unhandled get_components() in %s" % (self.type)
3017 print self.str_depth(1)
3020 def sel_req(self, sel, ectx):
3021 print "#Selection '%s' required for non-CHOICE type %s" % (sel, self.type)
3022 print self.str_depth(1)
3024 def fld_obj_eq(self, other):
3025 return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
3027 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
3028 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3030 if (ectx.Tag() and (len(self.tags) > tstrip)):
3032 for i in range(len(self.tags)-1, tstrip-1, -1):
3033 tagged_type = TaggedType(val=tagged_type, tstrip=i)
3034 tagged_type.AddTag(self.tags[i])
3035 if not tagflag: # 1st tagged level
3036 if self.IsNamed() and not selflag:
3037 tagged_type.SetName(self.name)
3038 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
3041 if ident and self.IsNamed() and not tagflag and not selflag:
3042 nm = ident + '/' + self.name
3045 elif self.IsNamed():
3047 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
3048 if not ident: # Assignment
3049 ectx.eth_reg_assign(nm, self)
3050 if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx):
3051 ectx.eth_reg_type(nm, self)
3052 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
3053 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
3054 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
3055 if ectx.conform.check_item('SET_TYPE', nm):
3056 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
3058 ectx.eth_reg_type(nm, self) # new type
3060 elif ectx.conform.check_item('SET_TYPE', nm):
3061 trnm = ectx.conform.use_item('SET_TYPE', nm)
3062 elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx):
3063 ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints
3068 ectx.eth_reg_type(nm, self)
3070 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
3071 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
3072 ectx.eth_reg_assign(vnm, self, virt=True)
3073 ectx.eth_reg_type(vnm, self)
3074 self.eth_reg_sub(vnm, ectx)
3075 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
3076 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
3077 if ident and not tagflag:
3078 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
3079 if ectx.conform.check_item('SET_TYPE', nm):
3080 virtual_tr.eth_reg_sub(nm, ectx)
3082 self.eth_reg_sub(nm, ectx)
3084 def eth_get_size_constr(self, ectx):
3085 (minv, maxv, ext) = ('MIN', 'MAX', False)
3086 if self.HasSizeConstraint():
3087 if self.constr.IsSize():
3088 (minv, maxv, ext) = self.constr.GetSize(ectx)
3089 if (self.constr.type == 'Intersection'):
3090 if self.constr.subtype[0].IsSize():
3091 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
3092 elif self.constr.subtype[1].IsSize():
3093 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
3094 if minv == 'MIN': minv = 'NO_BOUND'
3095 if maxv == 'MAX': maxv = 'NO_BOUND'
3096 if (ext): ext = 'TRUE'
3098 return (minv, maxv, ext)
3100 def eth_get_value_constr(self, ectx):
3101 (minv, maxv, ext) = ('MIN', 'MAX', False)
3102 if self.HasValueConstraint():
3103 (minv, maxv, ext) = self.constr.GetValue(ectx)
3104 if minv == 'MIN': minv = 'NO_BOUND'
3105 if maxv == 'MAX': maxv = 'NO_BOUND'
3106 if str(minv).isdigit(): minv += 'U'
3107 if str(maxv).isdigit(): maxv += 'U'
3108 if (ext): ext = 'TRUE'
3110 return (minv, maxv, ext)
3112 def eth_get_alphabet_constr(self, ectx):
3113 (alph, alphlen) = ('NULL', '0')
3114 if self.HasPermAlph():
3115 alph = self.constr.GetPermAlph(ectx)
3118 if (alph != 'NULL'):
3119 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
3120 alphlen = str(len(alph) - 2)
3122 alphlen = 'strlen(%s)' % (alph)
3123 return (alph, alphlen)
3125 def eth_type_vals(self, tname, ectx):
3126 if self.eth_has_vals():
3127 print "#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)
3128 print self.str_depth(1)
3131 def eth_type_enum(self, tname, ectx):
3132 if self.eth_has_enum(tname, ectx):
3133 print "#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)
3134 print self.str_depth(1)
3137 def eth_type_default_table(self, ectx, tname):
3140 def eth_type_default_body(self, ectx):
3141 print "#Unhandled eth_type_default_body() in %s" % (self.type)
3142 print self.str_depth(1)
3145 def eth_type_default_pars(self, ectx, tname):
3152 'OFFSET' : 'offset',
3154 'HF_INDEX' : 'hf_index',
3156 'IMPLICIT_TAG' : 'implicit_tag',
3158 if (ectx.eth_type[tname]['tree']):
3159 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
3160 if (ectx.merge_modules):
3163 pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
3166 def eth_type_fn(self, proto, tname, ectx):
3167 body = self.eth_type_default_body(ectx, tname)
3168 pars = self.eth_type_default_pars(ectx, tname)
3169 if ectx.conform.check_item('FN_PARS', tname):
3170 pars.update(ectx.conform.use_item('FN_PARS', tname))
3171 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
3172 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
3173 pars['DEFAULT_BODY'] = body
3175 for k in list(pars.keys()):
3177 pars[k] = pars[k] % pars
3179 raise sys.exc_info()[0], "%s\n%s" % (str(pars), sys.exc_info()[1])
3181 out += self.eth_type_default_table(ectx, tname) % pars
3182 out += ectx.eth_type_fn_hdr(tname)
3183 out += ectx.eth_type_fn_body(tname, body, pars=pars)
3184 out += ectx.eth_type_fn_ftr(tname)
3187 #--- Value --------------------------------------------------------------------
3189 def __init__(self,*args, **kw) :
3191 Node.__init__ (self,*args, **kw)
3193 def SetName(self, name) :
3196 def to_str(self, ectx):
3197 return str(self.val)
3202 def fld_obj_repr(self, ectx):
3203 return self.to_str(ectx)
3205 #--- Value_Ref -----------------------------------------------------------------
3206 class Value_Ref (Value):
3207 def to_str(self, ectx):
3208 return asn2c(self.val)
3210 #--- ObjectClass ---------------------------------------------------------------------
3211 class ObjectClass (Node):
3212 def __init__(self,*args, **kw) :
3214 Node.__init__ (self,*args, **kw)
3216 def SetName(self, name):
3218 add_class_ident(self.name)
3220 def eth_reg(self, ident, ectx):
3221 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
3222 ectx.eth_reg_objectclass(self.name, self)
3224 #--- Class_Ref -----------------------------------------------------------------
3225 class Class_Ref (ObjectClass):
3228 #--- ObjectClassDefn ---------------------------------------------------------------------
3229 class ObjectClassDefn (ObjectClass):
3230 def reg_types(self):
3231 for fld in self.fields:
3232 repr = fld.fld_repr()
3233 set_type_to_class(self.name, repr[0], repr[1:])
3236 #--- Tag ---------------------------------------------------------------
3238 def to_python (self, ctx):
3239 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
3242 self.typ.to_python (ctx))
3243 def IsImplicit(self, ectx):
3244 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
3246 def GetTag(self, ectx):
3248 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
3249 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
3250 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
3251 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
3252 return (tc, self.num)
3254 def eth_tname(self):
3256 if (self.cls == 'UNIVERSAL'): n = 'U'
3257 elif (self.cls == 'APPLICATION'): n = 'A'
3258 elif (self.cls == 'CONTEXT'): n = 'C'
3259 elif (self.cls == 'PRIVATE'): n = 'P'
3260 return n + str(self.num)
3262 #--- Constraint ---------------------------------------------------------------
3263 class Constraint (Node):
3264 def to_python (self, ctx):
3265 print "Ignoring constraint:", self.type
3266 return self.subtype.typ.to_python (ctx)
3268 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
3270 def eth_tname(self):
3271 return '#' + self.type + '_' + str(id(self))
3274 return (self.type == 'Size' and self.subtype.IsValue()) \
3275 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
3277 def GetSize(self, ectx):
3278 (minv, maxv, ext) = ('MIN', 'MAX', False)
3280 if self.type == 'Size':
3281 (minv, maxv, ext) = self.subtype.GetValue(ectx)
3282 elif self.type == 'Intersection':
3283 if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
3284 (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
3285 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
3286 (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
3287 return (minv, maxv, ext)
3290 return self.type == 'SingleValue' \
3291 or self.type == 'ValueRange' \
3292 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
3293 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
3295 def GetValue(self, ectx):
3296 (minv, maxv, ext) = ('MIN', 'MAX', False)
3298 if self.type == 'SingleValue':
3299 minv = ectx.value_get_eth(self.subtype)
3300 maxv = ectx.value_get_eth(self.subtype)
3301 ext = hasattr(self, 'ext') and self.ext
3302 elif self.type == 'ValueRange':
3303 minv = ectx.value_get_eth(self.subtype[0])
3304 maxv = ectx.value_get_eth(self.subtype[1])
3305 ext = hasattr(self, 'ext') and self.ext
3306 elif self.type == 'Intersection':
3307 if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
3308 (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
3309 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
3310 (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
3311 elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
3312 v0 = self.subtype[0].GetValue(ectx)
3313 v1 = self.subtype[1].GetValue(ectx)
3314 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
3315 elif self.type == 'Union':
3316 if self.subtype[0].IsValue() and self.subtype[1].IsValue():
3317 v0 = self.subtype[0].GetValue(ectx)
3318 v1 = self.subtype[1].GetValue(ectx)
3319 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
3320 return (minv, maxv, ext)
3322 def IsAlphabet(self):
3323 return self.type == 'SingleValue' \
3324 or self.type == 'ValueRange' \
3325 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
3326 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
3328 def GetAlphabet(self, ectx):
3330 if self.IsAlphabet():
3331 if self.type == 'SingleValue':
3332 alph = ectx.value_get_eth(self.subtype)
3333 elif self.type == 'ValueRange':
3334 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
3335 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
3337 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
3340 elif self.type == 'Union':
3341 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
3342 a0 = self.subtype[0].GetAlphabet(ectx)
3343 a1 = self.subtype[1].GetAlphabet(ectx)
3344 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
3345 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
3346 alph = '"' + a0[1:-1] + a1[1:-1] + '"'
3348 alph = a0 + ' ' + a1
3351 def IsPermAlph(self):
3352 return self.type == 'From' and self.subtype.IsAlphabet() \
3353 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
3355 def GetPermAlph(self, ectx):
3357 if self.IsPermAlph():
3358 if self.type == 'From':
3359 alph = self.subtype.GetAlphabet(ectx)
3360 elif self.type == 'Intersection':
3361 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
3362 alph = self.subtype[0].GetPermAlph(ectx)
3363 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
3364 alph = self.subtype[1].GetPermAlph(ectx)
3367 def IsContents(self):
3368 return self.type == 'Contents' \
3369 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
3371 def GetContents(self, ectx):
3373 if self.IsContents():
3374 if self.type == 'Contents':
3375 if self.subtype.type == 'Type_Ref':
3376 contents = self.subtype.val
3377 elif self.type == 'Intersection':
3378 if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
3379 contents = self.subtype[0].GetContents(ectx)
3380 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
3381 contents = self.subtype[1].GetContents(ectx)
3384 def IsNegativ(self):
3386 return isinstance(sval, str) and (sval[0] == '-')
3387 if self.type == 'SingleValue':
3388 return is_neg(self.subtype)
3389 elif self.type == 'ValueRange':
3390 if self.subtype[0] == 'MIN': return True
3391 return is_neg(self.subtype[0])
3394 def eth_constrname(self):
3396 if isinstance(val, Value_Ref):
3397 return asn2c(val.val)
3400 return 'M' + str(-int(val))
3403 except (ValueError, TypeError):
3404 return asn2c(str(val))
3407 if hasattr(self, 'ext') and self.ext:
3409 if self.type == 'SingleValue':
3410 return int2str(self.subtype) + ext
3411 elif self.type == 'ValueRange':
3412 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
3413 elif self.type == 'Size':
3414 return 'SIZE_' + self.subtype.eth_constrname() + ext
3416 return 'CONSTR' + str(id(self)) + ext
3419 class Module (Node):
3420 def to_python (self, ctx):
3421 ctx.tag_def = self.tag_def.dfl_tag
3423 %s""" % (self.ident, self.body.to_python (ctx))
3426 return self.ident.val
3428 def get_proto(self, ectx):
3432 prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name())
3435 def to_eth(self, ectx):
3436 ectx.tags_def = 'EXPLICIT' # default = explicit
3437 ectx.proto = self.get_proto(ectx)
3438 ectx.tag_def = self.tag_def.dfl_tag
3439 ectx.eth_reg_module(self)
3440 self.body.to_eth(ectx)
3442 class Module_Body (Node):
3443 def to_python (self, ctx):
3444 # XXX handle exports, imports.
3445 l = [x.to_python (ctx) for x in self.assign_list]
3446 l = [a for a in l if a != '']
3447 return "\n".join (l)
3449 def to_eth(self, ectx):
3451 ectx.eth_exports(self.exports)
3453 for i in self.imports:
3455 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
3456 ectx.eth_module_dep_add(ectx.Module(), mod)
3457 for s in i.symbol_list:
3458 if isinstance(s, Type_Ref):
3459 ectx.eth_import_type(s.val, mod, proto)
3460 elif isinstance(s, Value_Ref):
3461 ectx.eth_import_value(s.val, mod, proto)
3462 elif isinstance(s, Class_Ref):
3463 ectx.eth_import_class(s.val, mod, proto)
3465 msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
3466 warnings.warn_explicit(msg, UserWarning, '', 0)
3468 for a in self.assign_list:
3471 class Default_Tags (Node):
3472 def to_python (self, ctx): # not to be used directly
3475 # XXX should just calculate dependencies as we go along.
3476 def calc_dependencies (node, dict, trace = 0):
3477 if not hasattr (node, '__dict__'):
3478 if trace: print "#returning, node=", node
3480 if isinstance (node, Type_Ref):
3482 if trace: print "#Setting", node.val
3484 for (a, val) in list(node.__dict__.items ()):
3485 if trace: print "# Testing node ", node, "attr", a, " val", val
3488 elif isinstance (val, Node):
3489 calc_dependencies (val, dict, trace)
3490 elif isinstance (val, type ([])):
3492 calc_dependencies (v, dict, trace)
3495 class Type_Assign (Node):
3496 def __init__ (self, *args, **kw):
3497 Node.__init__ (self, *args, **kw)
3498 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3499 to_test = self.val.typ
3502 if isinstance (to_test, SequenceType):
3503 to_test.sequence_name = self.name.name
3505 def to_python (self, ctx):
3507 calc_dependencies (self.val, dep_dict, 0)
3508 depend_list = list(dep_dict.keys ())
3509 return ctx.register_assignment (self.name.name,
3510 self.val.to_python (ctx),
3513 class PyQuote (Node):
3514 def to_python (self, ctx):
3515 return ctx.register_pyquote (self.val)
3517 #--- Type_Ref -----------------------------------------------------------------
3518 class Type_Ref (Type):
3519 def to_python (self, ctx):
3522 def eth_reg_sub(self, ident, ectx):
3523 ectx.eth_dep_add(ident, self.val)
3525 def eth_tname(self):
3526 if self.HasSizeConstraint():
3527 return asn2c(self.val) + '_' + self.constr.eth_constrname()
3529 return asn2c(self.val)
3531 def tr_need_own_fn(self, ectx):
3532 return ectx.Per() and self.HasSizeConstraint()
3534 def fld_obj_repr(self, ectx):
3537 def get_components(self, ectx):
3538 if self.val not in ectx.type or ectx.type[self.val]['import']:
3539 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
3540 warnings.warn_explicit(msg, UserWarning, '', 0)
3543 return ectx.type[self.val]['val'].get_components(ectx)
3545 def GetTTag(self, ectx):
3546 #print "GetTTag(%s)\n" % self.val;
3547 if (ectx.type[self.val]['import']):
3548 if 'ttag' not in ectx.type[self.val]:
3549 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
3550 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
3551 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
3552 warnings.warn_explicit(msg, UserWarning, '', 0)
3553 ttag = ('-1/*imported*/', '-1/*imported*/')
3554 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
3555 return ectx.type[self.val]['ttag']
3557 return ectx.type[self.val]['val'].GetTag(ectx)
3559 def IndetermTag(self, ectx):
3560 if (ectx.type[self.val]['import']):
3563 return ectx.type[self.val]['val'].IndetermTag(ectx)
3565 def eth_type_default_pars(self, ectx, tname):
3567 pars = Type.eth_type_default_pars(self, ectx, tname)
3570 t = ectx.type[self.val]['ethname']
3571 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3572 pars['TYPE_REF_TNAME'] = t
3573 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3574 if self.HasSizeConstraint():
3575 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3578 def eth_type_default_body(self, ectx, tname):
3580 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3581 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3583 if self.HasSizeConstraint():
3584 body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset',
3585 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3586 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3588 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3589 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3591 body = '#error Can not decode %s' % (tname)
3594 #--- SelectionType ------------------------------------------------------------
3595 class SelectionType (Type):
3596 def to_python (self, ctx):
3599 def sel_of_typeref(self):
3600 return self.typ.type == 'Type_Ref'
3602 def eth_reg_sub(self, ident, ectx):
3603 if not self.sel_of_typeref():
3606 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
3607 ectx.eth_dep_add(ident, self.seltype)
3609 def eth_ftype(self, ectx):
3610 (ftype, display) = ('FT_NONE', 'BASE_NONE')
3611 if self.sel_of_typeref() and not ectx.type[self.seltype]['import']:
3612 (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx)
3613 return (ftype, display)
3615 def GetTTag(self, ectx):
3616 #print "GetTTag(%s)\n" % self.seltype;
3617 if (ectx.type[self.seltype]['import']):
3618 if 'ttag' not in ectx.type[self.seltype]:
3619 if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
3620 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
3621 warnings.warn_explicit(msg, UserWarning, '', 0)
3622 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
3623 return ectx.type[self.seltype]['ttag']
3625 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
3627 def eth_type_default_pars(self, ectx, tname):
3628 pars = Type.eth_type_default_pars(self, ectx, tname)
3629 if self.sel_of_typeref():
3630 t = ectx.type[self.seltype]['ethname']
3631 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3632 pars['TYPE_REF_TNAME'] = t
3633 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3636 def eth_type_default_body(self, ectx, tname):
3637 if not self.sel_of_typeref():
3638 body = '#error Can not decode %s' % (tname)
3640 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3641 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3643 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3644 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3646 body = '#error Can not decode %s' % (tname)
3649 #--- TaggedType -----------------------------------------------------------------
3650 class TaggedType (Type):
3651 def eth_tname(self):
3653 for i in range(self.tstrip, len(self.val.tags)):
3654 tn += self.val.tags[i].eth_tname()
3656 tn += self.val.eth_tname()
3659 def eth_set_val_name(self, ident, val_name, ectx):
3660 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3661 self.val_name = val_name
3662 ectx.eth_dep_add(ident, self.val_name)
3664 def eth_reg_sub(self, ident, ectx):
3665 self.val_name = ident + '/' + '_untag'
3666 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
3668 def GetTTag(self, ectx):
3669 #print "GetTTag(%s)\n" % self.seltype;
3670 return self.GetTag(ectx)
3672 def eth_ftype(self, ectx):
3673 return self.val.eth_ftype(ectx)
3675 def eth_type_default_pars(self, ectx, tname):
3676 pars = Type.eth_type_default_pars(self, ectx, tname)
3677 t = ectx.type[self.val_name]['ethname']
3678 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3679 pars['TYPE_REF_TNAME'] = t
3680 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3681 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
3682 if self.HasImplicitTag(ectx):
3683 pars['TAG_IMPL'] = 'TRUE'
3685 pars['TAG_IMPL'] = 'FALSE'
3688 def eth_type_default_body(self, ectx, tname):
3690 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
3691 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3692 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
3694 body = '#error Can not decode %s' % (tname)
3697 #--- SqType -----------------------------------------------------------
3698 class SqType (Type):
3699 def out_item(self, f, val, optional, ext, ectx):
3700 ef = ectx.field[f]['ethname']
3701 t = ectx.eth_hf[ef]['ethtype']
3703 if (ectx.Ber() and ectx.field[f]['impl']):
3706 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
3707 #print val.str_depth(1)
3710 opt = 'BER_FLAGS_OPTIONAL'
3711 if (not val.HasOwnTag()):
3712 if (opt): opt += '|'
3713 opt += 'BER_FLAGS_NOOWNTAG'
3714 elif (val.HasImplicitTag(ectx)):
3715 if (opt): opt += '|'
3716 opt += 'BER_FLAGS_IMPLTAG'
3717 if (val.IndetermTag(ectx)):
3718 if (opt): opt += '|'
3719 opt += 'BER_FLAGS_NOTCHKTAG'
3720 if (not opt): opt = '0'
3723 opt = 'ASN1_OPTIONAL'
3725 opt = 'ASN1_NOT_OPTIONAL'
3727 (tc, tn) = val.GetTag(ectx)
3728 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3729 % ('&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
3731 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
3732 % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
3737 #--- SeqType -----------------------------------------------------------
3738 class SeqType (SqType):
3740 def need_components(self):
3741 lst = self.elt_list[:]
3742 if hasattr(self, 'ext_list'):
3743 lst.extend(self.ext_list)
3744 if hasattr(self, 'elt_list2'):
3745 lst.extend(self.elt_list2)
3747 if e.type == 'components_of':
3751 def expand_components(self, ectx):
3752 while self.need_components():
3753 for i in range(len(self.elt_list)):
3754 if self.elt_list[i].type == 'components_of':
3755 comp = self.elt_list[i].typ.get_components(ectx)
3756 self.elt_list[i:i+1] = comp
3758 if hasattr(self, 'ext_list'):
3759 for i in range(len(self.ext_list)):
3760 if self.ext_list[i].type == 'components_of':
3761 comp = self.ext_list[i].typ.get_components(ectx)
3762 self.ext_list[i:i+1] = comp
3764 if hasattr(self, 'elt_list2'):
3765 for i in range(len(self.elt_list2)):
3766 if self.elt_list2[i].type == 'components_of':
3767 comp = self.elt_list2[i].typ.get_components(ectx)
3768 self.elt_list2[i:i+1] = comp
3771 def get_components(self, ectx):
3772 lst = self.elt_list[:]
3773 if hasattr(self, 'elt_list2'):
3774 lst.extend(self.elt_list2)
3777 def eth_type_default_table(self, ectx, tname):
3778 #print "eth_type_default_table(tname='%s')" % (tname)
3779 fname = ectx.eth_type[tname]['ref'][0]
3780 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
3781 if hasattr(self, 'ext_list'):
3782 ext = 'ASN1_EXTENSION_ROOT'
3784 ext = 'ASN1_NO_EXTENSIONS'
3785 for e in (self.elt_list):
3786 f = fname + '/' + e.val.name
3787 table += self.out_item(f, e.val, e.optional, ext, ectx)
3788 if hasattr(self, 'ext_list'):
3789 for e in (self.ext_list):
3790 f = fname + '/' + e.val.name
3791 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
3792 if hasattr(self, 'elt_list2'):
3793 for e in (self.elt_list2):
3794 f = fname + '/' + e.val.name
3795 table += self.out_item(f, e.val, e.optional, ext, ectx)
3797 table += " { NULL, 0, 0, 0, NULL }\n};\n"
3799 table += " { NULL, 0, 0, NULL }\n};\n"
3802 #--- SeqOfType -----------------------------------------------------------
3803 class SeqOfType (SqType):
3804 def eth_type_default_table(self, ectx, tname):
3805 #print "eth_type_default_table(tname='%s')" % (tname)
3806 fname = ectx.eth_type[tname]['ref'][0]
3807 if self.val.IsNamed ():
3808 f = fname + '/' + self.val.name
3810 f = fname + '/' + '_item'
3811 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
3812 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
3816 #--- SequenceOfType -----------------------------------------------------------
3817 class SequenceOfType (SeqOfType):
3818 def to_python (self, ctx):
3819 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3820 # or '' + (1,) for optional
3822 if self.size_constr != None:
3823 print "#Ignoring size constraint:", self.size_constr.subtype
3824 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
3825 self.val.to_python (ctx),
3828 def eth_reg_sub(self, ident, ectx):
3830 if not self.val.IsNamed ():
3831 itmnm += '/' + '_item'
3832 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
3834 def eth_tname(self):
3835 if self.val.type != 'Type_Ref':
3836 return '#' + self.type + '_' + str(id(self))
3837 if not self.HasConstraint():
3838 return "SEQUENCE_OF_" + self.val.eth_tname()
3839 elif self.constr.IsSize():
3840 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
3842 return '#' + self.type + '_' + str(id(self))
3844 def eth_ftype(self, ectx):
3845 return ('FT_UINT32', 'BASE_DEC')
3847 def eth_need_tree(self):
3850 def GetTTag(self, ectx):
3851 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
3853 def eth_type_default_pars(self, ectx, tname):
3854 pars = Type.eth_type_default_pars(self, ectx, tname)
3855 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3856 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
3859 def eth_type_default_body(self, ectx, tname):
3861 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
3862 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3863 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3864 elif (ectx.Per() and not self.HasConstraint()):
3865 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
3866 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3867 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3868 elif (ectx.Per() and self.constr.type == 'Size'):
3869 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
3870 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3871 ('%(ETT_INDEX)s', '%(TABLE)s',),
3872 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3874 body = '#error Can not decode %s' % (tname)
3878 #--- SetOfType ----------------------------------------------------------------
3879 class SetOfType (SeqOfType):
3880 def eth_reg_sub(self, ident, ectx):
3882 if not self.val.IsNamed ():
3883 itmnm += '/' + '_item'
3884 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
3886 def eth_tname(self):
3887 if self.val.type != 'Type_Ref':
3888 return '#' + self.type + '_' + str(id(self))
3889 if not self.HasConstraint():
3890 return "SET_OF_" + self.val.eth_tname()
3891 elif self.constr.IsSize():
3892 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
3894 return '#' + self.type + '_' + str(id(self))
3896 def eth_ftype(self, ectx):
3897 return ('FT_UINT32', 'BASE_DEC')
3899 def eth_need_tree(self):
3902 def GetTTag(self, ectx):
3903 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
3905 def eth_type_default_pars(self, ectx, tname):
3906 pars = Type.eth_type_default_pars(self, ectx, tname)
3907 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3908 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
3911 def eth_type_default_body(self, ectx, tname):
3913 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
3914 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3915 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3916 elif (ectx.Per() and not self.HasConstraint()):
3917 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
3918 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3919 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3920 elif (ectx.Per() and self.constr.type == 'Size'):
3921 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
3922 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3923 ('%(ETT_INDEX)s', '%(TABLE)s',),
3924 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3926 body = '#error Can not decode %s' % (tname)
3929 def mk_tag_str (ctx, cls, typ, num):
3931 # XXX should do conversion to int earlier!
3934 if typ == 'DEFAULT':
3936 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
3938 #--- SequenceType -------------------------------------------------------------
3939 class SequenceType (SeqType):
3940 def to_python (self, ctx):
3941 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3942 # or '' + (1,) for optional
3943 # XXX should also collect names for SEQUENCE inside SEQUENCE or
3944 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
3945 # from? for others, element or arm name would be fine)
3946 seq_name = getattr (self, 'sequence_name', None)
3947 if seq_name == None:
3950 seq_name = "'" + seq_name + "'"
3951 if 'ext_list' in self.__dict__:
3952 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
3953 self.elts_to_py (self.elt_list, ctx),
3954 self.elts_to_py (self.ext_list, ctx), seq_name)
3956 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
3957 self.elts_to_py (self.elt_list, ctx), seq_name)
3958 def elts_to_py (self, list, ctx):
3959 # we have elt_type, val= named_type, maybe default=, optional=
3960 # named_type node: either ident = or typ =
3961 # need to dismember these in order to generate Python output syntax.
3964 assert (e.type == 'elt_type')
3966 optflag = e.optional
3967 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
3968 assert (nt.type == 'named_type')
3971 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
3972 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
3973 nt.typ.tag.tag_typ,nt.typ.tag.num)
3977 return "('%s',%s,%s,%d)" % (identstr, tagstr,
3978 nt.typ.to_python (ctx), optflag)
3979 indentstr = ",\n" + ctx.spaces ()
3980 rv = indentstr.join ([elt_to_py (e) for e in list])
3984 def eth_reg_sub(self, ident, ectx, components_available=False):
3985 if self.need_components():
3986 if components_available:
3987 self.expand_components(ectx)
3989 ectx.eth_comp_req(ident)
3991 for e in (self.elt_list):
3992 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3993 if hasattr(self, 'ext_list'):
3994 for e in (self.ext_list):
3995 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3996 if hasattr(self, 'elt_list2'):
3997 for e in (self.elt_list2):
3998 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4000 def eth_need_tree(self):
4003 def GetTTag(self, ectx):
4004 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4006 def eth_type_default_pars(self, ectx, tname):
4007 pars = Type.eth_type_default_pars(self, ectx, tname)
4008 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4011 def eth_type_default_body(self, ectx, tname):
4013 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4014 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4015 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4017 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4018 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4019 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4021 body = '#error Can not decode %s' % (tname)
4024 #--- SetType ------------------------------------------------------------------
4025 class SetType(SeqType):
4027 def eth_reg_sub(self, ident, ectx, components_available=False):
4028 if self.need_components():
4029 if components_available:
4030 self.expand_components(ectx)
4032 ectx.eth_comp_req(ident)
4034 for e in (self.elt_list):
4035 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4036 if hasattr(self, 'ext_list'):
4037 for e in (self.ext_list):
4038 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4040 def eth_need_tree(self):
4043 def GetTTag(self, ectx):
4044 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4046 def eth_type_default_pars(self, ectx, tname):
4047 pars = Type.eth_type_default_pars(self, ectx, tname)
4048 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4051 def eth_type_default_body(self, ectx, tname):
4053 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4054 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4055 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4057 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4058 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4059 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4061 body = '#error Can not decode %s' % (tname)
4064 #--- ChoiceType ---------------------------------------------------------------
4065 class ChoiceType (Type):
4066 def to_python (self, ctx):
4067 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4068 # or '' + (1,) for optional
4069 if 'ext_list' in self.__dict__:
4070 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
4071 self.elts_to_py (self.elt_list, ctx),
4072 self.elts_to_py (self.ext_list, ctx))
4074 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
4075 def elts_to_py (self, list, ctx):
4078 assert (nt.type == 'named_type')
4080 if hasattr (nt, 'ident'):
4083 if hasattr (nt.typ, 'val'):
4084 identstr = nt.typ.val # XXX, making up name
4085 elif hasattr (nt.typ, 'name'):
4086 identstr = nt.typ.name
4088 identstr = ctx.make_new_name ()
4090 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4091 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4092 nt.typ.tag.tag_typ,nt.typ.tag.num)
4096 return "('%s',%s,%s)" % (identstr, tagstr,
4097 nt.typ.to_python (ctx))
4098 indentstr = ",\n" + ctx.spaces ()
4099 rv = indentstr.join ([elt_to_py (e) for e in list])
4103 def eth_reg_sub(self, ident, ectx):
4104 #print "eth_reg_sub(ident='%s')" % (ident)
4105 for e in (self.elt_list):
4106 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4107 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4108 ectx.eth_sel_req(ident, e.name)
4109 if hasattr(self, 'ext_list'):
4110 for e in (self.ext_list):
4111 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4112 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4113 ectx.eth_sel_req(ident, e.name)
4115 def sel_item(self, ident, sel, ectx):
4116 lst = self.elt_list[:]
4117 if hasattr(self, 'ext_list'):
4118 lst.extend(self.ext_list)
4120 for e in (self.elt_list):
4121 if e.IsNamed() and (e.name == sel):
4125 print "#CHOICE %s does not contain item %s" % (ident, sel)
4128 def sel_req(self, ident, sel, ectx):
4129 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4130 ee = self.sel_item(ident, sel, ectx)
4132 ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
4134 def eth_ftype(self, ectx):
4135 return ('FT_UINT32', 'BASE_DEC')
4137 def eth_ftype_sel(self, sel, ectx):
4138 ee = self.sel_item('', sel, ectx)
4140 return ee.eth_ftype(ectx)
4142 return ('FT_NONE', 'BASE_NONE')
4144 def eth_strings(self):
4147 def eth_need_tree(self):
4150 def eth_has_vals(self):
4153 def GetTTag(self, ectx):
4155 cls = 'BER_CLASS_ANY/*choice*/'
4156 #if hasattr(self, 'ext_list'):
4157 # lst.extend(self.ext_list)
4159 # cls = lst[0].GetTag(ectx)[0]
4161 # if (e.GetTag(ectx)[0] != cls):
4162 # cls = '-1/*choice*/'
4163 return (cls, '-1/*choice*/')
4165 def GetTTagSel(self, sel, ectx):
4166 ee = self.sel_item('', sel, ectx)
4168 return ee.GetTag(ectx)
4170 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4172 def IndetermTag(self, ectx):
4173 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4174 return not self.HasOwnTag()
4176 def detect_tagval(self, ectx):
4178 lst = self.elt_list[:]
4179 if hasattr(self, 'ext_list'):
4180 lst.extend(self.ext_list)
4181 if (len(lst) > 0) and (not ectx.Per() or lst[0].HasOwnTag()):
4182 t = lst[0].GetTag(ectx)[0]
4187 if (t == 'BER_CLASS_UNI'):
4190 if not ectx.Per() or e.HasOwnTag():
4191 tt = e.GetTag(ectx)[0]
4199 def get_vals(self, ectx):
4200 tagval = self.detect_tagval(ectx)
4203 for e in (self.elt_list):
4204 if (tagval): val = e.GetTag(ectx)[1]
4205 else: val = str(cnt)
4206 vals.append((val, e.name))
4208 if hasattr(self, 'ext_list'):
4209 for e in (self.ext_list):
4210 if (tagval): val = e.GetTag(ectx)[1]
4211 else: val = str(cnt)
4212 vals.append((val, e.name))
4216 def eth_type_vals(self, tname, ectx):
4218 vals = self.get_vals(ectx)
4219 out += ectx.eth_vals(tname, vals)
4222 def reg_enum_vals(self, tname, ectx):
4223 vals = self.get_vals(ectx)
4224 for (val, id) in vals:
4225 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4227 def eth_type_enum(self, tname, ectx):
4229 vals = self.get_vals(ectx)
4230 out += ectx.eth_enum(tname, vals)
4233 def eth_type_default_pars(self, ectx, tname):
4234 pars = Type.eth_type_default_pars(self, ectx, tname)
4235 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4238 def eth_type_default_table(self, ectx, tname):
4239 def out_item(val, e, ext, ectx):
4240 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
4242 vval = ectx.eth_enum_item(tname, e.name)
4245 f = fname + '/' + e.name
4246 ef = ectx.field[f]['ethname']
4247 t = ectx.eth_hf[ef]['ethtype']
4249 if (ectx.field[f]['impl']):
4253 if (not e.HasOwnTag()):
4254 opt = 'BER_FLAGS_NOOWNTAG'
4255 elif (e.HasImplicitTag(ectx)):
4256 if (opt): opt += '|'
4257 opt += 'BER_FLAGS_IMPLTAG'
4258 if (not opt): opt = '0'
4260 (tc, tn) = e.GetTag(ectx)
4261 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4262 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
4264 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4265 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
4270 #print "eth_type_default_table(tname='%s')" % (tname)
4271 fname = ectx.eth_type[tname]['ref'][0]
4272 tagval = self.detect_tagval(ectx)
4273 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4275 if hasattr(self, 'ext_list'):
4276 ext = 'ASN1_EXTENSION_ROOT'
4278 ext = 'ASN1_NO_EXTENSIONS'
4279 for e in (self.elt_list):
4280 if (tagval): val = e.GetTag(ectx)[1]
4281 else: val = str(cnt)
4282 table += out_item(val, e, ext, ectx)
4284 if hasattr(self, 'ext_list'):
4285 for e in (self.ext_list):
4286 if (tagval): val = e.GetTag(ectx)[1]
4287 else: val = str(cnt)
4288 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4291 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4293 table += " { 0, NULL, 0, NULL }\n};\n"
4296 def eth_type_default_body(self, ectx, tname):
4298 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4299 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4300 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4303 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4304 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4305 ('%(ETT_INDEX)s', '%(TABLE)s',),
4308 body = '#error Can not decode %s' % (tname)
4311 #--- ChoiceValue ----------------------------------------------------
4312 class ChoiceValue (Value):
4313 def to_str(self, ectx):
4314 return self.val.to_str(ectx)
4316 def fld_obj_eq(self, other):
4317 return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
4319 #--- EnumeratedType -----------------------------------------------------------
4320 class EnumeratedType (Type):
4321 def to_python (self, ctx):
4322 def strify_one (named_num):
4323 return "%s=%s" % (named_num.ident, named_num.val)
4324 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
4326 def eth_ftype(self, ectx):
4327 return ('FT_UINT32', 'BASE_DEC')
4329 def eth_strings(self):
4332 def eth_has_vals(self):
4335 def GetTTag(self, ectx):
4336 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4338 def get_vals_etc(self, ectx):
4346 for e in (self.val):
4347 if e.type == 'NamedNumber':
4348 used[int(e.val)] = True
4349 for e in (self.val):
4350 if e.type == 'NamedNumber':
4353 while lastv in used:
4357 vals.append((val, e.ident))
4358 map_table.append(val)
4362 if self.ext is not None:
4363 for e in (self.ext):
4364 if e.type == 'NamedNumber':
4365 used[int(e.val)] = True
4366 for e in (self.ext):
4367 if e.type == 'NamedNumber':
4370 while lastv in used:
4374 vals.append((val, e.ident))
4375 map_table.append(val)
4380 for i in range(len(map_table)):
4381 need_map = need_map or (map_table[i] != i)
4384 return (vals, root_num, ext_num, map_table)
4386 def eth_type_vals(self, tname, ectx):
4388 vals = self.get_vals_etc(ectx)[0]
4389 out += ectx.eth_vals(tname, vals)
4392 def reg_enum_vals(self, tname, ectx):
4393 vals = self.get_vals_etc(ectx)[0]
4394 for (val, id) in vals:
4395 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4397 def eth_type_enum(self, tname, ectx):
4399 vals = self.get_vals_etc(ectx)[0]
4400 out += ectx.eth_enum(tname, vals)
4403 def eth_type_default_pars(self, ectx, tname):
4404 pars = Type.eth_type_default_pars(self, ectx, tname)
4405 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
4406 if (self.ext != None):
4410 pars['ROOT_NUM'] = str(root_num)
4412 pars['EXT_NUM'] = str(ext_num)
4414 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4416 pars['TABLE'] = 'NULL'
4419 def eth_type_default_table(self, ectx, tname):
4420 if (not ectx.Per()): return ''
4421 map_table = self.get_vals_etc(ectx)[3]
4422 if (map_table == None): return ''
4423 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4424 table += ", ".join([str(v) for v in map_table])
4428 def eth_type_default_body(self, ectx, tname):
4430 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4431 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4434 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
4435 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4436 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4438 body = '#error Can not decode %s' % (tname)
4441 #--- EmbeddedPDVType -----------------------------------------------------------
4442 class EmbeddedPDVType (Type):
4443 def eth_tname(self):
4444 return 'EMBEDDED_PDV'
4446 def eth_ftype(self, ectx):
4447 return ('FT_NONE', 'BASE_NONE')
4449 def GetTTag(self, ectx):
4450 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4452 def eth_type_default_pars(self, ectx, tname):
4453 pars = Type.eth_type_default_pars(self, ectx, tname)
4454 if ectx.default_embedded_pdv_cb:
4455 pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb
4457 pars['TYPE_REF_FN'] = 'NULL'
4460 def eth_type_default_body(self, ectx, tname):
4462 body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset',
4463 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4465 body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset',
4466 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4468 body = '#error Can not decode %s' % (tname)
4471 #--- ExternalType -----------------------------------------------------------
4472 class ExternalType (Type):
4473 def eth_tname(self):
4476 def eth_ftype(self, ectx):
4477 return ('FT_NONE', 'BASE_NONE')
4479 def GetTTag(self, ectx):
4480 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4482 def eth_type_default_pars(self, ectx, tname):
4483 pars = Type.eth_type_default_pars(self, ectx, tname)
4484 if ectx.default_external_type_cb:
4485 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4487 pars['TYPE_REF_FN'] = 'NULL'
4490 def eth_type_default_body(self, ectx, tname):
4492 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4493 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4495 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4496 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4498 body = '#error Can not decode %s' % (tname)
4501 #--- OpenType -----------------------------------------------------------
4502 class OpenType (Type):
4503 def to_python (self, ctx):
4506 def single_type(self):
4507 if (self.HasConstraint() and
4508 self.constr.type == 'Type' and
4509 self.constr.subtype.type == 'Type_Ref'):
4510 return self.constr.subtype.val
4513 def eth_reg_sub(self, ident, ectx):
4514 t = self.single_type()
4516 ectx.eth_dep_add(ident, t)
4518 def eth_tname(self):
4519 t = self.single_type()
4521 return 'OpenType_' + t
4523 return Type.eth_tname(self)
4525 def eth_ftype(self, ectx):
4526 return ('FT_NONE', 'BASE_NONE')
4528 def GetTTag(self, ectx):
4529 return ('BER_CLASS_ANY', '0')
4531 def eth_type_default_pars(self, ectx, tname):
4532 pars = Type.eth_type_default_pars(self, ectx, tname)
4533 pars['FN_VARIANT'] = ectx.default_opentype_variant
4534 t = self.single_type()
4536 t = ectx.type[t]['ethname']
4537 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4538 pars['TYPE_REF_TNAME'] = t
4539 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4541 pars['TYPE_REF_FN'] = 'NULL'
4544 def eth_type_default_body(self, ectx, tname):
4546 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
4547 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4549 body = '#error Can not decode %s' % (tname)
4552 #--- InstanceOfType -----------------------------------------------------------
4553 class InstanceOfType (Type):
4554 def eth_tname(self):
4555 return 'INSTANCE_OF'
4557 def eth_ftype(self, ectx):
4558 return ('FT_NONE', 'BASE_NONE')
4560 def GetTTag(self, ectx):
4561 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4563 def eth_type_default_pars(self, ectx, tname):
4564 pars = Type.eth_type_default_pars(self, ectx, tname)
4565 if ectx.default_external_type_cb:
4566 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4568 pars['TYPE_REF_FN'] = 'NULL'
4571 def eth_type_default_body(self, ectx, tname):
4573 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4574 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4576 body = '#error Can not decode %s' % (tname)
4578 body = '#error Can not decode %s' % (tname)
4581 #--- AnyType -----------------------------------------------------------
4582 class AnyType (Type):
4583 def to_python (self, ctx):
4586 def eth_ftype(self, ectx):
4587 return ('FT_NONE', 'BASE_NONE')
4589 def GetTTag(self, ectx):
4590 return ('BER_CLASS_ANY', '0')
4592 def eth_type_default_body(self, ectx, tname):
4593 body = '#error Can not decode %s' % (tname)
4596 class Literal (Node):
4597 def to_python (self, ctx):
4600 #--- NullType -----------------------------------------------------------------
4601 class NullType (Type):
4602 def to_python (self, ctx):
4605 def eth_tname(self):
4608 def GetTTag(self, ectx):
4609 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
4611 def eth_type_default_body(self, ectx, tname):
4613 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4614 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4616 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4617 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4619 body = '#error Can not decode %s' % (tname)
4622 #--- NullValue ----------------------------------------------------
4623 class NullValue (Value):
4624 def to_str(self, ectx):
4627 #--- RealType -----------------------------------------------------------------
4628 class RealType (Type):
4629 def to_python (self, ctx):
4632 def eth_tname(self):
4635 def GetTTag(self, ectx):
4636 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
4638 def eth_ftype(self, ectx):
4639 return ('FT_DOUBLE', 'BASE_NONE')
4641 def eth_type_default_body(self, ectx, tname):
4643 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4644 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4647 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4648 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4650 body = '#error Can not decode %s' % (tname)
4653 #--- BooleanType --------------------------------------------------------------
4654 class BooleanType (Type):
4655 def to_python (self, ctx):
4656 return 'asn1.BOOLEAN'
4658 def eth_tname(self):
4661 def GetTTag(self, ectx):
4662 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
4664 def eth_ftype(self, ectx):
4665 return ('FT_BOOLEAN', '8')
4667 def eth_type_default_body(self, ectx, tname):
4669 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4670 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
4672 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4673 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4675 body = '#error Can not decode %s' % (tname)
4678 #--- OctetStringType ----------------------------------------------------------
4679 class OctetStringType (Type):
4680 def to_python (self, ctx):
4681 return 'asn1.OCTSTRING'
4683 def eth_tname(self):
4684 if not self.HasConstraint():
4685 return 'OCTET_STRING'
4686 elif self.constr.type == 'Size':
4687 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
4689 return '#' + self.type + '_' + str(id(self))
4691 def eth_ftype(self, ectx):
4692 return ('FT_BYTES', 'BASE_HEX')
4694 def GetTTag(self, ectx):
4695 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
4697 def eth_need_pdu(self, ectx):
4699 if self.HasContentsConstraint():
4700 t = self.constr.GetContents(ectx)
4701 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
4703 'new' : ectx.default_containing_variant == '_pdu_new' }
4706 def eth_type_default_pars(self, ectx, tname):
4707 pars = Type.eth_type_default_pars(self, ectx, tname)
4708 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4709 if self.HasContentsConstraint():
4710 pars['FN_VARIANT'] = ectx.default_containing_variant
4711 t = self.constr.GetContents(ectx)
4713 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
4714 t = ectx.field[t]['ethname']
4715 pars['TYPE_REF_PROTO'] = ''
4716 pars['TYPE_REF_TNAME'] = t
4717 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
4719 t = ectx.type[t]['ethname']
4720 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4721 pars['TYPE_REF_TNAME'] = t
4722 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4724 pars['TYPE_REF_FN'] = 'NULL'
4727 def eth_type_default_body(self, ectx, tname):
4729 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
4730 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4733 if self.HasContentsConstraint():
4734 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
4735 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4736 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
4738 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
4739 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4740 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
4742 body = '#error Can not decode %s' % (tname)
4745 #--- CharacterStringType ------------------------------------------------------
4746 class CharacterStringType (Type):
4747 def eth_tname(self):
4748 if not self.HasConstraint():
4749 return self.eth_tsname()
4750 elif self.constr.type == 'Size':
4751 return self.eth_tsname() + '_' + self.constr.eth_constrname()
4753 return '#' + self.type + '_' + str(id(self))
4755 def eth_ftype(self, ectx):
4756 return ('FT_STRING', 'BASE_NONE')
4758 class RestrictedCharacterStringType (CharacterStringType):
4759 def to_python (self, ctx):
4760 return 'asn1.' + self.eth_tsname()
4762 def GetTTag(self, ectx):
4763 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
4765 def eth_type_default_pars(self, ectx, tname):
4766 pars = Type.eth_type_default_pars(self, ectx, tname)
4767 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4768 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
4769 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
4772 def eth_type_default_body(self, ectx, tname):
4774 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
4775 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
4776 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4778 elif (ectx.Per() and self.HasPermAlph()):
4779 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
4780 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4781 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
4784 if (self.eth_tsname() == 'GeneralString'):
4785 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4786 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4787 elif (self.eth_tsname() == 'GeneralizedTime'):
4788 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
4789 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4790 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4791 elif (self.eth_tsname() == 'UTCTime'):
4792 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
4793 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4794 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4796 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4797 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4798 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4800 body = '#error Can not decode %s' % (tname)
4803 class BMPStringType (RestrictedCharacterStringType):
4804 def eth_tsname(self):
4807 class GeneralStringType (RestrictedCharacterStringType):
4808 def eth_tsname(self):
4809 return 'GeneralString'
4811 class GraphicStringType (RestrictedCharacterStringType):
4812 def eth_tsname(self):
4813 return 'GraphicString'
4815 class IA5StringType (RestrictedCharacterStringType):
4816 def eth_tsname(self):
4819 class NumericStringType (RestrictedCharacterStringType):
4820 def eth_tsname(self):
4821 return 'NumericString'
4823 class PrintableStringType (RestrictedCharacterStringType):
4824 def eth_tsname(self):
4825 return 'PrintableString'
4827 class TeletexStringType (RestrictedCharacterStringType):
4828 def eth_tsname(self):
4829 return 'TeletexString'
4831 class T61StringType (RestrictedCharacterStringType):
4832 def eth_tsname(self):
4834 def GetTTag(self, ectx):
4835 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
4837 class UniversalStringType (RestrictedCharacterStringType):
4838 def eth_tsname(self):
4839 return 'UniversalString'
4841 class UTF8StringType (RestrictedCharacterStringType):
4842 def eth_tsname(self):
4845 class VideotexStringType (RestrictedCharacterStringType):
4846 def eth_tsname(self):
4847 return 'VideotexString'
4849 class VisibleStringType (RestrictedCharacterStringType):
4850 def eth_tsname(self):
4851 return 'VisibleString'
4853 class ISO646StringType (RestrictedCharacterStringType):
4854 def eth_tsname(self):
4855 return 'ISO646String'
4856 def GetTTag(self, ectx):
4857 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
4859 class UnrestrictedCharacterStringType (CharacterStringType):
4860 def to_python (self, ctx):
4861 return 'asn1.UnrestrictedCharacterString'
4862 def eth_tsname(self):
4863 return 'CHARACTER_STRING'
4865 #--- UsefulType ---------------------------------------------------------------
4866 class GeneralizedTime (RestrictedCharacterStringType):
4867 def eth_tsname(self):
4868 return 'GeneralizedTime'
4870 def eth_type_default_body(self, ectx, tname):
4872 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4873 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4876 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4878 class UTCTime (RestrictedCharacterStringType):
4879 def eth_tsname(self):
4882 def eth_type_default_body(self, ectx, tname):
4884 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4885 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4888 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4890 class ObjectDescriptor (RestrictedCharacterStringType):
4891 def eth_tsname(self):
4892 return 'ObjectDescriptor'
4894 def eth_type_default_body(self, ectx, tname):
4896 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4898 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
4899 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4901 body = '#error Can not decode %s' % (tname)
4904 #--- ObjectIdentifierType -----------------------------------------------------
4905 class ObjectIdentifierType (Type):
4906 def to_python (self, ctx):
4907 return 'asn1.OBJECT_IDENTIFIER'
4909 def eth_tname(self):
4910 return 'OBJECT_IDENTIFIER'
4912 def eth_ftype(self, ectx):
4913 return ('FT_OID', 'BASE_NONE')
4915 def GetTTag(self, ectx):
4916 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
4918 def eth_type_default_pars(self, ectx, tname):
4919 pars = Type.eth_type_default_pars(self, ectx, tname)
4920 pars['FN_VARIANT'] = ectx.default_oid_variant
4923 def eth_type_default_body(self, ectx, tname):
4925 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
4926 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4928 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
4929 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4931 body = '#error Can not decode %s' % (tname)
4934 #--- ObjectIdentifierValue ----------------------------------------------------
4935 class ObjectIdentifierValue (Value):
4936 def get_num(self, path, val):
4937 return str(oid_names.get(path + '/' + val, val))
4939 def to_str(self, ectx):
4944 for v in self.comp_list:
4945 if isinstance(v, Node) and (v.type == 'name_and_number'):
4950 vstr = self.get_num(path, v)
4951 if not first and not vstr.isdigit():
4952 vstr = ectx.value_get_val(vstr)
4957 out += ectx.value_get_eth(vstr) + '"'
4967 v = self.comp_list[0]
4968 if isinstance(v, Node) and (v.type == 'name_and_number'):
4973 vstr = self.get_num('', v)
4979 class NamedNumber(Node):
4980 def to_python (self, ctx):
4981 return "('%s',%s)" % (self.ident, self.val)
4983 class NamedNumListBase(Node):
4984 def to_python (self, ctx):
4985 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
4986 [x.to_python (ctx) for x in self.named_list]))
4988 #--- RelativeOIDType ----------------------------------------------------------
4989 class RelativeOIDType (Type):
4991 def eth_tname(self):
4992 return 'RELATIVE_OID'
4994 def eth_ftype(self, ectx):
4995 return ('FT_BYTES', 'BASE_HEX')
4997 def GetTTag(self, ectx):
4998 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5000 def eth_type_default_pars(self, ectx, tname):
5001 pars = Type.eth_type_default_pars(self, ectx, tname)
5002 pars['FN_VARIANT'] = ectx.default_oid_variant
5005 def eth_type_default_body(self, ectx, tname):
5007 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5008 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5010 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5011 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5013 body = '#error Can not decode %s' % (tname)
5017 #--- IntegerType --------------------------------------------------------------
5018 class IntegerType (Type):
5019 def to_python (self, ctx):
5020 return "asn1.INTEGER_class ([%s])" % (",".join (
5021 [x.to_python (ctx) for x in self.named_list]))
5023 def add_named_value(self, ident, val):
5024 e = NamedNumber(ident = ident, val = val)
5025 if not self.named_list:
5026 self.named_list = []
5027 self.named_list.append(e)
5029 def eth_tname(self):
5031 return Type.eth_tname(self)
5032 if not self.HasConstraint():
5034 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
5035 return 'INTEGER' + '_' + self.constr.eth_constrname()
5037 return 'INTEGER' + '_' + self.constr.eth_tname()
5039 def GetTTag(self, ectx):
5040 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5043 def eth_ftype(self, ectx):
5044 if self.HasConstraint():
5045 if not self.constr.IsNegativ():
5046 return ('FT_UINT32', 'BASE_DEC')
5047 return ('FT_INT32', 'BASE_DEC')
5049 def eth_strings(self):
5050 if (self.named_list):
5055 def eth_has_vals(self):
5056 if (self.named_list):
5061 def get_vals(self, ectx):
5063 for e in (self.named_list):
5064 vals.append((int(e.val), e.ident))
5067 def eth_type_vals(self, tname, ectx):
5068 if not self.eth_has_vals(): return ''
5070 vals = self.get_vals(ectx)
5071 out += ectx.eth_vals(tname, vals)
5074 def reg_enum_vals(self, tname, ectx):
5075 vals = self.get_vals(ectx)
5076 for (val, id) in vals:
5077 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
5079 def eth_type_enum(self, tname, ectx):
5080 if not self.eth_has_enum(tname, ectx): return ''
5082 vals = self.get_vals(ectx)
5083 out += ectx.eth_enum(tname, vals)
5086 def eth_type_default_pars(self, ectx, tname):
5087 pars = Type.eth_type_default_pars(self, ectx, tname)
5088 if self.HasValueConstraint():
5089 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
5092 def eth_type_default_body(self, ectx, tname):
5094 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5095 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5097 elif (ectx.Per() and not self.HasValueConstraint()):
5098 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5099 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5100 elif (ectx.Per() and self.HasValueConstraint()):
5101 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5102 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5103 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5105 body = '#error Can not decode %s' % (tname)
5108 #--- BitStringType ------------------------------------------------------------
5109 class BitStringType (Type):
5110 def to_python (self, ctx):
5111 return "asn1.BITSTRING_class ([%s])" % (",".join (
5112 [x.to_python (ctx) for x in self.named_list]))
5114 def eth_tname(self):
5116 return Type.eth_tname(self)
5117 elif not self.HasConstraint():
5119 elif self.constr.IsSize():
5120 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
5122 return '#' + self.type + '_' + str(id(self))
5124 def GetTTag(self, ectx):
5125 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5127 def eth_ftype(self, ectx):
5128 return ('FT_BYTES', 'BASE_HEX')
5130 def eth_need_tree(self):
5131 return self.named_list
5133 def eth_need_pdu(self, ectx):
5135 if self.HasContentsConstraint():
5136 t = self.constr.GetContents(ectx)
5137 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5139 'new' : ectx.default_containing_variant == '_pdu_new' }
5142 def eth_named_bits(self):
5144 if (self.named_list):
5145 for e in (self.named_list):
5146 bits.append((int(e.val), e.ident))
5149 def eth_type_default_pars(self, ectx, tname):
5150 pars = Type.eth_type_default_pars(self, ectx, tname)
5151 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5152 if 'ETT_INDEX' not in pars:
5153 pars['ETT_INDEX'] = '-1'
5154 pars['TABLE'] = 'NULL'
5155 if self.eth_named_bits():
5156 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5157 if self.HasContentsConstraint():
5158 pars['FN_VARIANT'] = ectx.default_containing_variant
5159 t = self.constr.GetContents(ectx)
5161 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5162 t = ectx.field[t]['ethname']
5163 pars['TYPE_REF_PROTO'] = ''
5164 pars['TYPE_REF_TNAME'] = t
5165 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5167 t = ectx.type[t]['ethname']
5168 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5169 pars['TYPE_REF_TNAME'] = t
5170 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5172 pars['TYPE_REF_FN'] = 'NULL'
5175 def eth_type_default_table(self, ectx, tname):
5176 #print "eth_type_default_table(tname='%s')" % (tname)
5178 bits = self.eth_named_bits()
5179 if (bits and ectx.Ber()):
5180 table = ectx.eth_bits(tname, bits)
5183 def eth_type_default_body(self, ectx, tname):
5185 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
5186 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5187 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5190 if self.HasContentsConstraint():
5191 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
5192 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5193 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5195 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
5196 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5197 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s'),))
5199 body = '#error Can not decode %s' % (tname)
5202 #--- BStringValue ------------------------------------------------------------
5221 class BStringValue (Value):
5222 def to_str(self, ectx):
5225 v += '0' * (8 - len(v) % 8)
5227 for i in (range(0, len(v), 4)):
5228 vv += bstring_tab[v[i:i+4]]
5231 #--- HStringValue ------------------------------------------------------------
5232 class HStringValue (Value):
5233 def to_str(self, ectx):
5235 vv += self.val[1:-2]
5238 #--- FieldSpec ----------------------------------------------------------------
5239 class FieldSpec (Node):
5240 def __init__(self,*args, **kw) :
5242 Node.__init__ (self,*args, **kw)
5244 def SetName(self, name):
5248 return ['#UNSUPPORTED_' + self.type]
5252 repr.extend(self.get_repr())
5255 class TypeFieldSpec (FieldSpec):
5259 class FixedTypeValueFieldSpec (FieldSpec):
5261 if isinstance(self.typ, Type_Ref):
5262 repr = ['TypeReference', self.typ.val]
5264 repr = [self.typ.type]
5267 class VariableTypeValueFieldSpec (FieldSpec):
5269 return ['_' + self.type]
5271 class FixedTypeValueSetFieldSpec (FieldSpec):
5273 return ['_' + self.type]
5275 class ObjectFieldSpec (FieldSpec):
5277 return ['ClassReference', self.cls.val]
5279 class ObjectSetFieldSpec (FieldSpec):
5281 return ['ClassReference', self.cls.val]
5283 #==============================================================================
5285 def p_module_list_1 (t):
5286 'module_list : module_list ModuleDefinition'
5287 t[0] = t[1] + [t[2]]
5289 def p_module_list_2 (t):
5290 'module_list : ModuleDefinition'
5294 #--- ITU-T Recommendation X.680 -----------------------------------------------
5297 # 11 ASN.1 lexical items --------------------------------------------------------
5299 # 11.2 Type references
5301 'type_ref : UCASE_IDENT'
5302 t[0] = Type_Ref(val=t[1])
5305 def p_identifier (t):
5306 'identifier : LCASE_IDENT'
5309 # 11.4 Value references
5310 # cause reduce/reduce conflict
5311 #def p_valuereference (t):
5312 # 'valuereference : LCASE_IDENT'
5313 # t[0] = Value_Ref(val=t[1])
5315 # 11.5 Module references
5316 def p_modulereference (t):
5317 'modulereference : UCASE_IDENT'
5321 # 12 Module definition --------------------------------------------------------
5324 def p_ModuleDefinition (t):
5325 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5326 t[0] = Module (ident = t[1], tag_def = t[3], body = t[7])
5328 def p_ModuleBegin (t):
5330 if t[-4].val == 'Remote-Operations-Information-Objects':
5333 def p_TagDefault_1 (t):
5334 '''TagDefault : EXPLICIT TAGS
5337 t[0] = Default_Tags (dfl_tag = t[1])
5339 def p_TagDefault_2 (t):
5341 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5342 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
5344 def p_ModuleIdentifier_1 (t):
5345 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5346 t [0] = Node('module_ident', val = t[1], ident = t[2])
5348 def p_ModuleIdentifier_2 (t):
5349 'ModuleIdentifier : modulereference' # name, oid
5350 t [0] = Node('module_ident', val = t[1], ident = None)
5352 def p_DefinitiveIdentifier (t):
5353 'DefinitiveIdentifier : ObjectIdentifierValue'
5356 #def p_module_ref (t):
5357 # 'module_ref : UCASE_IDENT'
5360 def p_ModuleBody_1 (t):
5361 'ModuleBody : Exports Imports AssignmentList'
5362 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
5364 def p_ModuleBody_2 (t):
5366 t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
5368 def p_Exports_1 (t):
5369 'Exports : EXPORTS syms_exported SEMICOLON'
5372 def p_Exports_2 (t):
5373 'Exports : EXPORTS ALL SEMICOLON'
5376 def p_Exports_3 (t):
5380 def p_syms_exported_1 (t):
5381 'syms_exported : exp_sym_list'
5384 def p_syms_exported_2 (t):
5388 def p_exp_sym_list_1 (t):
5389 'exp_sym_list : Symbol'
5392 def p_exp_sym_list_2 (t):
5393 'exp_sym_list : exp_sym_list COMMA Symbol'
5394 t[0] = t[1] + [t[3]]
5397 def p_Imports_1 (t):
5398 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5400 global lcase_ident_assigned
5401 lcase_ident_assigned = {}
5403 def p_importsbegin (t):
5405 global lcase_ident_assigned
5407 lcase_ident_assigned = {}
5408 lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5410 def p_Imports_2 (t):
5414 def p_SymbolsImported_1(t):
5415 'SymbolsImported : '
5418 def p_SymbolsImported_2 (t):
5419 'SymbolsImported : SymbolsFromModuleList'
5422 def p_SymbolsFromModuleList_1 (t):
5423 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5424 t[0] = t[1] + [t[2]]
5426 def p_SymbolsFromModuleList_2 (t):
5427 'SymbolsFromModuleList : SymbolsFromModule'
5430 def p_SymbolsFromModule (t):
5431 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
5432 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
5433 for s in (t[0].symbol_list):
5434 if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
5435 import_symbols_from_module(t[0].module, t[0].symbol_list)
5437 def import_symbols_from_module(module, symbol_list):
5438 if module.val == 'Remote-Operations-Information-Objects':
5439 for i in range(len(symbol_list)):
5441 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
5443 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5444 symbol_list[i] = Class_Ref (val = s.val)
5446 for i in range(len(symbol_list)):
5448 if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)):
5449 import_class_from_module(module.val, s.val)
5450 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5451 symbol_list[i] = Class_Ref (val = s.val)
5453 def p_GlobalModuleReference (t):
5454 'GlobalModuleReference : modulereference AssignedIdentifier'
5455 t [0] = Node('module_ident', val = t[1], ident = t[2])
5457 def p_AssignedIdentifier_1 (t):
5458 'AssignedIdentifier : ObjectIdentifierValue'
5461 def p_AssignedIdentifier_2 (t):
5462 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5465 def p_AssignedIdentifier_3 (t):
5466 'AssignedIdentifier : '
5469 def p_SymbolList_1 (t):
5470 'SymbolList : Symbol'
5473 def p_SymbolList_2 (t):
5474 'SymbolList : SymbolList COMMA Symbol'
5475 t[0] = t[1] + [t[3]]
5478 '''Symbol : Reference
5479 | ParameterizedReference'''
5482 def p_Reference_1 (t):
5483 '''Reference : type_ref
5484 | objectclassreference '''
5487 def p_Reference_2 (t):
5488 '''Reference : LCASE_IDENT_ASSIGNED
5489 | identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5490 t[0] = Value_Ref(val=t[1])
5492 def p_AssignmentList_1 (t):
5493 'AssignmentList : AssignmentList Assignment'
5494 t[0] = t[1] + [t[2]]
5496 def p_AssignmentList_2 (t):
5497 'AssignmentList : Assignment SEMICOLON'
5500 def p_AssignmentList_3 (t):
5501 'AssignmentList : Assignment'
5504 def p_Assignment (t):
5505 '''Assignment : TypeAssignment
5507 | ValueSetTypeAssignment
5508 | ObjectClassAssignment
5510 | ObjectSetAssignment
5511 | ParameterizedAssignment
5516 # 13 Referencing type and value definitions -----------------------------------
5519 def p_DefinedType (t):
5520 '''DefinedType : ExternalTypeReference
5522 | ParameterizedType'''
5525 def p_DefinedValue_1(t):
5526 '''DefinedValue : ExternalValueReference'''
5529 def p_DefinedValue_2(t):
5530 '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5531 t[0] = Value_Ref(val=t[1])
5534 def p_ExternalTypeReference (t):
5535 'ExternalTypeReference : modulereference DOT type_ref'
5536 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
5538 def p_ExternalValueReference (t):
5539 'ExternalValueReference : modulereference DOT identifier'
5540 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
5543 # 15 Assigning types and values -----------------------------------------------
5546 def p_TypeAssignment (t):
5547 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
5552 def p_ValueAssignment (t):
5553 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
5554 t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
5556 # only "simple" types are supported to simplify grammer
5557 def p_ValueType (t):
5558 '''ValueType : type_ref
5561 | ObjectIdentifierType
5568 def p_ValueSetTypeAssignment (t):
5569 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
5570 t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4])
5574 'ValueSet : lbraceignore rbraceignore'
5578 # 16 Definition of types and values -------------------------------------------
5582 '''Type : BuiltinType
5584 | ConstrainedType'''
5588 def p_BuiltinType (t):
5589 '''BuiltinType : AnyType
5592 | CharacterStringType
5600 | ObjectClassFieldType
5601 | ObjectIdentifierType
5613 def p_ReferencedType (t):
5614 '''ReferencedType : DefinedType
5620 def p_NamedType (t):
5621 'NamedType : identifier Type'
5627 '''Value : BuiltinValue
5629 | ObjectClassFieldValue'''
5633 def p_BuiltinValue (t):
5634 '''BuiltinValue : BooleanValue
5637 | ObjectIdentifierValue
5642 | char_string''' # XXX we don't support {data} here
5646 def p_ReferencedValue (t):
5647 '''ReferencedValue : DefinedValue
5648 | ValueFromObject'''
5652 #def p_NamedValue (t):
5653 # 'NamedValue : identifier Value'
5654 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
5657 # 17 Notation for the boolean type --------------------------------------------
5660 def p_BooleanType (t):
5661 'BooleanType : BOOLEAN'
5662 t[0] = BooleanType ()
5665 def p_BooleanValue (t):
5666 '''BooleanValue : TRUE
5671 # 18 Notation for the integer type --------------------------------------------
5674 def p_IntegerType_1 (t):
5675 'IntegerType : INTEGER'
5676 t[0] = IntegerType (named_list = None)
5678 def p_IntegerType_2 (t):
5679 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
5680 t[0] = IntegerType(named_list = t[3])
5682 def p_NamedNumberList_1 (t):
5683 'NamedNumberList : NamedNumber'
5686 def p_NamedNumberList_2 (t):
5687 'NamedNumberList : NamedNumberList COMMA NamedNumber'
5688 t[0] = t[1] + [t[3]]
5690 def p_NamedNumber (t):
5691 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
5692 | identifier LPAREN DefinedValue RPAREN'''
5693 t[0] = NamedNumber(ident = t[1], val = t[3])
5695 def p_SignedNumber_1 (t):
5696 'SignedNumber : NUMBER'
5699 def p_SignedNumber_2 (t):
5700 'SignedNumber : MINUS NUMBER'
5704 def p_IntegerValue (t):
5705 'IntegerValue : SignedNumber'
5708 # 19 Notation for the enumerated type -----------------------------------------
5711 def p_EnumeratedType (t):
5712 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
5713 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
5715 def p_Enumerations_1 (t):
5716 'Enumerations : Enumeration'
5717 t[0] = { 'val' : t[1], 'ext' : None }
5719 def p_Enumerations_2 (t):
5720 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
5721 t[0] = { 'val' : t[1], 'ext' : [] }
5723 def p_Enumerations_3 (t):
5724 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
5725 t[0] = { 'val' : t[1], 'ext' : t[6] }
5727 def p_Enumeration_1 (t):
5728 'Enumeration : EnumerationItem'
5731 def p_Enumeration_2 (t):
5732 'Enumeration : Enumeration COMMA EnumerationItem'
5733 t[0] = t[1] + [t[3]]
5735 def p_EnumerationItem (t):
5736 '''EnumerationItem : Identifier
5740 def p_Identifier (t):
5741 'Identifier : identifier'
5742 t[0] = Node ('Identifier', ident = t[1])
5745 # 20 Notation for the real type -----------------------------------------------
5753 def p_RealValue (t):
5754 '''RealValue : REAL_NUMBER
5755 | SpecialRealValue'''
5758 def p_SpecialRealValue (t):
5759 '''SpecialRealValue : PLUS_INFINITY
5764 # 21 Notation for the bitstring type ------------------------------------------
5767 def p_BitStringType_1 (t):
5768 'BitStringType : BIT STRING'
5769 t[0] = BitStringType (named_list = None)
5771 def p_BitStringType_2 (t):
5772 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
5773 t[0] = BitStringType (named_list = t[4])
5775 def p_NamedBitList_1 (t):
5776 'NamedBitList : NamedBit'
5779 def p_NamedBitList_2 (t):
5780 'NamedBitList : NamedBitList COMMA NamedBit'
5781 t[0] = t[1] + [t[3]]
5784 '''NamedBit : identifier LPAREN NUMBER RPAREN
5785 | identifier LPAREN DefinedValue RPAREN'''
5786 t[0] = NamedNumber (ident = t[1], val = t[3])
5789 # 22 Notation for the octetstring type ----------------------------------------
5792 def p_OctetStringType (t):
5793 'OctetStringType : OCTET STRING'
5794 t[0] = OctetStringType ()
5797 # 23 Notation for the null type -----------------------------------------------
5805 def p_NullValue (t):
5810 # 24 Notation for sequence types ----------------------------------------------
5813 def p_SequenceType_1 (t):
5814 'SequenceType : SEQUENCE LBRACE RBRACE'
5815 t[0] = SequenceType (elt_list = [])
5817 def p_SequenceType_2 (t):
5818 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
5819 t[0] = SequenceType (elt_list = t[3]['elt_list'])
5820 if 'ext_list' in t[3]:
5821 t[0].ext_list = t[3]['ext_list']
5822 if 'elt_list2' in t[3]:
5823 t[0].ext_list = t[3]['elt_list2']
5825 def p_ExtensionAndException_1 (t):
5826 'ExtensionAndException : ELLIPSIS'
5829 def p_OptionalExtensionMarker_1 (t):
5830 'OptionalExtensionMarker : COMMA ELLIPSIS'
5833 def p_OptionalExtensionMarker_2 (t):
5834 'OptionalExtensionMarker : '
5837 def p_ComponentTypeLists_1 (t):
5838 'ComponentTypeLists : ComponentTypeList'
5839 t[0] = {'elt_list' : t[1]}
5841 def p_ComponentTypeLists_2 (t):
5842 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
5843 t[0] = {'elt_list' : t[1], 'ext_list' : []}
5845 def p_ComponentTypeLists_3 (t):
5846 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
5847 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
5849 def p_ComponentTypeLists_4 (t):
5850 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
5851 t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]}
5853 def p_ComponentTypeLists_5 (t):
5854 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
5855 t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]}
5857 def p_ComponentTypeLists_6 (t):
5858 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
5859 t[0] = {'elt_list' : [], 'ext_list' : []}
5861 def p_ComponentTypeLists_7 (t):
5862 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
5863 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
5865 #def p_RootComponentTypeList (t):
5866 # 'RootComponentTypeList : ComponentTypeList'
5869 def p_ExtensionEndMarker (t):
5870 'ExtensionEndMarker : COMMA ELLIPSIS'
5873 #def p_extension_additions_1 (t):
5874 # 'extension_additions : extension_addition_list'
5877 #def p_extension_additions_2 (t):
5878 # 'extension_additions : '
5881 def p_ExtensionAdditionList_1 (t):
5882 'ExtensionAdditionList : COMMA extension_addition'
5885 def p_ExtensionAdditionList_2 (t):
5886 'ExtensionAdditionList : ExtensionAdditionList COMMA extension_addition'
5887 t[0] = t[1] + [t[3]]
5889 def p_extension_addition_1 (t):
5890 'extension_addition : ComponentType'
5893 def p_ComponentTypeList_1 (t):
5894 'ComponentTypeList : ComponentType'
5897 def p_ComponentTypeList_2 (t):
5898 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
5899 t[0] = t[1] + [t[3]]
5901 def p_ComponentType_1 (t):
5902 'ComponentType : NamedType'
5903 t[0] = Node ('elt_type', val = t[1], optional = 0)
5905 def p_ComponentType_2 (t):
5906 'ComponentType : NamedType OPTIONAL'
5907 t[0] = Node ('elt_type', val = t[1], optional = 1)
5909 def p_ComponentType_3 (t):
5910 'ComponentType : NamedType DEFAULT DefaultValue'
5911 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
5913 def p_ComponentType_4 (t):
5914 'ComponentType : COMPONENTS OF Type'
5915 t[0] = Node ('components_of', typ = t[3])
5917 def p_DefaultValue_1 (t):
5918 '''DefaultValue : ReferencedValue
5926 | ObjectClassFieldValue'''
5929 def p_DefaultValue_2 (t):
5930 'DefaultValue : lbraceignore rbraceignore'
5934 def p_SequenceValue_1 (t):
5935 'SequenceValue : LBRACE RBRACE'
5939 #def p_SequenceValue_2 (t):
5940 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
5943 #def p_ComponentValueList_1 (t):
5944 # 'ComponentValueList : NamedValue'
5947 #def p_ComponentValueList_2 (t):
5948 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
5949 # t[0] = t[1] + [t[3]]
5952 # 25 Notation for sequence-of types -------------------------------------------
5955 def p_SequenceOfType (t):
5956 '''SequenceOfType : SEQUENCE OF Type
5957 | SEQUENCE OF NamedType'''
5958 t[0] = SequenceOfType (val = t[3], size_constr = None)
5961 # 26 Notation for set types ---------------------------------------------------
5964 def p_SetType_1 (t):
5965 'SetType : SET LBRACE RBRACE'
5966 t[0] = SetType (elt_list = [])
5968 def p_SetType_2 (t):
5969 'SetType : SET LBRACE ComponentTypeLists RBRACE'
5970 if 'ext_list' in t[3]:
5971 t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
5973 t[0] = SetType (elt_list = t[3]['elt_list'])
5976 # 27 Notation for set-of types ------------------------------------------------
5979 def p_SetOfType (t):
5980 '''SetOfType : SET OF Type
5981 | SET OF NamedType'''
5982 t[0] = SetOfType (val = t[3])
5984 # 28 Notation for choice types ------------------------------------------------
5987 def p_ChoiceType (t):
5988 'ChoiceType : CHOICE LBRACE alternative_type_lists RBRACE'
5989 if 'ext_list' in t[3]:
5990 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
5992 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
5994 def p_alternative_type_lists_1 (t):
5995 'alternative_type_lists : alternative_type_list'
5996 t[0] = {'elt_list' : t[1]}
5998 def p_alternative_type_lists_2 (t):
5999 '''alternative_type_lists : alternative_type_list COMMA ExtensionAndException extension_addition_alternatives OptionalExtensionMarker'''
6000 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6002 def p_extension_addition_alternatives_1 (t):
6003 'extension_addition_alternatives : extension_addition_alternatives_list'
6006 def p_extension_addition_alternatives_2 (t):
6007 'extension_addition_alternatives : '
6010 def p_extension_addition_alternatives_list_1 (t):
6011 'extension_addition_alternatives_list : COMMA extension_addition_alternative'
6014 def p_extension_addition_alternatives_list_2 (t):
6015 'extension_addition_alternatives_list : extension_addition_alternatives_list COMMA extension_addition_alternative'
6016 t[0] = t[1] + [t[3]]
6018 def p_extension_addition_alternative_1 (t):
6019 'extension_addition_alternative : NamedType'
6022 def p_alternative_type_list_1 (t):
6023 'alternative_type_list : NamedType'
6026 def p_alternative_type_list_2 (t):
6027 'alternative_type_list : alternative_type_list COMMA NamedType'
6028 t[0] = t[1] + [t[3]]
6031 def p_ChoiceValue_1 (t):
6032 '''ChoiceValue : identifier COLON Value
6033 | identifier COLON NullValue '''
6035 if not isinstance(val, Value):
6036 val = Value(val=val)
6037 t[0] = ChoiceValue (choice = t[1], val = val)
6039 # 29 Notation for selection types
6042 def p_SelectionType (t): #
6043 'SelectionType : identifier LT Type'
6044 t[0] = SelectionType (typ = t[3], sel = t[1])
6046 # 30 Notation for tagged types ------------------------------------------------
6049 def p_TaggedType_1 (t):
6050 'TaggedType : Tag Type'
6051 t[1].mode = 'default'
6055 def p_TaggedType_2 (t):
6056 '''TaggedType : Tag IMPLICIT Type
6057 | Tag EXPLICIT Type'''
6063 'Tag : LBRACK Class ClassNumber RBRACK'
6064 t[0] = Tag(cls = t[2], num = t[3])
6066 def p_ClassNumber_1 (t):
6067 'ClassNumber : number'
6070 def p_ClassNumber_2 (t):
6071 'ClassNumber : DefinedValue'
6075 '''Class : UNIVERSAL
6085 # 31 Notation for the object identifier type ----------------------------------
6088 def p_ObjectIdentifierType (t):
6089 'ObjectIdentifierType : OBJECT IDENTIFIER'
6090 t[0] = ObjectIdentifierType()
6093 def p_ObjectIdentifierValue (t):
6094 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6095 t[0] = ObjectIdentifierValue (comp_list=t[2])
6097 def p_oid_comp_list_1 (t):
6098 'oid_comp_list : oid_comp_list ObjIdComponents'
6099 t[0] = t[1] + [t[2]]
6101 def p_oid_comp_list_2 (t):
6102 'oid_comp_list : ObjIdComponents'
6105 def p_ObjIdComponents (t):
6106 '''ObjIdComponents : NameForm
6108 | NameAndNumberForm'''
6112 '''NameForm : LCASE_IDENT
6113 | LCASE_IDENT_ASSIGNED'''
6116 def p_NumberForm (t):
6117 '''NumberForm : NUMBER'''
6121 def p_NameAndNumberForm (t):
6122 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6123 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6124 t[0] = Node('name_and_number', ident = t[1], number = t[3])
6126 # 32 Notation for the relative object identifier type -------------------------
6129 def p_RelativeOIDType (t):
6130 'RelativeOIDType : RELATIVE_OID'
6131 t[0] = RelativeOIDType()
6133 # 33 Notation for the embedded-pdv type ---------------------------------------
6136 def p_EmbeddedPDVType (t):
6137 'EmbeddedPDVType : EMBEDDED PDV'
6138 t[0] = EmbeddedPDVType()
6140 # 34 Notation for the external type -------------------------------------------
6143 def p_ExternalType (t):
6144 'ExternalType : EXTERNAL'
6145 t[0] = ExternalType()
6147 # 36 Notation for character string types --------------------------------------
6150 def p_CharacterStringType (t):
6151 '''CharacterStringType : RestrictedCharacterStringType
6152 | UnrestrictedCharacterStringType'''
6156 # 37 Definition of restricted character string types --------------------------
6158 def p_RestrictedCharacterStringType_1 (t):
6159 'RestrictedCharacterStringType : BMPString'
6160 t[0] = BMPStringType ()
6161 def p_RestrictedCharacterStringType_2 (t):
6162 'RestrictedCharacterStringType : GeneralString'
6163 t[0] = GeneralStringType ()
6164 def p_RestrictedCharacterStringType_3 (t):
6165 'RestrictedCharacterStringType : GraphicString'
6166 t[0] = GraphicStringType ()
6167 def p_RestrictedCharacterStringType_4 (t):
6168 'RestrictedCharacterStringType : IA5String'
6169 t[0] = IA5StringType ()
6170 def p_RestrictedCharacterStringType_5 (t):
6171 'RestrictedCharacterStringType : ISO646String'
6172 t[0] = ISO646StringType ()
6173 def p_RestrictedCharacterStringType_6 (t):
6174 'RestrictedCharacterStringType : NumericString'
6175 t[0] = NumericStringType ()
6176 def p_RestrictedCharacterStringType_7 (t):
6177 'RestrictedCharacterStringType : PrintableString'
6178 t[0] = PrintableStringType ()
6179 def p_RestrictedCharacterStringType_8 (t):
6180 'RestrictedCharacterStringType : TeletexString'
6181 t[0] = TeletexStringType ()
6182 def p_RestrictedCharacterStringType_9 (t):
6183 'RestrictedCharacterStringType : T61String'
6184 t[0] = T61StringType ()
6185 def p_RestrictedCharacterStringType_10 (t):
6186 'RestrictedCharacterStringType : UniversalString'
6187 t[0] = UniversalStringType ()
6188 def p_RestrictedCharacterStringType_11 (t):
6189 'RestrictedCharacterStringType : UTF8String'
6190 t[0] = UTF8StringType ()
6191 def p_RestrictedCharacterStringType_12 (t):
6192 'RestrictedCharacterStringType : VideotexString'
6193 t[0] = VideotexStringType ()
6194 def p_RestrictedCharacterStringType_13 (t):
6195 'RestrictedCharacterStringType : VisibleString'
6196 t[0] = VisibleStringType ()
6199 # 40 Definition of unrestricted character string types ------------------------
6202 def p_UnrestrictedCharacterStringType (t):
6203 'UnrestrictedCharacterStringType : CHARACTER STRING'
6204 t[0] = UnrestrictedCharacterStringType ()
6207 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6209 # 42 Generalized time ---------------------------------------------------------
6211 def p_UsefulType_1 (t):
6212 'UsefulType : GeneralizedTime'
6213 t[0] = GeneralizedTime()
6215 # 43 Universal time -----------------------------------------------------------
6217 def p_UsefulType_2 (t):
6218 'UsefulType : UTCTime'
6221 # 44 The object descriptor type -----------------------------------------------
6223 def p_UsefulType_3 (t):
6224 'UsefulType : ObjectDescriptor'
6225 t[0] = ObjectDescriptor()
6228 # 45 Constrained types --------------------------------------------------------
6231 def p_ConstrainedType_1 (t):
6232 'ConstrainedType : Type Constraint'
6234 t[0].AddConstraint(t[2])
6236 def p_ConstrainedType_2 (t):
6237 'ConstrainedType : TypeWithConstraint'
6241 def p_TypeWithConstraint_1 (t):
6242 '''TypeWithConstraint : SET Constraint OF Type
6243 | SET SizeConstraint OF Type'''
6244 t[0] = SetOfType (val = t[4], constr = t[2])
6246 def p_TypeWithConstraint_2 (t):
6247 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6248 | SEQUENCE SizeConstraint OF Type'''
6249 t[0] = SequenceOfType (val = t[4], constr = t[2])
6251 def p_TypeWithConstraint_3 (t):
6252 '''TypeWithConstraint : SET Constraint OF NamedType
6253 | SET SizeConstraint OF NamedType'''
6254 t[0] = SetOfType (val = t[4], constr = t[2])
6256 def p_TypeWithConstraint_4 (t):
6257 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6258 | SEQUENCE SizeConstraint OF NamedType'''
6259 t[0] = SequenceOfType (val = t[4], constr = t[2])
6263 def p_Constraint (t):
6264 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6267 def p_ConstraintSpec (t):
6268 '''ConstraintSpec : ElementSetSpecs
6269 | GeneralConstraint'''
6272 # 46 Element set specification ------------------------------------------------
6275 def p_ElementSetSpecs_1 (t):
6276 'ElementSetSpecs : RootElementSetSpec'
6279 def p_ElementSetSpecs_2 (t):
6280 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6284 def p_ElementSetSpecs_3 (t):
6285 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6289 def p_RootElementSetSpec (t):
6290 'RootElementSetSpec : ElementSetSpec'
6293 def p_AdditionalElementSetSpec (t):
6294 'AdditionalElementSetSpec : ElementSetSpec'
6297 def p_ElementSetSpec (t):
6298 'ElementSetSpec : Unions'
6302 'Unions : Intersections'
6306 'Unions : UElems UnionMark Intersections'
6307 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
6313 def p_Intersections_1 (t):
6314 'Intersections : IntersectionElements'
6317 def p_Intersections_2 (t):
6318 'Intersections : IElems IntersectionMark IntersectionElements'
6319 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
6322 'IElems : Intersections'
6325 def p_IntersectionElements (t):
6326 'IntersectionElements : Elements'
6329 def p_UnionMark (t):
6333 def p_IntersectionMark (t):
6334 '''IntersectionMark : CIRCUMFLEX
6338 def p_Elements_1 (t):
6339 'Elements : SubtypeElements'
6342 def p_Elements_2 (t):
6343 'Elements : LPAREN ElementSetSpec RPAREN'
6346 # 47 Subtype elements ---------------------------------------------------------
6349 def p_SubtypeElements (t):
6350 '''SubtypeElements : SingleValue
6356 | InnerTypeConstraints
6357 | PatternConstraint'''
6362 def p_SingleValue (t):
6363 'SingleValue : Value'
6364 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
6366 # 47.3 Contained subtype
6368 def p_ContainedSubtype (t):
6369 'ContainedSubtype : Includes Type'
6370 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
6373 '''Includes : INCLUDES
6378 def p_ValueRange (t):
6379 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6380 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
6383 def p_LowerEndpoint_1 (t):
6384 'LowerEndpoint : LowerEndValue'
6387 def p_LowerEndpoint_2 (t):
6388 'LowerEndpoint : LowerEndValue LT'
6389 t[0] = t[1] # but not inclusive range
6391 def p_UpperEndpoint_1 (t):
6392 'UpperEndpoint : UpperEndValue'
6395 def p_UpperEndpoint_2 (t):
6396 'UpperEndpoint : LT UpperEndValue'
6397 t[0] = t[1] # but not inclusive range
6400 def p_LowerEndValue (t):
6401 '''LowerEndValue : Value
6405 def p_UpperEndValue (t):
6406 '''UpperEndValue : Value
6410 # 47.5 Size constraint
6412 def p_SizeConstraint (t):
6413 'SizeConstraint : SIZE Constraint'
6414 t[0] = Constraint (type = 'Size', subtype = t[2])
6416 # 47.6 Type constraint
6418 def p_TypeConstraint (t):
6419 'TypeConstraint : Type'
6420 t[0] = Constraint (type = 'Type', subtype = t[1])
6422 # 47.7 Permitted alphabet
6424 def p_PermittedAlphabet (t):
6425 'PermittedAlphabet : FROM Constraint'
6426 t[0] = Constraint (type = 'From', subtype = t[2])
6428 # 47.8 Inner subtyping
6430 def p_InnerTypeConstraints (t):
6431 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6432 | WITH COMPONENTS MultipleTypeConstraints'''
6433 pass # ignore PER invisible constraint
6436 def p_SingleTypeConstraint (t):
6437 'SingleTypeConstraint : Constraint'
6441 def p_MultipleTypeConstraints (t):
6442 '''MultipleTypeConstraints : FullSpecification
6443 | PartialSpecification'''
6446 def p_FullSpecification (t):
6447 'FullSpecification : LBRACE TypeConstraints RBRACE'
6450 def p_PartialSpecification (t):
6451 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6454 def p_TypeConstraints_1 (t):
6455 'TypeConstraints : named_constraint'
6458 def p_TypeConstraints_2 (t):
6459 'TypeConstraints : TypeConstraints COMMA named_constraint'
6460 t[0] = t[1] + [t[3]]
6462 def p_named_constraint_1 (t):
6463 'named_constraint : identifier constraint'
6464 return Node ('named_constraint', ident = t[1], constr = t[2])
6466 def p_named_constraint_2 (t):
6467 'named_constraint : constraint'
6468 return Node ('named_constraint', constr = t[1])
6470 def p_constraint (t):
6471 'constraint : value_constraint presence_constraint'
6472 t[0] = Node ('constraint', value = t[1], presence = t[2])
6474 def p_value_constraint_1 (t):
6475 'value_constraint : Constraint'
6478 def p_value_constraint_2 (t):
6479 'value_constraint : '
6482 def p_presence_constraint_1 (t):
6483 '''presence_constraint : PRESENT
6488 def p_presence_constraint_2 (t):
6489 '''presence_constraint : '''
6492 # 47.9 Pattern constraint
6494 def p_PatternConstraint (t):
6495 'PatternConstraint : PATTERN Value'
6496 t[0] = Constraint (type = 'Pattern', subtype = t[2])
6498 # 49 The exception identifier
6501 def p_ExceptionSpec_1 (t):
6502 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
6505 def p_ExceptionSpec_2 (t):
6509 def p_ExceptionIdentification (t):
6510 '''ExceptionIdentification : SignedNumber
6512 | Type COLON Value '''
6515 # /*-----------------------------------------------------------------------*/
6516 # /* Value Notation Productions */
6517 # /*-----------------------------------------------------------------------*/
6521 def p_binary_string (t):
6522 'binary_string : BSTRING'
6523 t[0] = BStringValue(val = t[1])
6525 def p_hex_string (t):
6526 'hex_string : HSTRING'
6527 t[0] = HStringValue(val = t[1])
6529 def p_char_string (t):
6530 'char_string : QSTRING'
6538 #--- ITU-T Recommendation X.208 -----------------------------------------------
6540 # 27 Notation for the any type ------------------------------------------------
6545 | ANY DEFINED BY identifier'''
6548 #--- ITU-T Recommendation X.681 -----------------------------------------------
6550 # 7 ASN.1 lexical items -------------------------------------------------------
6552 # 7.1 Information object class references
6554 def p_objectclassreference (t):
6555 'objectclassreference : CLASS_IDENT'
6556 t[0] = Class_Ref(val=t[1])
6558 # 7.2 Information object references
6560 def p_objectreference (t):
6561 'objectreference : LCASE_IDENT'
6564 # 7.3 Information object set references
6566 #def p_objectsetreference (t):
6567 # 'objectsetreference : UCASE_IDENT'
6570 # 7.4 Type field references
6571 # ucasefieldreference
6572 # 7.5 Value field references
6573 # lcasefieldreference
6574 # 7.6 Value set field references
6575 # ucasefieldreference
6576 # 7.7 Object field references
6577 # lcasefieldreference
6578 # 7.8 Object set field references
6579 # ucasefieldreference
6581 def p_ucasefieldreference (t):
6582 'ucasefieldreference : AMPERSAND UCASE_IDENT'
6585 def p_lcasefieldreference (t):
6586 'lcasefieldreference : AMPERSAND LCASE_IDENT'
6589 # 8 Referencing definitions
6592 def p_DefinedObjectClass (t):
6593 '''DefinedObjectClass : objectclassreference
6594 | UsefulObjectClassReference'''
6597 obj_class = t[0].val
6599 def p_DefinedObject (t):
6600 '''DefinedObject : objectreference'''
6604 def p_UsefulObjectClassReference (t):
6605 '''UsefulObjectClassReference : TYPE_IDENTIFIER
6606 | ABSTRACT_SYNTAX'''
6607 t[0] = Class_Ref(val=t[1])
6609 # 9 Information object class definition and assignment
6612 def p_ObjectClassAssignment (t):
6613 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
6614 | UCASE_IDENT ASSIGNMENT ObjectClass'''
6617 if isinstance(t[0], ObjectClassDefn):
6621 def p_ObjectClass (t):
6622 '''ObjectClass : DefinedObjectClass
6624 | ParameterizedObjectClass '''
6628 def p_ObjectClassDefn (t):
6629 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
6630 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
6631 t[0] = ObjectClassDefn(fields = t[3])
6633 def p_FieldSpecs_1 (t):
6634 'FieldSpecs : FieldSpec'
6637 def p_FieldSpecs_2 (t):
6638 'FieldSpecs : FieldSpecs COMMA FieldSpec'
6639 t[0] = t[1] + [t[3]]
6641 def p_WithSyntaxSpec (t):
6642 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
6646 def p_FieldSpec (t):
6647 '''FieldSpec : TypeFieldSpec
6648 | FixedTypeValueFieldSpec
6649 | VariableTypeValueFieldSpec
6650 | FixedTypeValueSetFieldSpec
6652 | ObjectSetFieldSpec '''
6656 def p_TypeFieldSpec (t):
6657 '''TypeFieldSpec : ucasefieldreference
6658 | ucasefieldreference TypeOptionalitySpec '''
6659 t[0] = TypeFieldSpec()
6662 def p_TypeOptionalitySpec_1 (t):
6663 'TypeOptionalitySpec ::= OPTIONAL'
6666 def p_TypeOptionalitySpec_2 (t):
6667 'TypeOptionalitySpec ::= DEFAULT Type'
6671 def p_FixedTypeValueFieldSpec (t):
6672 '''FixedTypeValueFieldSpec : lcasefieldreference Type
6673 | lcasefieldreference Type UNIQUE
6674 | lcasefieldreference Type ValueOptionalitySpec
6675 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
6676 t[0] = FixedTypeValueFieldSpec(typ = t[2])
6679 def p_ValueOptionalitySpec_1 (t):
6680 'ValueOptionalitySpec ::= OPTIONAL'
6683 def p_ValueOptionalitySpec_2 (t):
6684 'ValueOptionalitySpec ::= DEFAULT Value'
6689 def p_VariableTypeValueFieldSpec (t):
6690 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
6691 | lcasefieldreference FieldName ValueOptionalitySpec '''
6692 t[0] = VariableTypeValueFieldSpec()
6696 def p_FixedTypeValueSetFieldSpec (t):
6697 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
6698 | ucasefieldreference Type ValueSetOptionalitySpec '''
6699 t[0] = FixedTypeValueSetFieldSpec()
6702 def p_ValueSetOptionalitySpec_1 (t):
6703 'ValueSetOptionalitySpec ::= OPTIONAL'
6706 def p_ValueSetOptionalitySpec_2 (t):
6707 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
6711 def p_ObjectFieldSpec (t):
6712 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
6713 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
6714 t[0] = ObjectFieldSpec(cls=t[2])
6719 def p_ObjectOptionalitySpec_1 (t):
6720 'ObjectOptionalitySpec ::= OPTIONAL'
6723 def p_ObjectOptionalitySpec_2 (t):
6724 'ObjectOptionalitySpec ::= DEFAULT Object'
6728 def p_ObjectSetFieldSpec (t):
6729 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
6730 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
6731 t[0] = ObjectSetFieldSpec(cls=t[2])
6734 def p_ObjectSetOptionalitySpec_1 (t):
6735 'ObjectSetOptionalitySpec ::= OPTIONAL'
6738 def p_ObjectSetOptionalitySpec_2 (t):
6739 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
6743 def p_PrimitiveFieldName (t):
6744 '''PrimitiveFieldName : ucasefieldreference
6745 | lcasefieldreference '''
6749 def p_FieldName_1 (t):
6750 'FieldName : PrimitiveFieldName'
6753 def p_FieldName_2 (t):
6754 'FieldName : FieldName DOT PrimitiveFieldName'
6755 t[0] = t[1] + '.' + t[3]
6757 # 11 Information object definition and assignment
6760 def p_ObjectAssignment (t):
6761 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
6762 t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4])
6768 '''Object : DefinedObject
6770 | ParameterizedObject'''
6774 def p_ObjectDefn (t):
6775 'ObjectDefn : lbraceobject bodyobject rbraceobject'
6778 # {...} block of object definition
6779 def p_lbraceobject(t):
6780 'lbraceobject : braceobjectbegin LBRACE'
6783 def p_braceobjectbegin(t):
6784 'braceobjectbegin : '
6787 if set_class_syntax(obj_class):
6791 state = 'braceignore'
6792 lexer.push_state(state)
6794 def p_rbraceobject(t):
6795 'rbraceobject : braceobjectend RBRACE'
6798 def p_braceobjectend(t):
6802 set_class_syntax(None)
6804 def p_bodyobject_1 (t):
6808 def p_bodyobject_2 (t):
6809 'bodyobject : cls_syntax_list'
6812 def p_cls_syntax_list_1 (t):
6813 'cls_syntax_list : cls_syntax_list cls_syntax'
6817 def p_cls_syntax_list_2 (t):
6818 'cls_syntax_list : cls_syntax'
6822 def p_cls_syntax_1 (t):
6823 'cls_syntax : Type IDENTIFIED BY Value'
6824 t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
6826 def p_cls_syntax_2 (t):
6827 'cls_syntax : HAS PROPERTY Value'
6828 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
6831 def p_cls_syntax_3 (t):
6832 '''cls_syntax : ERRORS ObjectSet
6834 | RETURN RESULT BooleanValue
6835 | SYNCHRONOUS BooleanValue
6836 | INVOKE PRIORITY Value
6837 | RESULT_PRIORITY Value
6839 | ALWAYS RESPONDS BooleanValue
6840 | IDEMPOTENT BooleanValue '''
6841 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
6843 def p_cls_syntax_4 (t):
6844 '''cls_syntax : ARGUMENT Type
6848 t[0] = { get_class_fieled(t[1]) : t[2] }
6850 def p_cls_syntax_5 (t):
6851 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
6852 | RESULT Type OPTIONAL BooleanValue
6853 | PARAMETER Type OPTIONAL BooleanValue '''
6854 t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
6856 # 12 Information object set definition and assignment
6859 def p_ObjectSetAssignment (t):
6860 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
6861 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
6864 def p_ObjectSet (t):
6865 'ObjectSet : lbraceignore rbraceignore'
6868 # 14 Notation for the object class field type ---------------------------------
6871 def p_ObjectClassFieldType (t):
6872 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
6873 t[0] = get_type_from_class(t[1], t[3])
6876 def p_ObjectClassFieldValue (t):
6877 '''ObjectClassFieldValue : OpenTypeFieldVal'''
6880 def p_OpenTypeFieldVal (t):
6881 '''OpenTypeFieldVal : Type COLON Value
6882 | NullType COLON NullValue'''
6886 # 15 Information from objects -------------------------------------------------
6890 def p_ValueFromObject (t):
6891 'ValueFromObject : LCASE_IDENT DOT FieldName'
6892 t[0] = t[1] + '.' + t[3]
6895 # Annex C - The instance-of type ----------------------------------------------
6898 def p_InstanceOfType (t):
6899 'InstanceOfType : INSTANCE OF DefinedObjectClass'
6900 t[0] = InstanceOfType()
6905 useful_object_class_types = {
6907 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
6908 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
6910 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
6911 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
6912 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
6915 object_class_types = { }
6917 object_class_typerefs = { }
6919 object_class_classrefs = { }
6922 class _VariableTypeValueFieldSpec (AnyType):
6925 class _FixedTypeValueSetFieldSpec (AnyType):
6928 class_types_creator = {
6929 'BooleanType' : lambda : BooleanType(),
6930 'IntegerType' : lambda : IntegerType(),
6931 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
6932 'OpenType' : lambda : OpenType(),
6934 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
6935 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
6941 'TYPE-IDENTIFIER' : {
6943 'IDENTIFIED' : 'IDENTIFIED',
6945 'IDENTIFIED BY' : '&id',
6947 'ABSTRACT-SYNTAX' : {
6949 'IDENTIFIED' : 'IDENTIFIED',
6951 'IDENTIFIED BY' : '&id',
6953 'PROPERTY' : 'PROPERTY',
6954 'HAS PROPERTY' : '&property',
6958 class_syntaxes_enabled = {
6959 'TYPE-IDENTIFIER' : True,
6960 'ABSTRACT-SYNTAX' : True,
6964 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
6965 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
6968 class_current_syntax = None
6970 def get_syntax_tokens(syntaxes):
6972 for s in (syntaxes):
6973 for k in (list(syntaxes[s].keys())):
6976 tokens[k] = tokens[k].replace('-', '_')
6977 return list(tokens.values())
6979 tokens = tokens + get_syntax_tokens(x681_syntaxes)
6981 def set_class_syntax(syntax):
6982 global class_syntaxes_enabled
6983 global class_current_syntax
6984 #print "set_class_syntax", syntax, class_current_syntax
6985 if class_syntaxes_enabled.get(syntax, False):
6986 class_current_syntax = syntax
6989 class_current_syntax = None
6992 def is_class_syntax(name):
6993 global class_syntaxes
6994 global class_current_syntax
6995 #print "is_class_syntax", name, class_current_syntax
6996 if not class_current_syntax:
6998 return name in class_syntaxes[class_current_syntax]
7000 def get_class_fieled(name):
7001 if not class_current_syntax:
7003 return class_syntaxes[class_current_syntax][name]
7005 def is_class_ident(name):
7006 return name in class_names
7008 def add_class_ident(name):
7009 #print "add_class_ident", name
7010 class_names[name] = name
7012 def get_type_from_class(cls, fld):
7013 flds = fld.split('.')
7014 if (isinstance(cls, Class_Ref)):
7015 key = cls.val + '.' + flds[0]
7017 key = cls + '.' + flds[0]
7019 if key in object_class_classrefs:
7020 return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:]))
7022 if key in object_class_typerefs:
7023 return Type_Ref(val=object_class_typerefs[key])
7025 creator = lambda : AnyType()
7026 creator = useful_object_class_types.get(key, creator)
7027 creator = object_class_types.get(key, creator)
7030 def set_type_to_class(cls, fld, pars):
7031 #print "set_type_to_class", cls, fld, pars
7032 key = cls + '.' + fld
7033 typename = 'OpenType'
7037 pars.append(typename)
7040 if (isinstance(pars[1], Class_Ref)):
7041 pars[1] = pars[1].val
7045 if key in object_class_types:
7046 msg = object_class_types[key]().type
7047 if key in object_class_typerefs:
7048 msg = "TypeReference " + object_class_typerefs[key]
7049 if key in object_class_classrefs:
7050 msg = "ClassReference " + object_class_classrefs[key]
7052 if msg == ' '.join(pars):
7056 msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars))
7057 msg1 = "Already defined as '%s'" % (msg)
7058 raise CompError(msg0 + msg1)
7060 if (typename == 'ClassReference'):
7061 if not typeref: return False
7062 object_class_classrefs[key] = typeref
7065 if (typename == 'TypeReference'):
7066 if not typeref: return False
7067 object_class_typerefs[key] = typeref
7070 creator = class_types_creator.get(typename)
7072 object_class_types[key] = creator
7077 def import_class_from_module(mod, cls):
7078 add_class_ident(cls)
7079 mcls = "$%s$%s" % (mod, cls)
7080 for k in list(object_class_classrefs.keys()):
7081 kk = k.split('.', 1)
7083 object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k]
7084 for k in list(object_class_typerefs.keys()):
7085 kk = k.split('.', 1)
7087 object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k]
7088 for k in list(object_class_types.keys()):
7089 kk = k.split('.', 1)
7091 object_class_types[cls + '.' + kk[0]] = object_class_types[k]
7093 #--- ITU-T Recommendation X.682 -----------------------------------------------
7095 # 8 General constraint specification ------------------------------------------
7098 def p_GeneralConstraint (t):
7099 '''GeneralConstraint : UserDefinedConstraint
7101 | ContentsConstraint'''
7104 # 9 User-defined constraints --------------------------------------------------
7107 def p_UserDefinedConstraint (t):
7108 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7109 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
7111 def p_UserDefinedConstraintParameterList_1 (t):
7112 'UserDefinedConstraintParameterList : '
7115 def p_UserDefinedConstraintParameterList_2 (t):
7116 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7119 def p_UserDefinedConstraintParameterList_3 (t):
7120 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7121 t[0] = t[1] + [t[3]]
7124 def p_UserDefinedConstraintParameter (t):
7125 'UserDefinedConstraintParameter : Type'
7128 # 10 Table constraints, including component relation constraints --------------
7131 def p_TableConstraint (t):
7132 '''TableConstraint : SimpleTableConstraint
7133 | ComponentRelationConstraint'''
7134 t[0] = Constraint(type = 'Table', subtype = t[1])
7136 def p_SimpleTableConstraint (t):
7137 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7141 def p_ComponentRelationConstraint (t):
7142 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7143 t[0] = t[2] + str(t[5])
7145 def p_AtNotations_1 (t):
7146 'AtNotations : AtNotation'
7149 def p_AtNotations_2 (t):
7150 'AtNotations : AtNotations COMMA AtNotation'
7151 t[0] = t[1] + [t[3]]
7153 def p_AtNotation_1 (t):
7154 'AtNotation : AT ComponentIdList'
7157 def p_AtNotation_2 (t):
7158 'AtNotation : AT DOT Level ComponentIdList'
7159 t[0] = '@.' + t[3] + t[4]
7169 def p_ComponentIdList_1 (t):
7170 'ComponentIdList : LCASE_IDENT'
7173 def p_ComponentIdList_2 (t):
7174 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7175 t[0] = t[1] + '.' + t[3]
7177 # 11 Contents constraints -----------------------------------------------------
7180 def p_ContentsConstraint (t):
7181 'ContentsConstraint : CONTAINING type_ref'
7182 t[0] = Constraint(type = 'Contents', subtype = t[2])
7185 #--- ITU-T Recommendation X.683 -----------------------------------------------
7187 # 8 Parameterized assignments -------------------------------------------------
7190 def p_ParameterizedAssignment (t):
7191 '''ParameterizedAssignment : ParameterizedTypeAssignment
7192 | ParameterizedObjectClassAssignment
7193 | ParameterizedObjectAssignment
7194 | ParameterizedObjectSetAssignment'''
7198 def p_ParameterizedTypeAssignment (t):
7199 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7201 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
7203 def p_ParameterizedObjectClassAssignment (t):
7204 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7205 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7208 if isinstance(t[0], ObjectClassDefn):
7211 def p_ParameterizedObjectAssignment (t):
7212 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7213 t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
7217 def p_ParameterizedObjectSetAssignment (t):
7218 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7219 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
7222 def p_ParameterList (t):
7223 'ParameterList : lbraceignore rbraceignore'
7225 #def p_ParameterList (t):
7226 # 'ParameterList : LBRACE Parameters RBRACE'
7229 #def p_Parameters_1 (t):
7230 # 'Parameters : Parameter'
7233 #def p_Parameters_2 (t):
7234 # 'Parameters : Parameters COMMA Parameter'
7235 # t[0] = t[1] + [t[3]]
7237 #def p_Parameter_1 (t):
7238 # 'Parameter : Type COLON Reference'
7239 # t[0] = [t[1], t[3]]
7241 #def p_Parameter_2 (t):
7242 # 'Parameter : Reference'
7246 # 9 Referencing parameterized definitions -------------------------------------
7249 def p_ParameterizedReference (t):
7250 'ParameterizedReference : Reference LBRACE RBRACE'
7255 def p_ParameterizedType (t):
7256 'ParameterizedType : type_ref ActualParameterList'
7261 def p_ParameterizedObjectClass (t):
7262 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7266 def p_ParameterizedObject (t):
7267 'ParameterizedObject : DefinedObject ActualParameterList'
7272 def p_ActualParameterList (t):
7273 'ActualParameterList : lbraceignore rbraceignore'
7275 #def p_ActualParameterList (t):
7276 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7279 #def p_ActualParameters_1 (t):
7280 # 'ActualParameters : ActualParameter'
7283 #def p_ActualParameters_2 (t):
7284 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7285 # t[0] = t[1] + [t[3]]
7287 #def p_ActualParameter (t):
7288 # '''ActualParameter : Type
7293 #--- ITU-T Recommendation X.880 -----------------------------------------------
7297 '&ArgumentType' : [],
7298 '&argumentTypeOptional' : [ 'BooleanType' ],
7299 '&returnResult' : [ 'BooleanType' ],
7301 '&resultTypeOptional' : [ 'BooleanType' ],
7302 '&Errors' : [ 'ClassReference', 'ERROR' ],
7303 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7304 '&synchronous' : [ 'BooleanType' ],
7305 '&idempotent' : [ 'BooleanType' ],
7306 '&alwaysReturns' : [ 'BooleanType' ],
7307 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7308 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7309 '&operationCode' : [ 'TypeReference', 'Code' ],
7312 '&ParameterType' : [],
7313 '¶meterTypeOptional' : [ 'BooleanType' ],
7314 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7315 '&errorCode' : [ 'TypeReference', 'Code' ],
7317 'OPERATION-PACKAGE' : {
7318 '&Both' : [ 'ClassReference', 'OPERATION' ],
7319 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7320 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7321 '&id' : [ 'ObjectIdentifierType' ],
7323 'CONNECTION-PACKAGE' : {
7324 '&bind' : [ 'ClassReference', 'OPERATION' ],
7325 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7326 '&responderCanUnbind' : [ 'BooleanType' ],
7327 '&unbindCanFail' : [ 'BooleanType' ],
7328 '&id' : [ 'ObjectIdentifierType' ],
7331 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7332 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7333 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7334 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7335 '&id' : [ 'ObjectIdentifierType' ],
7337 'ROS-OBJECT-CLASS' : {
7338 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7339 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7340 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7341 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7342 '&id' : [ 'ObjectIdentifierType' ],
7348 'ARGUMENT' : '&ArgumentType',
7349 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7350 'RESULT' : '&ResultType',
7351 'RESULT OPTIONAL' : '&resultTypeOptional',
7352 'RETURN' : 'RETURN',
7353 'RETURN RESULT' : '&returnResult',
7354 'ERRORS' : '&Errors',
7355 'LINKED' : '&Linked',
7356 'SYNCHRONOUS' : '&synchronous',
7357 'IDEMPOTENT' : '&idempotent',
7358 'ALWAYS' : 'ALWAYS',
7359 'RESPONDS' : 'RESPONDS',
7360 'ALWAYS RESPONDS' : '&alwaysReturns',
7361 'INVOKE' : 'INVOKE',
7362 'PRIORITY' : 'PRIORITY',
7363 'INVOKE PRIORITY' : '&InvokePriority',
7364 'RESULT-PRIORITY': '&ResultPriority',
7365 'CODE' : '&operationCode',
7368 'PARAMETER' : '&ParameterType',
7369 'PARAMETER OPTIONAL' : '¶meterTypeOptional',
7370 'PRIORITY' : '&ErrorPriority',
7371 'CODE' : '&errorCode',
7373 # 'OPERATION-PACKAGE' : {
7375 # 'CONNECTION-PACKAGE' : {
7379 # 'ROS-OBJECT-CLASS' : {
7383 def x880_module_begin():
7384 #print "x880_module_begin()"
7385 for name in list(x880_classes.keys()):
7386 add_class_ident(name)
7388 def x880_import(name):
7389 if name in x880_syntaxes:
7390 class_syntaxes_enabled[name] = True
7391 class_syntaxes[name] = x880_syntaxes[name]
7392 if name in x880_classes:
7393 add_class_ident(name)
7394 for f in (list(x880_classes[name].keys())):
7395 set_type_to_class(name, f, x880_classes[name][f])
7397 tokens = tokens + get_syntax_tokens(x880_syntaxes)
7400 #def p_lbrace_oid(t):
7401 # 'lbrace_oid : brace_oid_begin LBRACE'
7404 #def p_brace_oid_begin(t):
7405 # 'brace_oid_begin : '
7409 #def p_rbrace_oid(t):
7410 # 'rbrace_oid : brace_oid_end RBRACE'
7413 #def p_brace_oid_end(t):
7414 # 'brace_oid_end : '
7418 # {...} block to be ignored
7419 def p_lbraceignore(t):
7420 'lbraceignore : braceignorebegin LBRACE'
7423 def p_braceignorebegin(t):
7424 'braceignorebegin : '
7427 lexer.push_state('braceignore')
7429 def p_rbraceignore(t):
7430 'rbraceignore : braceignoreend RBRACE'
7433 def p_braceignoreend(t):
7440 raise ParseError(t, input_file)
7443 '''pyquote : PYQUOTE'''
7444 t[0] = PyQuote (val = t[1])
7450 token = lexer.token ()
7456 def do_module (ast, defined_dict):
7457 assert (ast.type == 'Module')
7458 ctx = Ctx (defined_dict)
7459 print ast.to_python (ctx)
7460 print ctx.output_assignments ()
7461 print ctx.output_pyquotes ()
7463 def eth_do_module (ast, ectx):
7464 assert (ast.type == 'Module')
7465 if ectx.dbg('s'): print ast.str_depth(0)
7468 def testyacc(s, fn, defined_dict):
7469 ast = yacc.parse(s, debug=0)
7470 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
7471 print """#!/usr/bin/env python
7472 # Auto-generated from %s at %s
7473 from PyZ3950 import asn1""" % (fn, time_str)
7475 eth_do_module (module, defined_dict)
7478 # Wireshark compiler
7481 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
7483 -b : BER (default is PER)
7484 -u : Unaligned (default is aligned)
7485 -p proto : Protocol name (implies -S). Default is module-name
7486 from input_file (renamed by #.MODULE if present)
7487 -o name : Output files name core (default is <proto>)
7488 -O dir : Output directory
7489 -c cnf_file : Conformance file
7490 -I path : Path for conformance file includes
7491 -e : Create conformance file for exported types
7492 -E : Just create conformance file for exported types
7493 -S : Single output for multiple modules
7494 -s template : Single file output (template is input file
7495 without .c/.h extension)
7496 -k : Keep intermediate files though single file output is used
7497 -L : Suppress #line directive from .cnf file
7498 -D dir : Directory for input_file(s) (default: '.')
7500 input_file(s) : Input ASN.1 file(s)
7502 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
7506 s - internal ASN.1 structure
7507 a - list of assignments
7509 c - conformance values
7510 m - list of compiled modules with dependency
7511 o - list of output files
7518 print "ASN.1 to Wireshark dissector compiler";
7520 opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kL");
7521 except getopt.GetoptError:
7522 eth_usage(); sys.exit(2)
7524 eth_usage(); sys.exit(2)
7529 ectx = EthCtx(conform, output)
7530 ectx.encoding = 'per'
7531 ectx.proto_opt = None
7533 ectx.tag_opt = False
7534 ectx.outnm_opt = None
7539 ectx.justexpcnf = False
7540 ectx.merge_modules = False
7541 ectx.group_by_prot = False
7542 ectx.conform.last_group = 0
7543 ectx.conform.suppress_line = False;
7544 ectx.output.outnm = None
7545 ectx.output.single_file = None
7547 if o in ("-h", "-?"):
7548 eth_usage(); sys.exit(2)
7552 ectx.conform.include_path.append(a)
7555 ectx.justexpcnf = True
7559 warnings.warn("Command line option -X is obsolete and can be removed")
7561 warnings.warn("Command line option -T is obsolete and can be removed")
7564 ectx.conform.read(conf_to_read)
7567 if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-X", "-T"):
7568 pass # already processed
7572 ectx.conform.set_opt(o, par, "commandline", 0)
7574 (ld, yd, pd) = (0, 0, 0);
7575 if ectx.dbg('l'): ld = 1
7576 if ectx.dbg('y'): yd = 1
7577 if ectx.dbg('p'): pd = 2
7578 lexer = lex.lex(debug=ld)
7579 yacc.yacc(method='LALR', debug=yd)
7580 g_conform = ectx.conform
7585 if (ectx.srcdir): fn = ectx.srcdir + '/' + fn
7587 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
7590 if (ectx.merge_modules): # common output for all module
7593 eth_do_module(module, ectx)
7595 ectx.eth_do_output()
7596 elif (ectx.groups()): # group by protocols/group
7599 if (ectx.group_by_prot): # group by protocols
7601 prot = module.get_proto(ectx)
7602 if prot not in pr2gr:
7603 pr2gr[prot] = len(groups)
7605 groups[pr2gr[prot]].append(module)
7606 else: # group by groups
7611 eth_do_module(module, ectx)
7613 ectx.eth_do_output()
7614 else: # output for each module
7617 eth_do_module(module, ectx)
7619 ectx.eth_do_output()
7625 ectx.conform.dbg_print()
7626 if not ectx.justexpcnf:
7627 ectx.conform.unused_report()
7630 ectx.output.dbg_print()
7631 ectx.output.make_single_file()
7637 if len (sys.argv) == 1:
7639 s = raw_input ('Query: ')
7642 testfn (s, 'console', {})
7645 for fn in sys.argv [1:]:
7647 testfn (f.read (), fn, defined_dict)
7652 #--- BODY ---------------------------------------------------------------------
7654 if __name__ == '__main__':
7655 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
7660 #------------------------------------------------------------------------------