5 # ASN.1 to Wireshark dissector compiler
6 # Copyright 2004 Tomas Kukosa
8 # SPDX-License-Identifier: MIT
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 # https://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 # https://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
54 # Fallback: use lex.py and yacc from the tools directory within the
55 # Wireshark source tree if python-ply is not installed.
59 if sys
.version_info
[0] < 3:
60 from string
import maketrans
63 # OID name -> number conversion table
69 '0/recommendation' : 0,
98 '0/administration' : 2,
99 '0/network-operator' : 3,
100 '0/identified-organization' : 4,
101 '0/r-recommendation' : 5,
105 '1/registration-authority' : 1,
107 '1/identified-organization' : 3,
108 '/joint-iso-itu-t' : 2,
109 '/joint-iso-ccitt' : 2,
110 '2/presentation' : 0,
112 '2/association-control' : 2,
113 '2/reliable-transfer' : 3,
114 '2/remote-operations' : 4,
122 '2/osi-management' : 9,
123 '2/transaction-processing' : 10,
125 '2/distinguished-object-reference' : 11,
126 '2/reference-data-transfe' : 12,
127 '2/network-layer' : 13,
128 '2/network-layer-management' : 13,
129 '2/transport-layer' : 14,
130 '2/transport-layer-management' : 14,
131 '2/datalink-layer' : 15,
132 '2/datalink-layer-managemen' : 15,
133 '2/datalink-layer-management-information' : 15,
135 '2/registration-procedures' : 17,
136 '2/registration-procedure' : 17,
137 '2/physical-layer' : 18,
138 '2/physical-layer-management' : 18,
141 '2/generic-upper-layers-security' : 20,
143 '2/transport-layer-security-protocol' : 21,
144 '2/network-layer-security-protocol' : 22,
145 '2/international-organizations' : 23,
146 '2/internationalRA' : 23,
153 ITEM_FIELD_NAME
= '_item'
154 UNTAG_TYPE_NAME
= '_untag'
157 return id.replace('-', '_').replace('.', '_').replace('&', '_')
165 class LexError(Exception):
166 def __init__(self
, tok
, filename
=None):
168 self
.filename
= filename
169 self
.msg
= "Unexpected character %r" % (self
.tok
.value
[0])
170 Exception.__init
__(self
, self
.msg
)
172 return "%s:%d: %s" % (self
.filename
, self
.tok
.lineno
, self
.msg
)
176 class ParseError(Exception):
177 def __init__(self
, tok
, filename
=None):
179 self
.filename
= filename
180 self
.msg
= "Unexpected token %s(%r)" % (self
.tok
.type, self
.tok
.value
)
181 Exception.__init
__(self
, self
.msg
)
183 return "%s:%d: %s" % (self
.filename
, self
.tok
.lineno
, self
.msg
)
187 class DuplicateError(Exception):
188 def __init__(self
, type, ident
):
191 self
.msg
= "Duplicate %s for %s" % (self
.type, self
.ident
)
192 Exception.__init
__(self
, self
.msg
)
197 class CompError(Exception):
198 def __init__(self
, msg
):
200 Exception.__init
__(self
, self
.msg
)
207 ('braceignore','exclusive'),
211 ('left', 'UNION', 'BAR'),
212 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
214 # 11 ASN.1 lexical items
217 r
'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
218 r
'\.\.' : 'RANGE', # 11.17 Range separator
219 r
'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
220 r
'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
221 r
'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
222 # 11.26 Single character lexical items
237 #r"'" : 'APOSTROPHE',
240 r
'\!' : 'EXCLAMATION',
241 r
'\^' : 'CIRCUMFLEX',
246 # 11.27 Reserved words
248 # all keys in reserved_words must start w/ upper case
251 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
253 'APPLICATION' : 'APPLICATION',
254 'AUTOMATIC' : 'AUTOMATIC',
257 'BOOLEAN' : 'BOOLEAN',
259 'CHARACTER' : 'CHARACTER',
262 'COMPONENT' : 'COMPONENT',
263 'COMPONENTS' : 'COMPONENTS',
264 'CONSTRAINED' : 'CONSTRAINED',
265 'CONTAINING' : 'CONTAINING',
266 'DEFAULT' : 'DEFAULT',
267 'DEFINITIONS' : 'DEFINITIONS',
268 'EMBEDDED' : 'EMBEDDED',
269 # 'ENCODED' : 'ENCODED',
271 'ENUMERATED' : 'ENUMERATED',
272 # 'EXCEPT' : 'EXCEPT',
273 'EXPLICIT' : 'EXPLICIT',
274 'EXPORTS' : 'EXPORTS',
275 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
276 'EXTERNAL' : 'EXTERNAL',
279 'GeneralizedTime' : 'GeneralizedTime',
280 'IDENTIFIER' : 'IDENTIFIER',
281 'IMPLICIT' : 'IMPLICIT',
282 # 'IMPLIED' : 'IMPLIED',
283 'IMPORTS' : 'IMPORTS',
284 'INCLUDES' : 'INCLUDES',
285 'INSTANCE' : 'INSTANCE',
286 'INTEGER' : 'INTEGER',
287 'INTERSECTION' : 'INTERSECTION',
290 'MINUS-INFINITY' : 'MINUS_INFINITY',
293 'ObjectDescriptor' : 'ObjectDescriptor',
296 'OPTIONAL' : 'OPTIONAL',
297 'PATTERN' : 'PATTERN',
299 'PLUS-INFINITY' : 'PLUS_INFINITY',
300 'PRESENT' : 'PRESENT',
301 'PRIVATE' : 'PRIVATE',
303 'RELATIVE-OID' : 'RELATIVE_OID',
304 'SEQUENCE' : 'SEQUENCE',
308 'SUCCESSORS' : 'SUCCESSORS',
312 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
315 'UNIVERSAL' : 'UNIVERSAL',
316 'UTCTime' : 'UTCTime',
318 # X.208 obsolete but still used
320 'DEFINED' : 'DEFINED',
323 for k
in list(static_tokens
.keys()):
324 if static_tokens
[k
] is None:
325 static_tokens
[k
] = k
327 StringTypes
= ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
328 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
331 # Effective permitted-alphabet constraints are PER-visible only
332 # for the known-multiplier character string types (X.691 27.1)
334 # XXX: This should include BMPString (UCS2) and UniversalString (UCS4),
335 # but asn2wrs only suports the RestrictedCharacterStringValue
336 # notation of "cstring", but not that of "CharacterStringList",
337 # "Quadruple", or "Tuple" (See X.680 41.8), and packet-per.c does
338 # not support members of the permitted-alphabet being outside the
339 # ASCII range. We don't currently have any ASN.1 modules that need it,
341 KnownMultiplierStringTypes
= ('NumericString', 'PrintableString', 'IA5String',
342 'ISO646String', 'VisibleString')
344 for s
in StringTypes
:
345 reserved_words
[s
+ 'String'] = s
+ 'String'
347 tokens
= list(static_tokens
.values()) \
348 + list(reserved_words
.values()) \
349 + ['BSTRING', 'HSTRING', 'QSTRING',
350 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
351 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
354 cur_mod
= __import__ (__name__
) # XXX blech!
356 for (k
, v
) in list(static_tokens
.items ()):
357 cur_mod
.__dict
__['t_' + v
] = k
359 # 11.10 Binary strings
364 # 11.12 Hexadecimal strings
373 def t_UCASE_IDENT (t
):
374 r
"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
375 if (is_class_ident(t
.value
)): t
.type = 'CLASS_IDENT'
376 if (is_class_syntax(t
.value
)): t
.type = t
.value
377 t
.type = reserved_words
.get(t
.value
, t
.type)
380 lcase_ident_assigned
= {}
381 def t_LCASE_IDENT (t
):
382 r
"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
383 if (not in_oid
and (t
.value
in lcase_ident_assigned
)): t
.type = 'LCASE_IDENT_ASSIGNED'
387 def t_REAL_NUMBER (t
):
388 r
"[0-9]+\.[0-9]*(?!\.)"
397 pyquote_str
= 'PYQUOTE'
399 r
"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
400 if (t
.value
.find("\n") >= 0) : t
.lexer
.lineno
+= 1
401 if t
.value
[2:2+len (pyquote_str
)] == pyquote_str
:
402 t
.value
= t
.value
[2+len(pyquote_str
):]
403 t
.value
= t
.value
.lstrip ()
412 t
.lexer
.lineno
+= t
.value
.count("\n")
416 raise LexError(t
, input_file
)
418 # state 'braceignore'
420 def t_braceignore_lbrace(t
):
424 def t_braceignore_rbrace(t
):
427 # If closing brace, return token
428 if t
.lexer
.level
== 0:
432 def t_braceignore_QSTRING (t
):
434 t
.lexer
.lineno
+= t
.value
.count("\n")
436 def t_braceignore_COMMENT(t
):
437 r
"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
438 if (t
.value
.find("\n") >= 0) : t
.lexer
.lineno
+= 1
440 def t_braceignore_nonspace(t
):
441 r
'[^\s\{\}\"-]+|-(?!-)'
443 t_braceignore_ignore
= " \t\r"
445 def t_braceignore_NEWLINE(t
):
447 t
.lexer
.lineno
+= t
.value
.count("\n")
449 def t_braceignore_error(t
):
453 def __init__ (self
, defined_dict
, indent
= 0):
454 self
.tags_def
= 'EXPLICIT' # default = explicit
456 self
.assignments
= {}
457 self
.dependencies
= {}
459 self
.defined_dict
= defined_dict
462 return " " * (4 * self
.indent_lev
)
467 assert (self
.indent_lev
>= 0)
468 def register_assignment (self
, ident
, val
, dependencies
):
469 if ident
in self
.assignments
:
470 raise DuplicateError("assignment", ident
)
471 if ident
in self
.defined_dict
:
472 raise Exception("cross-module duplicates for %s" % ident
)
473 self
.defined_dict
[ident
] = 1
474 self
.assignments
[ident
] = val
475 self
.dependencies
[ident
] = dependencies
477 # return "#%s depends on %s" % (ident, str (dependencies))
478 def register_pyquote (self
, val
):
479 self
.pyquotes
.append (val
)
481 def output_assignments (self
):
484 assign_keys
= list(self
.assignments
.keys())
485 to_output_count
= len (assign_keys
)
488 for (ident
, val
) in list(self
.assignments
.items ()):
489 if ident
in already_output
:
492 for d
in self
.dependencies
[ident
]:
493 if ((d
not in already_output
) and
497 text_list
.append ("%s=%s" % (ident
,
498 self
.assignments
[ident
]))
499 already_output
[ident
] = 1
502 assert (to_output_count
>= 0)
504 if to_output_count
== 0:
506 # OK, we detected a cycle
508 for ident
in list(self
.assignments
.keys ()):
509 if ident
not in already_output
:
510 depend_list
= [d
for d
in self
.dependencies
[ident
] if d
in assign_keys
]
511 cycle_list
.append ("%s(%s)" % (ident
, ",".join (depend_list
)))
513 text_list
.append ("# Cycle XXX " + ",".join (cycle_list
))
514 for (ident
, val
) in list(self
.assignments
.items ()):
515 if ident
not in already_output
:
516 text_list
.append ("%s=%s" % (ident
, self
.assignments
[ident
]))
519 return "\n".join (text_list
)
520 def output_pyquotes (self
):
521 return "\n".join (self
.pyquotes
)
522 def make_new_name (self
):
524 return "_compiler_generated_name_%d" % (self
.name_ctr
,)
526 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
530 EF_WS_DLL
= 0x0010 # exported from shared library
539 #--- common dependency computation ---
540 # Input : list of items
541 # dictionary with lists of dependency
544 # Output : list of two outputs:
545 # [0] list of items in dependency
546 # [1] list of cycle dependency cycles
547 def dependency_compute(items
, dependency
, map_fn
= lambda t
: t
, ignore_fn
= lambda t
: False):
550 x
= {} # already emitted
551 #print '# Dependency computation'
554 #print 'Continue: %s : %s' % (t, (map_fn(t))
557 stackx
= {t
: dependency
.get(t
, [])[:]}
558 #print 'Push: %s : %s' % (t, str(stackx[t]))
560 if stackx
[stack
[-1]]: # has dependencies
561 d
= stackx
[stack
[-1]].pop(0)
562 if map_fn(d
) in x
or ignore_fn(d
):
564 if d
in stackx
: # cyclic dependency
567 c
= [d
] + c
[0:c
.index(d
)+1]
570 #print 'Cyclic: %s ' % (' -> '.join(c))
573 stackx
[d
] = dependency
.get(d
, [])[:]
574 #print 'Push: %s : %s' % (d, str(stackx[d]))
576 #print 'Pop: %s' % (stack[-1])
577 del stackx
[stack
[-1]]
578 e
= map_fn(stack
.pop())
581 #print 'Add: %s' % (e)
584 return (item_ord
, item_cyc
)
586 # Given a filename, return a relative path from the current directory
587 def relpath(filename
):
588 return os
.path
.relpath(filename
)
590 # Given a filename, return a relative path from epan/dissectors
591 def rel_dissector_path(filename
):
592 path_parts
= os
.path
.abspath(filename
).split(os
.sep
)
593 while (len(path_parts
) > 3 and path_parts
[0] != 'asn1'):
595 path_parts
.insert(0, '.')
596 return '/'.join(path_parts
)
599 #--- EthCtx -------------------------------------------------------------------
601 def __init__(self
, conform
, output
, indent
= 0):
602 self
.conform
= conform
604 self
.conform
.ectx
= self
605 self
.output
.ectx
= self
606 self
.encoding
= 'per'
608 self
.default_oid_variant
= ''
609 self
.default_opentype_variant
= ''
610 self
.default_containing_variant
= '_pdu_new'
611 self
.default_embedded_pdv_cb
= None
612 self
.default_external_type_cb
= None
613 self
.remove_prefix
= None
615 self
.emitted_pdu
= {}
618 self
.all_type_attr
= {}
622 def encp(self
): # encoding protocol
627 def Per(self
): return self
.encoding
== 'per'
628 def Ber(self
): return self
.encoding
== 'ber'
629 def Oer(self
): return self
.encoding
== 'oer'
630 def Aligned(self
): return self
.aligned
631 def Unaligned(self
): return not self
.aligned
632 def NeedTags(self
): return self
.tag_opt
or self
.Ber()
633 def NAPI(self
): return False # disable planned features
635 def Module(self
): # current module name
636 return self
.modules
[-1][0]
639 return self
.group_by_prot
or (self
.conform
.last_group
> 0)
642 if (self
.dbgopt
.find(d
) >= 0):
647 def value_max(self
, a
, b
):
648 if (a
== 'MAX') or (b
== 'MAX'): return 'MAX'
649 if a
== 'MIN': return b
650 if b
== 'MIN': return a
652 if (int(a
) > int(b
)):
656 except (ValueError, TypeError):
658 return "MAX((%s),(%s))" % (a
, b
)
660 def value_min(self
, a
, b
):
661 if (a
== 'MIN') or (b
== 'MIN'): return 'MIN'
662 if a
== 'MAX': return b
663 if b
== 'MAX': return a
665 if (int(a
) < int(b
)):
669 except (ValueError, TypeError):
671 return "MIN((%s),(%s))" % (a
, b
)
673 def value_get_eth(self
, val
):
674 if isinstance(val
, Value
):
675 return val
.to_str(self
)
677 if val
in self
.value
:
678 ethname
= self
.value
[val
]['ethname']
681 def value_get_val(self
, nm
):
684 if self
.value
[nm
]['import']:
685 v
= self
.get_val_from_all(nm
, self
.value
[nm
]['import'])
687 msg
= 'Need value of imported value identifier %s from %s (%s)' % (nm
, self
.value
[nm
]['import'], self
.value
[nm
]['proto'])
688 warnings
.warn_explicit(msg
, UserWarning, '', 0)
692 val
= self
.value
[nm
]['value']
693 if isinstance (val
, Value
):
694 val
= val
.to_str(self
)
696 msg
= 'Need value of unknown value identifier %s' % (nm
)
697 warnings
.warn_explicit(msg
, UserWarning, '', 0)
700 def eth_get_type_attr(self
, type):
701 #print "eth_get_type_attr(%s)" % (type)
703 while (not self
.type[type]['import']):
704 val
= self
.type[type]['val']
707 while (val
.type == 'TaggedType'):
709 ttype
+= '/' + UNTAG_TYPE_NAME
710 if (val
.type != 'Type_Ref'):
720 if (self
.type[t
]['import']):
721 attr
.update(self
.type[t
]['attr'])
722 attr
.update(self
.eth_get_type_attr_from_all(t
, self
.type[t
]['import']))
723 elif (self
.type[t
]['val'].type == 'SelectionType'):
724 val
= self
.type[t
]['val']
725 (ftype
, display
) = val
.eth_ftype(self
)
726 attr
.update({ 'TYPE' : ftype
, 'DISPLAY' : display
,
727 'STRINGS' : val
.eth_strings(), 'BITMASK' : '0' })
729 attr
.update(self
.type[t
]['attr'])
730 attr
.update(self
.eth_type
[self
.type[t
]['ethname']]['attr'])
731 if attr
['STRINGS'].startswith('VALS64(') and '|BASE_VAL64_STRING' not in attr
['DISPLAY']:
732 attr
['DISPLAY'] += '|BASE_VAL64_STRING'
736 def eth_get_type_attr_from_all(self
, type, module
):
738 if module
in self
.all_type_attr
and type in self
.all_type_attr
[module
]:
739 attr
= self
.all_type_attr
[module
][type]
742 def get_ttag_from_all(self
, type, module
):
744 if module
in self
.all_tags
and type in self
.all_tags
[module
]:
745 ttag
= self
.all_tags
[module
][type]
748 def get_val_from_all(self
, nm
, module
):
750 if module
in self
.all_vals
and nm
in self
.all_vals
[module
]:
751 val
= self
.all_vals
[module
][nm
]
754 def get_obj_repr(self
, ident
, flds
=[], not_flds
=[]):
755 def set_type_fn(cls
, field
, fnfield
):
756 obj
[fnfield
+ '_fn'] = 'NULL'
757 obj
[fnfield
+ '_pdu'] = 'NULL'
758 if field
in val
and isinstance(val
[field
], Type_Ref
):
759 p
= val
[field
].eth_type_default_pars(self
, '')
760 obj
[fnfield
+ '_fn'] = p
['TYPE_REF_FN']
761 obj
[fnfield
+ '_fn'] = obj
[fnfield
+ '_fn'] % p
# one iteration
762 if (self
.conform
.check_item('PDU', cls
+ '.' + field
)):
763 obj
[fnfield
+ '_pdu'] = 'dissect_' + self
.field
[val
[field
].val
]['ethname']
765 # end of get_type_fn()
766 obj
= { '_name' : ident
, '_ident' : asn2c(ident
)}
767 obj
['_class'] = self
.oassign
[ident
].cls
768 obj
['_module'] = self
.oassign
[ident
].module
769 val
= self
.oassign
[ident
].val
776 for f
in list(val
.keys()):
777 if isinstance(val
[f
], Node
):
778 obj
[f
] = val
[f
].fld_obj_repr(self
)
781 if (obj
['_class'] == 'TYPE-IDENTIFIER') or (obj
['_class'] == 'ABSTRACT-SYNTAX'):
782 set_type_fn(obj
['_class'], '&Type', '_type')
783 if (obj
['_class'] == 'OPERATION'):
784 set_type_fn(obj
['_class'], '&ArgumentType', '_argument')
785 set_type_fn(obj
['_class'], '&ResultType', '_result')
786 if (obj
['_class'] == 'ERROR'):
787 set_type_fn(obj
['_class'], '&ParameterType', '_parameter')
790 #--- eth_reg_module -----------------------------------------------------------
791 def eth_reg_module(self
, module
):
792 #print "eth_reg_module(module='%s')" % (module)
793 name
= module
.get_name()
794 self
.modules
.append([name
, module
.get_proto(self
)])
795 if name
in self
.module
:
796 raise DuplicateError("module", name
)
797 self
.module
[name
] = []
798 self
.module_ord
.append(name
)
800 #--- eth_module_dep_add ------------------------------------------------------------
801 def eth_module_dep_add(self
, module
, dep
):
802 self
.module
[module
].append(dep
)
804 #--- eth_exports ------------------------------------------------------------
805 def eth_exports(self
, exports
):
806 self
.exports_all
= False
807 if ((len(exports
) == 1) and (exports
[0] == 'ALL')):
808 self
.exports_all
= True
811 if isinstance(e
, Type_Ref
):
812 self
.exports
.append(e
.val
)
813 elif isinstance(e
, Class_Ref
):
814 self
.cexports
.append(e
.val
)
816 self
.vexports
.append(e
)
818 #--- eth_reg_assign ---------------------------------------------------------
819 def eth_reg_assign(self
, ident
, val
, virt
=False):
820 #print("eth_reg_assign(ident='%s')" % (ident), 'module=', self.Module())
821 if ident
in self
.assign
:
822 raise DuplicateError("assignment", ident
)
823 self
.assign
[ident
] = { 'val' : val
, 'virt' : virt
}
824 self
.assign_ord
.append(ident
)
825 if (self
.exports_all
):
826 self
.exports
.append(ident
)
828 #--- eth_reg_vassign --------------------------------------------------------
829 def eth_reg_vassign(self
, vassign
):
830 ident
= vassign
.ident
831 #print "eth_reg_vassign(ident='%s')" % (ident)
832 if ident
in self
.vassign
:
833 raise DuplicateError("value assignment", ident
)
834 self
.vassign
[ident
] = vassign
835 self
.vassign_ord
.append(ident
)
836 if (self
.exports_all
):
837 self
.vexports
.append(ident
)
839 #--- eth_reg_oassign --------------------------------------------------------
840 def eth_reg_oassign(self
, oassign
):
841 ident
= oassign
.ident
842 #print "eth_reg_oassign(ident='%s')" % (ident)
843 if ident
in self
.oassign
:
844 if self
.oassign
[ident
] == oassign
:
845 return # OK - already defined
847 raise DuplicateError("information object assignment", ident
)
848 self
.oassign
[ident
] = oassign
849 self
.oassign_ord
.append(ident
)
850 self
.oassign_cls
.setdefault(oassign
.cls
, []).append(ident
)
852 #--- eth_import_type --------------------------------------------------------
853 def eth_import_type(self
, ident
, mod
, proto
):
854 #print ("eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto))
855 if ident
in self
.type:
856 #print ("already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-')))
857 if not self
.type[ident
]['import'] and (self
.type[ident
]['module'] == mod
) :
858 return # OK - already defined
859 elif self
.type[ident
]['import'] and (self
.type[ident
]['import'] == mod
) :
860 return # OK - already imported
862 raise DuplicateError("type", ident
)
863 self
.type[ident
] = {'import' : mod
, 'proto' : proto
,
865 self
.type[ident
]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
866 'STRINGS' : 'NULL', 'BITMASK' : '0' }
867 mident
= "$%s$%s" % (mod
, ident
)
868 if (self
.conform
.check_item('TYPE_ATTR', mident
)):
869 self
.type[ident
]['attr'].update(self
.conform
.use_item('TYPE_ATTR', mident
))
871 self
.type[ident
]['attr'].update(self
.conform
.use_item('TYPE_ATTR', ident
))
872 if (self
.conform
.check_item('IMPORT_TAG', mident
)):
873 self
.conform
.copy_item('IMPORT_TAG', ident
, mident
)
874 self
.type_imp
.append(ident
)
876 #--- dummy_import_type --------------------------------------------------------
877 def dummy_import_type(self
, ident
):
879 if ident
in self
.type:
880 raise Exception("Try to dummy import for existing type :%s" % ident
)
881 ethtype
= asn2c(ident
)
882 self
.type[ident
] = {'import' : 'xxx', 'proto' : 'xxx',
883 'ethname' : ethtype
}
884 self
.type[ident
]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
885 'STRINGS' : 'NULL', 'BITMASK' : '0' }
886 self
.eth_type
[ethtype
] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
887 print("Dummy imported: %s (%s)" % (ident
, ethtype
))
890 #--- eth_import_class --------------------------------------------------------
891 def eth_import_class(self
, ident
, mod
, proto
):
892 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
893 if ident
in self
.objectclass
:
894 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
895 if not self
.objectclass
[ident
]['import'] and (self
.objectclass
[ident
]['module'] == mod
) :
896 return # OK - already defined
897 elif self
.objectclass
[ident
]['import'] and (self
.objectclass
[ident
]['import'] == mod
) :
898 return # OK - already imported
900 raise DuplicateError("object class", ident
)
901 self
.objectclass
[ident
] = {'import' : mod
, 'proto' : proto
,
903 self
.objectclass_imp
.append(ident
)
905 #--- eth_import_value -------------------------------------------------------
906 def eth_import_value(self
, ident
, mod
, proto
):
907 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
908 if ident
in self
.value
:
909 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
910 if not self
.value
[ident
]['import'] and (self
.value
[ident
]['module'] == mod
) :
911 return # OK - already defined
912 elif self
.value
[ident
]['import'] and (self
.value
[ident
]['import'] == mod
) :
913 return # OK - already imported
915 raise DuplicateError("value", ident
)
916 self
.value
[ident
] = {'import' : mod
, 'proto' : proto
,
918 self
.value_imp
.append(ident
)
920 #--- eth_sel_req ------------------------------------------------------------
921 def eth_sel_req(self
, typ
, sel
):
922 key
= typ
+ '.' + sel
923 if key
not in self
.sel_req
:
924 self
.sel_req
[key
] = { 'typ' : typ
, 'sel' : sel
}
925 self
.sel_req_ord
.append(key
)
928 #--- eth_comp_req ------------------------------------------------------------
929 def eth_comp_req(self
, type):
930 self
.comp_req_ord
.append(type)
932 #--- eth_dep_add ------------------------------------------------------------
933 def eth_dep_add(self
, type, dep
):
934 if type not in self
.type_dep
:
935 self
.type_dep
[type] = []
936 self
.type_dep
[type].append(dep
)
938 #--- eth_reg_type -----------------------------------------------------------
939 def eth_reg_type(self
, ident
, val
, mod
=None):
940 #print("eth_reg_type(ident='%s', type='%s')" % (ident, val.type))
941 if ident
in self
.type:
942 if self
.type[ident
]['import'] and (self
.type[ident
]['import'] == self
.Module()) :
943 # replace imported type
945 self
.type_imp
.remove(ident
)
947 #print('DuplicateError: import=', self.type[ident]['import'], 'module=', self.Module())
948 raise DuplicateError("type", ident
)
950 self
.type[ident
] = { 'val' : val
, 'import' : None }
951 self
.type[ident
]['module'] = self
.Module()
952 self
.type[ident
]['proto'] = self
.proto
953 if len(ident
.split('/')) > 1:
954 self
.type[ident
]['tname'] = val
.eth_tname()
956 self
.type[ident
]['tname'] = asn2c(ident
)
958 mident
= "$%s$%s" % (mod
, ident
)
961 self
.type[ident
]['export'] = self
.conform
.use_item('EXPORTS', ident
)
962 self
.type[ident
]['enum'] = self
.conform
.use_item('MAKE_ENUM', ident
)
963 self
.type[ident
]['vals_ext'] = self
.conform
.use_item('USE_VALS_EXT', ident
)
964 self
.type[ident
]['user_def'] = self
.conform
.use_item('USER_DEFINED', ident
)
965 if mident
and self
.conform
.check_item('NO_EMIT', mident
) :
966 self
.type[ident
]['no_emit'] = self
.conform
.use_item('NO_EMIT', mident
)
968 self
.type[ident
]['no_emit'] = self
.conform
.use_item('NO_EMIT', ident
)
969 self
.type[ident
]['tname'] = self
.conform
.use_item('TYPE_RENAME', ident
, val_dflt
=self
.type[ident
]['tname'])
970 self
.type[ident
]['ethname'] = ''
971 if (val
.type == 'Type_Ref') or (val
.type == 'TaggedType') or (val
.type == 'SelectionType') :
972 self
.type[ident
]['attr'] = {}
974 (ftype
, display
) = val
.eth_ftype(self
)
975 self
.type[ident
]['attr'] = { 'TYPE' : ftype
, 'DISPLAY' : display
,
976 'STRINGS' : val
.eth_strings(), 'BITMASK' : '0' }
977 self
.type[ident
]['attr'].update(self
.conform
.use_item('TYPE_ATTR', ident
))
978 self
.type_ord
.append(ident
)
980 if (self
.conform
.check_item('PDU', ident
)):
981 self
.eth_reg_field(ident
, ident
, impl
=val
.HasImplicitTag(self
), pdu
=self
.conform
.use_item('PDU', ident
))
983 #--- eth_reg_objectclass ----------------------------------------------------------
984 def eth_reg_objectclass(self
, ident
, val
):
985 #print "eth_reg_objectclass(ident='%s')" % (ident)
986 if ident
in self
.objectclass
:
987 if self
.objectclass
[ident
]['import'] and (self
.objectclass
[ident
]['import'] == self
.Module()) :
988 # replace imported object class
989 del self
.objectclass
[ident
]
990 self
.objectclass_imp
.remove(ident
)
991 elif isinstance(self
.objectclass
[ident
]['val'], Class_Ref
) and \
992 isinstance(val
, Class_Ref
) and \
993 (self
.objectclass
[ident
]['val'].val
== val
.val
):
994 pass # ignore duplicated CLASS1 ::= CLASS2
996 raise DuplicateError("object class", ident
)
997 self
.objectclass
[ident
] = { 'import' : None, 'module' : self
.Module(), 'proto' : self
.proto
}
998 self
.objectclass
[ident
]['val'] = val
999 self
.objectclass
[ident
]['export'] = self
.conform
.use_item('EXPORTS', ident
)
1000 self
.objectclass_ord
.append(ident
)
1002 #--- eth_reg_value ----------------------------------------------------------
1003 def eth_reg_value(self
, ident
, type, value
, ethname
=None):
1004 #print "eth_reg_value(ident='%s')" % (ident)
1005 if ident
in self
.value
:
1006 if self
.value
[ident
]['import'] and (self
.value
[ident
]['import'] == self
.Module()) :
1007 # replace imported value
1008 del self
.value
[ident
]
1009 self
.value_imp
.remove(ident
)
1011 self
.value
[ident
]['ethname'] = ethname
1014 raise DuplicateError("value", ident
)
1015 self
.value
[ident
] = { 'import' : None, 'module' : self
.Module(), 'proto' : self
.proto
,
1016 'type' : type, 'value' : value
,
1018 self
.value
[ident
]['export'] = self
.conform
.use_item('EXPORTS', ident
)
1019 self
.value
[ident
]['ethname'] = ''
1020 if (ethname
): self
.value
[ident
]['ethname'] = ethname
1021 self
.value_ord
.append(ident
)
1023 #--- eth_reg_field ----------------------------------------------------------
1024 def eth_reg_field(self
, ident
, type, idx
='', parent
=None, impl
=False, pdu
=None):
1025 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
1026 if ident
in self
.field
:
1027 if pdu
and (type == self
.field
[ident
]['type']):
1028 pass # OK already created PDU
1030 raise DuplicateError("field", ident
)
1031 self
.field
[ident
] = {'type' : type, 'idx' : idx
, 'impl' : impl
, 'pdu' : pdu
,
1032 'modified' : '', 'attr' : {} }
1033 name
= ident
.split('/')[-1]
1034 if self
.remove_prefix
and name
.startswith(self
.remove_prefix
):
1035 name
= name
[len(self
.remove_prefix
):]
1037 if len(ident
.split('/')) > 1 and name
== ITEM_FIELD_NAME
: # Sequence/Set of type
1038 if len(self
.field
[ident
]['type'].split('/')) > 1:
1039 self
.field
[ident
]['attr']['NAME'] = '"%s item"' % ident
.split('/')[-2]
1040 self
.field
[ident
]['attr']['ABBREV'] = asn2c(ident
.split('/')[-2] + name
)
1042 self
.field
[ident
]['attr']['NAME'] = '"%s"' % self
.field
[ident
]['type']
1043 self
.field
[ident
]['attr']['ABBREV'] = asn2c(self
.field
[ident
]['type'])
1045 self
.field
[ident
]['attr']['NAME'] = '"%s"' % name
1046 self
.field
[ident
]['attr']['ABBREV'] = asn2c(name
)
1047 if self
.conform
.check_item('FIELD_ATTR', ident
):
1048 self
.field
[ident
]['modified'] = '#' + str(id(self
))
1049 self
.field
[ident
]['attr'].update(self
.conform
.use_item('FIELD_ATTR', ident
))
1051 self
.field
[ident
]['pdu']['export'] = (self
.conform
.use_item('EXPORTS', ident
+ '_PDU') != 0)
1052 self
.pdu_ord
.append(ident
)
1054 self
.field_ord
.append(ident
)
1056 self
.eth_dep_add(parent
, type)
1058 def eth_dummy_eag_field_required(self
):
1059 if (not self
.dummy_eag_field
):
1060 self
.dummy_eag_field
= 'eag_field'
1062 #--- eth_clean --------------------------------------------------------------
1063 def eth_clean(self
):
1064 self
.proto
= self
.proto_opt
1065 #--- ASN.1 tables ----------------
1067 self
.assign_ord
= []
1076 self
.sel_req_ord
= []
1077 self
.comp_req_ord
= []
1079 self
.vassign_ord
= []
1083 self
.objectclass
= {}
1084 self
.objectclass_ord
= []
1085 self
.objectclass_imp
= []
1087 self
.oassign_ord
= []
1088 self
.oassign_cls
= {}
1089 #--- Modules ------------
1091 self
.exports_all
= False
1095 #--- types -------------------
1097 self
.eth_type_ord
= []
1098 self
.eth_export_ord
= []
1099 self
.eth_type_dupl
= {}
1101 #--- value dependencies -------------------
1103 #--- values -------------------
1105 self
.eth_value_ord
= []
1106 #--- fields -------------------------
1108 self
.eth_hf_ord
= []
1109 self
.eth_hfpdu_ord
= []
1110 self
.eth_hf_dupl
= {}
1111 self
.dummy_eag_field
= None
1112 #--- type dependencies -------------------
1113 self
.eth_type_ord1
= []
1114 self
.eth_dep_cycle
= []
1115 self
.dep_cycle_eth_type
= {}
1116 #--- value dependencies and export -------------------
1117 self
.eth_value_ord1
= []
1118 self
.eth_vexport_ord
= []
1120 #--- eth_prepare ------------------------------------------------------------
1121 def eth_prepare(self
):
1122 self
.eproto
= asn2c(self
.proto
)
1124 #--- dummy types/fields for PDU registration ---
1126 if (self
.conform
.check_item('PDU', nm
)):
1127 self
.eth_reg_type('_dummy/'+nm
, NullType())
1128 self
.eth_reg_field(nm
, '_dummy/'+nm
, pdu
=self
.conform
.use_item('PDU', nm
))
1130 #--- required PDUs ----------------------------
1131 for t
in self
.type_ord
:
1132 pdu
= self
.type[t
]['val'].eth_need_pdu(self
)
1133 if not pdu
: continue
1136 pdu
['hidden'] = False
1137 pdu
['need_decl'] = True
1138 if f
not in self
.field
:
1139 self
.eth_reg_field(f
, f
, pdu
=pdu
)
1141 #--- values -> named values -------------------
1143 for v
in self
.value_ord
:
1144 if (self
.value
[v
]['type'].type == 'Type_Ref') or self
.conform
.check_item('ASSIGN_VALUE_TO_TYPE', v
):
1145 if self
.conform
.check_item('ASSIGN_VALUE_TO_TYPE', v
):
1146 tnm
= self
.conform
.use_item('ASSIGN_VALUE_TO_TYPE', v
)
1148 tnm
= self
.value
[v
]['type'].val
1149 if tnm
in self
.type \
1150 and not self
.type[tnm
]['import'] \
1151 and (self
.type[tnm
]['val'].type == 'IntegerType'):
1152 self
.type[tnm
]['val'].add_named_value(v
, self
.value
[v
]['value'])
1153 self
.value
[v
]['no_emit'] = True
1154 t_for_update
[tnm
] = True
1155 for t
in list(t_for_update
.keys()):
1156 self
.type[t
]['attr']['STRINGS'] = self
.type[t
]['val'].eth_strings()
1157 self
.type[t
]['attr'].update(self
.conform
.use_item('TYPE_ATTR', t
))
1159 #--- required components of ---------------------------
1160 #print "self.comp_req_ord = ", self.comp_req_ord
1161 for t
in self
.comp_req_ord
:
1162 self
.type[t
]['val'].eth_reg_sub(t
, self
, components_available
=True)
1164 #--- required selection types ---------------------------
1165 #print "self.sel_req_ord = ", self.sel_req_ord
1166 for t
in self
.sel_req_ord
:
1167 tt
= self
.sel_req
[t
]['typ']
1168 if tt
not in self
.type:
1169 self
.dummy_import_type(t
)
1170 elif self
.type[tt
]['import']:
1171 self
.eth_import_type(t
, self
.type[tt
]['import'], self
.type[tt
]['proto'])
1173 self
.type[tt
]['val'].sel_req(t
, self
.sel_req
[t
]['sel'], self
)
1175 #--- types -------------------
1176 for t
in self
.type_imp
: # imported types
1178 self
.eth_type
[nm
] = { 'import' : self
.type[t
]['import'],
1179 'proto' : asn2c(self
.type[t
]['proto']),
1180 'attr' : {}, 'ref' : []}
1181 self
.eth_type
[nm
]['attr'].update(self
.conform
.use_item('ETYPE_ATTR', nm
))
1182 self
.type[t
]['ethname'] = nm
1183 for t
in self
.type_ord
: # dummy import for missing type reference
1184 tp
= self
.type[t
]['val']
1185 #print "X : %s %s " % (t, tp.type)
1186 if isinstance(tp
, TaggedType
):
1187 #print "%s : %s " % (tp.type, t)
1189 if isinstance(tp
, Type_Ref
):
1190 #print "%s : %s ::= %s " % (tp.type, t, tp.val)
1191 if tp
.val
not in self
.type:
1192 self
.dummy_import_type(tp
.val
)
1193 for t
in self
.type_ord
:
1194 nm
= self
.type[t
]['tname']
1195 if ((nm
.find('#') >= 0) or
1196 ((len(t
.split('/'))>1) and
1197 (self
.conform
.get_fn_presence(t
) or self
.conform
.check_item('FN_PARS', t
) or
1198 self
.conform
.get_fn_presence('/'.join((t
,ITEM_FIELD_NAME
))) or self
.conform
.check_item('FN_PARS', '/'.join((t
,ITEM_FIELD_NAME
)))) and
1199 not self
.conform
.check_item('TYPE_RENAME', t
))):
1200 if len(t
.split('/')) == 2 and t
.split('/')[1] == ITEM_FIELD_NAME
: # Sequence of type at the 1st level
1201 nm
= t
.split('/')[0] + t
.split('/')[1]
1202 elif t
.split('/')[-1] == ITEM_FIELD_NAME
: # Sequence/Set of type at next levels
1203 nm
= 'T_' + self
.conform
.use_item('FIELD_RENAME', '/'.join(t
.split('/')[0:-1]), val_dflt
=t
.split('/')[-2]) + t
.split('/')[-1]
1204 elif t
.split('/')[-1] == UNTAG_TYPE_NAME
: # Untagged type
1205 nm
= self
.type['/'.join(t
.split('/')[0:-1])]['ethname'] + '_U'
1207 nm
= 'T_' + self
.conform
.use_item('FIELD_RENAME', t
, val_dflt
=t
.split('/')[-1])
1209 if nm
in self
.eth_type
:
1210 if nm
in self
.eth_type_dupl
:
1211 self
.eth_type_dupl
[nm
].append(t
)
1213 self
.eth_type_dupl
[nm
] = [self
.eth_type
[nm
]['ref'][0], t
]
1214 nm
+= '_%02d' % (len(self
.eth_type_dupl
[nm
])-1)
1215 if nm
in self
.eth_type
:
1216 self
.eth_type
[nm
]['ref'].append(t
)
1218 self
.eth_type_ord
.append(nm
)
1219 self
.eth_type
[nm
] = { 'import' : None, 'proto' : self
.eproto
, 'export' : 0, 'enum' : 0, 'vals_ext' : 0,
1220 'user_def' : EF_TYPE|EF_VALS
, 'no_emit' : EF_TYPE|EF_VALS
,
1221 'val' : self
.type[t
]['val'],
1222 'attr' : {}, 'ref' : [t
]}
1223 self
.type[t
]['ethname'] = nm
1224 if (not self
.eth_type
[nm
]['export'] and self
.type[t
]['export']): # new export
1225 self
.eth_export_ord
.append(nm
)
1226 self
.eth_type
[nm
]['export'] |
= self
.type[t
]['export']
1227 self
.eth_type
[nm
]['enum'] |
= self
.type[t
]['enum']
1228 self
.eth_type
[nm
]['vals_ext'] |
= self
.type[t
]['vals_ext']
1229 self
.eth_type
[nm
]['user_def'] &= self
.type[t
]['user_def']
1230 self
.eth_type
[nm
]['no_emit'] &= self
.type[t
]['no_emit']
1231 if self
.type[t
]['attr'].get('STRINGS') == '$$':
1232 use_ext
= self
.type[t
]['vals_ext']
1234 self
.eth_type
[nm
]['attr']['STRINGS'] = '&%s_ext' % (self
.eth_vals_nm(nm
))
1236 if self
.eth_type
[nm
]['val'].type == 'IntegerType' \
1237 and self
.eth_type
[nm
]['val'].HasConstraint() \
1238 and self
.eth_type
[nm
]['val'].constr
.Needs64b(self
):
1239 self
.eth_type
[nm
]['attr']['STRINGS'] = 'VALS64(%s)' % (self
.eth_vals_nm(nm
))
1241 self
.eth_type
[nm
]['attr']['STRINGS'] = 'VALS(%s)' % (self
.eth_vals_nm(nm
))
1242 self
.eth_type
[nm
]['attr'].update(self
.conform
.use_item('ETYPE_ATTR', nm
))
1243 for t
in self
.eth_type_ord
:
1244 bits
= self
.eth_type
[t
]['val'].eth_named_bits()
1246 for (val
, id) in bits
:
1247 self
.named_bit
.append({'name' : id, 'val' : val
,
1248 'ethname' : 'hf_%s_%s_%s' % (self
.eproto
, t
, asn2c(id)),
1249 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1251 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val
%8]})
1252 if self
.eth_type
[t
]['val'].eth_need_tree():
1253 self
.eth_type
[t
]['tree'] = "ett_%s_%s" % (self
.eth_type
[t
]['proto'], t
)
1255 self
.eth_type
[t
]['tree'] = None
1257 #--- register values from enums ------------
1258 for t
in self
.eth_type_ord
:
1259 if (self
.eth_type
[t
]['val'].eth_has_enum(t
, self
)):
1260 self
.eth_type
[t
]['val'].reg_enum_vals(t
, self
)
1262 #--- value dependencies -------------------
1263 for v
in self
.value_ord
:
1264 if isinstance (self
.value
[v
]['value'], Value
):
1265 dep
= self
.value
[v
]['value'].get_dep()
1267 dep
= self
.value
[v
]['value']
1268 if dep
and dep
in self
.value
:
1269 self
.value_dep
.setdefault(v
, []).append(dep
)
1271 #--- exports all necessary values
1272 for v
in self
.value_ord
:
1273 if not self
.value
[v
]['export']: continue
1274 deparr
= self
.value_dep
.get(v
, [])
1277 if not self
.value
[d
]['import']:
1278 if not self
.value
[d
]['export']:
1279 self
.value
[d
]['export'] = EF_TYPE
1280 deparr
.extend(self
.value_dep
.get(d
, []))
1282 #--- values -------------------
1283 for v
in self
.value_imp
:
1285 self
.eth_value
[nm
] = { 'import' : self
.value
[v
]['import'],
1286 'proto' : asn2c(self
.value
[v
]['proto']),
1288 self
.value
[v
]['ethname'] = nm
1289 for v
in self
.value_ord
:
1290 if (self
.value
[v
]['ethname']):
1292 if (self
.value
[v
]['no_emit']):
1295 self
.eth_value
[nm
] = { 'import' : None,
1296 'proto' : asn2c(self
.value
[v
]['proto']),
1297 'export' : self
.value
[v
]['export'], 'ref' : [v
] }
1298 self
.eth_value
[nm
]['value'] = self
.value
[v
]['value']
1299 self
.eth_value_ord
.append(nm
)
1300 self
.value
[v
]['ethname'] = nm
1302 #--- fields -------------------------
1303 for f
in (self
.pdu_ord
+ self
.field_ord
):
1304 if len(f
.split('/')) > 1 and f
.split('/')[-1] == ITEM_FIELD_NAME
: # Sequence/Set of type
1305 nm
= self
.conform
.use_item('FIELD_RENAME', '/'.join(f
.split('/')[0:-1]), val_dflt
=f
.split('/')[-2]) + f
.split('/')[-1]
1307 nm
= f
.split('/')[-1]
1308 nm
= self
.conform
.use_item('FIELD_RENAME', f
, val_dflt
=nm
)
1310 if (self
.field
[f
]['pdu']):
1312 if (not self
.merge_modules
or self
.field
[f
]['pdu']['export']):
1313 nm
= self
.eproto
+ '_' + nm
1314 t
= self
.field
[f
]['type']
1316 ethtype
= self
.type[t
]['ethname']
1317 else: # undefined type
1318 ethtype
= self
.dummy_import_type(t
)
1319 ethtypemod
= ethtype
+ self
.field
[f
]['modified']
1320 if nm
in self
.eth_hf
:
1321 if nm
in self
.eth_hf_dupl
:
1322 if ethtypemod
in self
.eth_hf_dupl
[nm
]:
1323 nm
= self
.eth_hf_dupl
[nm
][ethtypemod
]
1324 self
.eth_hf
[nm
]['ref'].append(f
)
1325 self
.field
[f
]['ethname'] = nm
1328 nmx
= nm
+ ('_%02d' % (len(self
.eth_hf_dupl
[nm
])))
1329 self
.eth_hf_dupl
[nm
][ethtype
] = nmx
1332 if (self
.eth_hf
[nm
]['ethtype']+self
.eth_hf
[nm
]['modified']) == ethtypemod
:
1333 self
.eth_hf
[nm
]['ref'].append(f
)
1334 self
.field
[f
]['ethname'] = nm
1338 self
.eth_hf_dupl
[nm
] = {self
.eth_hf
[nm
]['ethtype']+self
.eth_hf
[nm
]['modified'] : nm
, \
1341 if (self
.field
[f
]['pdu']):
1342 self
.eth_hfpdu_ord
.append(nm
)
1344 self
.eth_hf_ord
.append(nm
)
1345 fullname
= 'hf_%s_%s' % (self
.eproto
, nm
)
1346 attr
= self
.eth_get_type_attr(self
.field
[f
]['type']).copy()
1347 attr
.update(self
.field
[f
]['attr'])
1348 if (self
.NAPI() and 'NAME' in attr
):
1349 attr
['NAME'] += self
.field
[f
]['idx']
1350 attr
.update(self
.conform
.use_item('EFIELD_ATTR', nm
))
1351 use_vals_ext
= self
.eth_type
[ethtype
].get('vals_ext')
1353 attr
['DISPLAY'] += '|BASE_EXT_STRING'
1354 self
.eth_hf
[nm
] = {'fullname' : fullname
, 'pdu' : self
.field
[f
]['pdu'],
1355 'ethtype' : ethtype
, 'modified' : self
.field
[f
]['modified'],
1356 'attr' : attr
.copy(),
1358 self
.field
[f
]['ethname'] = nm
1359 if (self
.dummy_eag_field
):
1360 # Prepending "dummy_" avoids matching checkhf.pl.
1361 self
.dummy_eag_field
= 'dummy_hf_%s_%s' % (self
.eproto
, self
.dummy_eag_field
)
1362 #--- type dependencies -------------------
1363 (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'])
1365 while i
< len(self
.eth_dep_cycle
):
1366 t
= self
.type[self
.eth_dep_cycle
[i
][0]]['ethname']
1367 self
.dep_cycle_eth_type
.setdefault(t
, []).append(i
)
1370 #--- value dependencies and export -------------------
1371 for v
in self
.eth_value_ord
:
1372 if self
.eth_value
[v
]['export']:
1373 self
.eth_vexport_ord
.append(v
)
1375 self
.eth_value_ord1
.append(v
)
1377 #--- export tags, values, ... ---
1378 for t
in self
.exports
:
1379 if t
not in self
.type:
1381 if self
.type[t
]['import']:
1383 m
= self
.type[t
]['module']
1384 if not self
.Per() and not self
.Oer():
1385 if m
not in self
.all_tags
:
1386 self
.all_tags
[m
] = {}
1387 self
.all_tags
[m
][t
] = self
.type[t
]['val'].GetTTag(self
)
1388 if m
not in self
.all_type_attr
:
1389 self
.all_type_attr
[m
] = {}
1390 self
.all_type_attr
[m
][t
] = self
.eth_get_type_attr(t
).copy()
1391 for v
in self
.vexports
:
1392 if v
not in self
.value
:
1394 if self
.value
[v
]['import']:
1396 m
= self
.value
[v
]['module']
1397 if m
not in self
.all_vals
:
1398 self
.all_vals
[m
] = {}
1399 vv
= self
.value
[v
]['value']
1400 if isinstance (vv
, Value
):
1401 vv
= vv
.to_str(self
)
1402 self
.all_vals
[m
][v
] = vv
1404 #--- eth_vals_nm ------------------------------------------------------------
1405 def eth_vals_nm(self
, tname
):
1407 if (not self
.eth_type
[tname
]['export'] & EF_NO_PROT
):
1408 out
+= "%s_" % (self
.eproto
)
1409 out
+= "%s_vals" % (tname
)
1412 #--- eth_vals ---------------------------------------------------------------
1413 def eth_vals(self
, tname
, vals
):
1415 has_enum
= self
.eth_type
[tname
]['enum'] & EF_ENUM
1416 use_ext
= self
.eth_type
[tname
]['vals_ext']
1418 vals
.sort(key
=lambda vals_entry
: int(vals_entry
[0]))
1419 if (not self
.eth_type
[tname
]['export'] & EF_VALS
):
1421 if (self
.eth_type
[tname
]['export'] & EF_VALS
) and (self
.eth_type
[tname
]['export'] & EF_TABLE
):
1423 if self
.eth_type
[tname
]['val'].HasConstraint() and self
.eth_type
[tname
]['val'].constr
.Needs64b(self
) \
1424 and self
.eth_type
[tname
]['val'].type == 'IntegerType':
1425 out
+= "const val64_string %s[] = {\n" % (self
.eth_vals_nm(tname
))
1427 out
+= "const value_string %s[] = {\n" % (self
.eth_vals_nm(tname
))
1428 for (val
, id) in vals
:
1430 vval
= self
.eth_enum_item(tname
, id)
1433 out
+= ' { %3s, "%s" },\n' % (vval
, id)
1434 out
+= " { 0, NULL }\n};\n"
1436 out
+= "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self
.eth_vals_nm(tname
), self
.eth_vals_nm(tname
))
1439 #--- eth_enum_prefix ------------------------------------------------------------
1440 def eth_enum_prefix(self
, tname
, type=False):
1442 if (self
.eth_type
[tname
]['export'] & EF_ENUM
):
1443 no_prot
= self
.eth_type
[tname
]['export'] & EF_NO_PROT
1445 no_prot
= self
.eth_type
[tname
]['enum'] & EF_NO_PROT
1448 if ((not self
.eth_type
[tname
]['enum'] & EF_NO_TYPE
) or type):
1449 if (out
): out
+= '_'
1451 if (self
.eth_type
[tname
]['enum'] & EF_UCASE
):
1453 if (out
): out
+= '_'
1456 #--- eth_enum_nm ------------------------------------------------------------
1457 def eth_enum_nm(self
, tname
):
1458 out
= self
.eth_enum_prefix(tname
, type=True)
1462 #--- eth_enum_item ---------------------------------------------------------------
1463 def eth_enum_item(self
, tname
, ident
):
1464 out
= self
.eth_enum_prefix(tname
)
1466 if (self
.eth_type
[tname
]['enum'] & EF_UCASE
):
1470 #--- eth_enum ---------------------------------------------------------------
1471 def eth_enum(self
, tname
, vals
):
1473 if (self
.eth_type
[tname
]['enum'] & EF_DEFINE
):
1474 out
+= "/* enumerated values for %s */\n" % (tname
)
1475 for (val
, id) in vals
:
1476 out
+= '#define %-12s %3s\n' % (self
.eth_enum_item(tname
, id), val
)
1478 out
+= "typedef enum _%s {\n" % (self
.eth_enum_nm(tname
))
1480 for (val
, id) in vals
:
1481 if (first_line
== 1):
1485 out
+= ' %-12s = %3s' % (self
.eth_enum_item(tname
, id), val
)
1486 out
+= "\n} %s;\n" % (self
.eth_enum_nm(tname
))
1489 #--- eth_bits ---------------------------------------------------------------
1490 def eth_bits(self
, tname
, bits
):
1492 out
+= "static int * const "
1493 out
+= "%(TABLE)s[] = {\n"
1494 for (val
, id) in bits
:
1495 out
+= ' &hf_%s_%s_%s,\n' % (self
.eproto
, tname
, asn2c(id))
1496 out
+= " NULL\n};\n"
1499 #--- eth_type_fn_h ----------------------------------------------------------
1500 def eth_type_fn_h(self
, tname
):
1502 if (not self
.eth_type
[tname
]['export'] & EF_TYPE
):
1506 out
+= "dissect_%s_%s(bool 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
)
1507 elif (self
.Per() or self
.Oer()):
1508 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
)
1512 #--- eth_fn_call ------------------------------------------------------------
1513 def eth_fn_call(self
, fname
, ret
=None, indent
=2, par
=None):
1516 if (ret
== 'return'):
1522 for i
in range(len(par
)):
1523 if (i
>0): out
+= ind
* ' '
1524 out
+= ', '.join(par
[i
])
1525 if (i
<(len(par
)-1)): out
+= ',\n'
1529 def output_proto_root(self
):
1531 if self
.conform
.proto_root_name
:
1532 out
+= ' proto_item *prot_ti = proto_tree_add_item(tree, ' + self
.conform
.proto_root_name
+ ', tvb, 0, -1, ENC_NA);\n'
1533 out
+= ' proto_item_set_hidden(prot_ti);\n'
1536 #--- eth_type_fn_hdr --------------------------------------------------------
1537 def eth_type_fn_hdr(self
, tname
):
1539 if (not self
.eth_type
[tname
]['export'] & EF_TYPE
):
1543 out
+= "dissect_%s_%s(bool 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
)
1544 elif (self
.Per() or self
.Oer()):
1545 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
)
1546 #if self.conform.get_fn_presence(tname):
1547 # out += self.conform.get_fn_text(tname, 'FN_HDR')
1549 if self
.conform
.check_item('PDU', tname
):
1550 out
+= self
.output_proto_root()
1553 if self
.eth_dep_cycle
:
1554 for cur_cycle
in self
.eth_dep_cycle
:
1555 t
= self
.type[cur_cycle
[0]]['ethname']
1557 cycle_funcs
= cur_cycle
1560 if len(cycle_funcs
) > 1:
1562 // {' -> '.join(cycle_funcs)}
1563 actx->pinfo->dissection_depth += {len(cycle_funcs) - 1};
1564 increment_dissection_depth(actx->pinfo);
1567 if self
.conform
.get_fn_presence(self
.eth_type
[tname
]['ref'][0]):
1568 out
+= self
.conform
.get_fn_text(self
.eth_type
[tname
]['ref'][0], 'FN_HDR')
1571 #--- eth_type_fn_ftr --------------------------------------------------------
1572 def eth_type_fn_ftr(self
, tname
):
1574 #if self.conform.get_fn_presence(tname):
1575 # out += self.conform.get_fn_text(tname, 'FN_FTR')
1579 if self
.eth_dep_cycle
:
1580 for cur_cycle
in self
.eth_dep_cycle
:
1581 t
= self
.type[cur_cycle
[0]]['ethname']
1583 cycle_funcs
= cur_cycle
1586 if len(cycle_funcs
) > 1:
1588 actx->pinfo->dissection_depth -= {len(cycle_funcs) - 1};
1589 decrement_dissection_depth(actx->pinfo);
1592 if self
.conform
.get_fn_presence(self
.eth_type
[tname
]['ref'][0]):
1593 out
+= self
.conform
.get_fn_text(self
.eth_type
[tname
]['ref'][0], 'FN_FTR')
1594 out
+= " return offset;\n"
1598 #--- eth_type_fn_body -------------------------------------------------------
1599 def eth_type_fn_body(self
, tname
, body
, pars
=None):
1601 #if self.conform.get_fn_body_presence(tname):
1602 # out = self.conform.get_fn_text(tname, 'FN_BODY')
1604 if self
.conform
.get_fn_body_presence(self
.eth_type
[tname
]['ref'][0]):
1605 out
= self
.conform
.get_fn_text(self
.eth_type
[tname
]['ref'][0], 'FN_BODY')
1613 #--- eth_out_pdu_decl ----------------------------------------------------------
1614 def eth_out_pdu_decl(self
, f
):
1615 #t = self.eth_hf[f]['ethtype']
1617 if (not self
.eth_hf
[f
]['pdu']['export']):
1620 out
+= 'dissect_'+f
+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n'
1623 #--- eth_output_hf ----------------------------------------------------------
1624 def eth_output_hf (self
):
1625 if not len(self
.eth_hf_ord
) and not len(self
.eth_hfpdu_ord
) and not len(self
.named_bit
): return
1626 fx
= self
.output
.file_open('hf')
1627 for f
in (self
.eth_hfpdu_ord
+ self
.eth_hf_ord
):
1628 fx
.write("%-50s/* %s */\n" % ("static int %s; " % (self
.eth_hf
[f
]['fullname']), self
.eth_hf
[f
]['ethtype']))
1629 if (self
.named_bit
):
1630 fx
.write('/* named bits */\n')
1631 for nb
in self
.named_bit
:
1632 fx
.write("static int %s;\n" % (nb
['ethname']))
1633 if (self
.dummy_eag_field
):
1634 fx
.write("static int %s; /* never registered */\n" % (self
.dummy_eag_field
))
1635 self
.output
.file_close(fx
)
1637 #--- eth_output_hf_arr ------------------------------------------------------
1638 def eth_output_hf_arr (self
):
1639 if not len(self
.eth_hf_ord
) and not len(self
.eth_hfpdu_ord
) and not len(self
.named_bit
): return
1640 fx
= self
.output
.file_open('hfarr')
1641 for f
in (self
.eth_hfpdu_ord
+ self
.eth_hf_ord
):
1642 t
= self
.eth_hf
[f
]['ethtype']
1643 if self
.remove_prefix
and t
.startswith(self
.remove_prefix
):
1644 t
= t
[len(self
.remove_prefix
):]
1645 name
=self
.eth_hf
[f
]['attr']['NAME']
1647 trantab
= maketrans("- ", "__")
1649 trantab
= str.maketrans("- ", "__")
1650 name
= name
.translate(trantab
)
1651 namelower
= name
.lower()
1652 tquoted_lower
= '"' + t
.lower() + '"'
1653 # Try to avoid giving blurbs that give no more info than the name
1654 if tquoted_lower
== namelower
or \
1656 tquoted_lower
.replace("t_", "") == namelower
:
1659 blurb
= '"%s"' % (t
)
1660 attr
= self
.eth_hf
[f
]['attr'].copy()
1661 if attr
['TYPE'] == 'FT_NONE':
1662 attr
['ABBREV'] = '"%s.%s_element"' % (self
.proto
, attr
['ABBREV'])
1664 attr
['ABBREV'] = '"%s.%s"' % (self
.proto
, attr
['ABBREV'])
1665 if 'BLURB' not in attr
:
1666 attr
['BLURB'] = blurb
1667 fx
.write(' { &%s,\n' % (self
.eth_hf
[f
]['fullname']))
1668 fx
.write(' { %(NAME)s, %(ABBREV)s,\n' % attr
)
1669 fx
.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr
)
1670 fx
.write(' %(BLURB)s, HFILL }},\n' % attr
)
1671 for nb
in self
.named_bit
:
1672 flt_str
= nb
['ethname']
1674 flt_str
= flt_str
[3:]
1675 flt_str
= flt_str
.replace('_' , '.')
1676 #print("filter string=%s" % (flt_str))
1677 fx
.write(' { &%s,\n' % (nb
['ethname']))
1678 fx
.write(' { "%s", "%s",\n' % (nb
['name'], flt_str
))
1679 fx
.write(' %s, %s, %s, %s,\n' % (nb
['ftype'], nb
['display'], nb
['strings'], nb
['bitmask']))
1680 fx
.write(' NULL, HFILL }},\n')
1681 self
.output
.file_close(fx
)
1683 #--- eth_output_ett ---------------------------------------------------------
1684 def eth_output_ett (self
):
1685 fx
= self
.output
.file_open('ett')
1687 #fx.write("static int ett_%s;\n" % (self.eproto))
1688 for t
in self
.eth_type_ord
:
1689 if self
.eth_type
[t
]['tree']:
1690 fx
.write("static int %s;\n" % (self
.eth_type
[t
]['tree']))
1692 self
.output
.file_close(fx
, discard
=fempty
)
1694 #--- eth_output_ett_arr -----------------------------------------------------
1695 def eth_output_ett_arr(self
):
1696 fx
= self
.output
.file_open('ettarr')
1698 #fx.write(" &ett_%s,\n" % (self.eproto))
1699 for t
in self
.eth_type_ord
:
1700 if self
.eth_type
[t
]['tree']:
1701 fx
.write(" &%s,\n" % (self
.eth_type
[t
]['tree']))
1703 self
.output
.file_close(fx
, discard
=fempty
)
1705 #--- eth_output_export ------------------------------------------------------
1706 def eth_output_export(self
):
1707 fx
= self
.output
.file_open('exp', ext
='h')
1708 for t
in self
.eth_export_ord
: # vals
1709 if (self
.eth_type
[t
]['export'] & EF_ENUM
) and self
.eth_type
[t
]['val'].eth_has_enum(t
, self
):
1710 fx
.write(self
.eth_type
[t
]['val'].eth_type_enum(t
, self
))
1711 if (self
.eth_type
[t
]['export'] & EF_VALS
) and self
.eth_type
[t
]['val'].eth_has_vals():
1712 if not self
.eth_type
[t
]['export'] & EF_TABLE
:
1713 if self
.eth_type
[t
]['export'] & EF_WS_DLL
:
1714 fx
.write("WS_DLL_PUBLIC ")
1717 if self
.eth_type
[t
]['val'].HasConstraint() and self
.eth_type
[t
]['val'].constr
.Needs64b(self
) \
1718 and self
.eth_type
[t
]['val'].type == 'IntegerType':
1719 fx
.write("const val64_string %s[];\n" % (self
.eth_vals_nm(t
)))
1721 fx
.write("const value_string %s[];\n" % (self
.eth_vals_nm(t
)))
1723 fx
.write(self
.eth_type
[t
]['val'].eth_type_vals(t
, self
))
1724 for t
in self
.eth_export_ord
: # functions
1725 if (self
.eth_type
[t
]['export'] & EF_TYPE
):
1726 if self
.eth_type
[t
]['export'] & EF_EXTERN
:
1727 if self
.eth_type
[t
]['export'] & EF_WS_DLL
:
1728 fx
.write("WS_DLL_PUBLIC ")
1731 fx
.write(self
.eth_type_fn_h(t
))
1732 for f
in self
.eth_hfpdu_ord
: # PDUs
1733 if (self
.eth_hf
[f
]['pdu'] and self
.eth_hf
[f
]['pdu']['export']):
1734 fx
.write(self
.eth_out_pdu_decl(f
))
1735 self
.output
.file_close(fx
)
1737 #--- eth_output_expcnf ------------------------------------------------------
1738 def eth_output_expcnf(self
):
1739 fx
= self
.output
.file_open('exp', ext
='cnf')
1740 fx
.write('#.MODULE\n')
1742 for (m
, p
) in self
.modules
:
1743 if (len(m
) > maxw
): maxw
= len(m
)
1744 for (m
, p
) in self
.modules
:
1745 fx
.write("%-*s %s\n" % (maxw
, m
, p
))
1746 fx
.write('#.END\n\n')
1747 for cls
in self
.objectclass_ord
:
1748 if self
.objectclass
[cls
]['export']:
1750 if self
.objectclass
[cls
]['export'] & EF_MODULE
:
1751 cnm
= "$%s$%s" % (self
.objectclass
[cls
]['module'], cnm
)
1752 fx
.write('#.CLASS %s\n' % (cnm
))
1754 for fld
in self
.objectclass
[cls
]['val'].fields
:
1755 w
= len(fld
.fld_repr()[0])
1756 if (w
> maxw
): maxw
= w
1757 for fld
in self
.objectclass
[cls
]['val'].fields
:
1758 repr = fld
.fld_repr()
1759 fx
.write('%-*s %s\n' % (maxw
, repr[0], ' '.join(repr[1:])))
1760 fx
.write('#.END\n\n')
1762 fx
.write('#.IMPORT_TAG\n')
1763 for t
in self
.eth_export_ord
: # tags
1764 if (self
.eth_type
[t
]['export'] & EF_TYPE
):
1765 fx
.write('%-24s ' % self
.eth_type
[t
]['ref'][0])
1766 fx
.write('%s %s\n' % self
.eth_type
[t
]['val'].GetTag(self
))
1767 fx
.write('#.END\n\n')
1768 fx
.write('#.TYPE_ATTR\n')
1769 for t
in self
.eth_export_ord
: # attributes
1770 if (self
.eth_type
[t
]['export'] & EF_TYPE
):
1771 tnm
= self
.eth_type
[t
]['ref'][0]
1772 if self
.eth_type
[t
]['export'] & EF_MODULE
:
1773 tnm
= "$%s$%s" % (self
.type[tnm
]['module'], tnm
)
1774 fx
.write('%-24s ' % tnm
)
1775 attr
= self
.eth_get_type_attr(self
.eth_type
[t
]['ref'][0]).copy()
1776 fx
.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr
)
1777 fx
.write('#.END\n\n')
1778 self
.output
.file_close(fx
, keep_anyway
=True)
1780 #--- eth_output_val ------------------------------------------------------
1781 def eth_output_val(self
):
1782 fx
= self
.output
.file_open('val', ext
='h')
1783 for v
in self
.eth_value_ord1
:
1784 vv
= self
.eth_value
[v
]['value']
1785 if isinstance (vv
, Value
):
1786 vv
= vv
.to_str(self
)
1787 fx
.write("#define %-30s %s\n" % (v
, vv
))
1788 for t
in self
.eth_type_ord1
:
1789 if self
.eth_type
[t
]['import']:
1791 if self
.eth_type
[t
]['val'].eth_has_enum(t
, self
) and not (self
.eth_type
[t
]['export'] & EF_ENUM
):
1792 fx
.write(self
.eth_type
[t
]['val'].eth_type_enum(t
, self
))
1793 self
.output
.file_close(fx
)
1795 #--- eth_output_valexp ------------------------------------------------------
1796 def eth_output_valexp(self
):
1797 if (not len(self
.eth_vexport_ord
)): return
1798 fx
= self
.output
.file_open('valexp', ext
='h')
1799 for v
in self
.eth_vexport_ord
:
1800 vv
= self
.eth_value
[v
]['value']
1801 if isinstance (vv
, Value
):
1802 vv
= vv
.to_str(self
)
1803 fx
.write("#define %-30s %s\n" % (v
, vv
))
1804 self
.output
.file_close(fx
)
1806 #--- eth_output_types -------------------------------------------------------
1807 def eth_output_types(self
):
1809 t
= self
.eth_hf
[f
]['ethtype']
1812 if (not self
.eth_hf
[f
]['pdu']['export']):
1815 out
+= 'dissect_'+f
+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n'
1816 out
+= self
.output_proto_root()
1818 out
+= ' int offset = 0;\n'
1822 if (self
.Aligned()):
1826 out
+= " asn1_ctx_t asn1_ctx;\n"
1827 out
+= self
.eth_fn_call('asn1_ctx_init', par
=(('&asn1_ctx', 'ASN1_ENC_PER', aligned
, 'pinfo'),))
1829 out
+= " asn1_ctx_t asn1_ctx;\n"
1830 out
+= self
.eth_fn_call('asn1_ctx_init', par
=(('&asn1_ctx', 'ASN1_ENC_BER', 'true', 'pinfo'),))
1831 par
=((impl
, 'tvb', off_par
,'&asn1_ctx', 'tree', self
.eth_hf
[f
]['fullname']),)
1833 par
=(('tvb', off_par
, '&asn1_ctx', 'tree', self
.eth_hf
[f
]['fullname']),)
1835 out
+= " asn1_ctx_t asn1_ctx;\n"
1836 out
+= self
.eth_fn_call('asn1_ctx_init', par
=(('&asn1_ctx', 'ASN1_ENC_OER', 'true', 'pinfo'),))
1837 par
=(('tvb', off_par
,'&asn1_ctx', 'tree', self
.eth_hf
[f
]['fullname']),)
1840 out
+= self
.eth_fn_call('dissect_%s_%s' % (self
.eth_type
[t
]['proto'], t
), ret
=ret_par
, par
=par
)
1842 out
+= ' offset += 7; offset >>= 3;\n'
1843 out
+= ' return offset;\n'
1847 fx
= self
.output
.file_open('fn')
1849 if (len(self
.eth_hfpdu_ord
)):
1851 for f
in self
.eth_hfpdu_ord
:
1852 if (self
.eth_hf
[f
]['pdu'] and self
.eth_hf
[f
]['pdu']['need_decl']):
1854 fx
.write('/*--- PDUs declarations ---*/\n')
1856 fx
.write(self
.eth_out_pdu_decl(f
))
1860 add_depth_define
= False
1861 if self
.eth_dep_cycle
:
1862 fx
.write('/*--- Cyclic dependencies ---*/\n\n')
1864 while i
< len(self
.eth_dep_cycle
):
1865 t
= self
.type[self
.eth_dep_cycle
[i
][0]]['ethname']
1866 if self
.dep_cycle_eth_type
[t
][0] != i
: i
+= 1; continue
1867 add_depth_define
= True
1868 fx
.write(''.join(['/* %s */\n' % ' -> '.join(self
.eth_dep_cycle
[i
]) for i
in self
.dep_cycle_eth_type
[t
]]))
1869 if not self
.eth_type
[t
]['export'] & EF_TYPE
:
1870 fx
.write(self
.eth_type_fn_h(t
))
1872 fx
.write('/*' + self
.eth_type_fn_h(t
).strip() + '*/\n')
1876 for t
in self
.eth_type_ord1
:
1877 if self
.eth_type
[t
]['import']:
1879 if self
.eth_type
[t
]['val'].eth_has_vals():
1880 if self
.eth_type
[t
]['no_emit'] & EF_VALS
:
1882 elif self
.eth_type
[t
]['user_def'] & EF_VALS
:
1883 if self
.eth_type
[t
]['val'].HasConstraint() and self
.eth_type
[t
]['val'].constr
.Needs64b(self
) \
1884 and self
.eth_type
[t
]['val'].type == 'IntegerType':
1885 fx
.write("extern const val64_string %s[];\n" % (self
.eth_vals_nm(t
)))
1887 fx
.write("extern const value_string %s[];\n" % (self
.eth_vals_nm(t
)))
1888 elif (self
.eth_type
[t
]['export'] & EF_VALS
) and (self
.eth_type
[t
]['export'] & EF_TABLE
):
1891 fx
.write(self
.eth_type
[t
]['val'].eth_type_vals(t
, self
))
1892 if self
.eth_type
[t
]['no_emit'] & EF_TYPE
:
1894 elif self
.eth_type
[t
]['user_def'] & EF_TYPE
:
1895 fx
.write(self
.eth_type_fn_h(t
))
1897 fx
.write(self
.eth_type
[t
]['val'].eth_type_fn(self
.eth_type
[t
]['proto'], t
, self
))
1899 if (len(self
.eth_hfpdu_ord
)):
1900 fx
.write('/*--- PDUs ---*/\n\n')
1901 for f
in self
.eth_hfpdu_ord
:
1902 if (self
.eth_hf
[f
]['pdu']):
1903 if (f
in self
.emitted_pdu
):
1904 fx
.write(" /* %s already emitted */\n" % (f
))
1906 fx
.write(out_pdu(f
))
1907 self
.emitted_pdu
[f
] = True
1909 fempty
= pos
== fx
.tell()
1910 self
.output
.file_close(fx
, discard
=fempty
)
1912 #--- eth_output_dis_hnd -----------------------------------------------------
1913 def eth_output_dis_hnd(self
):
1914 fx
= self
.output
.file_open('dis-hnd')
1916 for f
in self
.eth_hfpdu_ord
:
1917 pdu
= self
.eth_hf
[f
]['pdu']
1918 if (pdu
and pdu
['reg'] and not pdu
['hidden']):
1920 if (pdu
['reg'] != '.'):
1921 dis
+= '.' + pdu
['reg']
1922 fx
.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis
)))
1925 self
.output
.file_close(fx
, discard
=fempty
)
1927 #--- eth_output_dis_reg -----------------------------------------------------
1928 def eth_output_dis_reg(self
):
1929 fx
= self
.output
.file_open('dis-reg')
1931 for f
in self
.eth_hfpdu_ord
:
1932 pdu
= self
.eth_hf
[f
]['pdu']
1933 if (pdu
and pdu
['reg']):
1935 if (pdu
['new']): new_prefix
= 'new_'
1937 if (pdu
['reg'] != '.'): dis
+= '.' + pdu
['reg']
1938 fx
.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix
, dis
, f
, self
.eproto
))
1939 if (not pdu
['hidden']):
1940 fx
.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis
), dis
))
1943 self
.output
.file_close(fx
, discard
=fempty
)
1945 #--- eth_output_dis_tab -----------------------------------------------------
1946 def eth_output_dis_tab(self
):
1947 fx
= self
.output
.file_open('dis-tab')
1949 for k
in self
.conform
.get_order('REGISTER'):
1950 reg
= self
.conform
.use_item('REGISTER', k
)
1951 if reg
['pdu'] not in self
.field
: continue
1952 f
= self
.field
[reg
['pdu']]['ethname']
1953 pdu
= self
.eth_hf
[f
]['pdu']
1955 if (pdu
['new']): new_prefix
= 'new_'
1956 if (reg
['rtype'] in ('NUM', 'STR')):
1958 if (reg
['rtype'] == 'STR'):
1964 if (pdu
['reg'] != '.'): dis
+= '.' + pdu
['reg']
1965 if (not pdu
['hidden']):
1966 hnd
= '%s_handle' % (asn2c(dis
))
1968 hnd
= 'find_dissector("%s")' % (dis
)
1970 hnd
= '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix
, f
, self
.eproto
)
1971 rport
= self
.value_get_eth(reg
['rport'])
1972 fx
.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr
, reg
['rtable'], rport
, hnd
))
1973 elif (reg
['rtype'] in ('BER', 'PER', 'OER')):
1974 roid
= self
.value_get_eth(reg
['roid'])
1975 fx
.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix
, reg
['rtype'].lower(), roid
, f
, self
.eproto
, reg
['roidname']))
1978 self
.output
.file_close(fx
, discard
=fempty
)
1980 #--- eth_output_syn_reg -----------------------------------------------------
1981 def eth_output_syn_reg(self
):
1982 fx
= self
.output
.file_open('syn-reg')
1985 for k
in self
.conform
.get_order('SYNTAX'):
1986 reg
= self
.conform
.use_item('SYNTAX', k
)
1987 if reg
['pdu'] not in self
.field
: continue
1988 f
= self
.field
[reg
['pdu']]['ethname']
1989 pdu
= self
.eth_hf
[f
]['pdu']
1991 if (pdu
['new']): new_prefix
= 'new_'
1993 fx
.write(' /*--- Syntax registrations ---*/\n')
1995 fx
.write(' %sregister_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (new_prefix
, k
, self
.eproto
, reg
['pdu']))
1997 self
.output
.file_close(fx
, discard
=fempty
)
1999 #--- eth_output_tables -----------------------------------------------------
2000 def eth_output_tables(self
):
2001 for num
in list(self
.conform
.report
.keys()):
2002 fx
= self
.output
.file_open('table' + num
)
2003 for rep
in self
.conform
.report
[num
]:
2004 self
.eth_output_table(fx
, rep
)
2005 self
.output
.file_close(fx
)
2007 #--- eth_output_table -----------------------------------------------------
2008 def eth_output_table(self
, fx
, rep
):
2009 if rep
['type'] == 'HDR':
2013 var_list
= var
.split('.', 1)
2021 not_flds
.append(f
[1:])
2029 sort_flds
.append(f
[1:])
2034 if (cls
in self
.oassign_cls
):
2035 for ident
in self
.oassign_cls
[cls
]:
2036 obj
= self
.get_obj_repr(ident
, flds
, not_flds
)
2040 obj
['_DICT'] = str(obj
)
2042 objs_ord
.append(ident
)
2044 # Sort identifiers according to the matching object in objs.
2045 # The order is determined by sort_flds, keys prefixed by a
2046 # '#' are compared numerically.
2047 def obj_key_fn(name
):
2050 int(obj
[f
[1:]]) if f
[0] == '#' else obj
[f
]
2053 objs_ord
.sort(key
=obj_key_fn
)
2054 for ident
in objs_ord
:
2057 text
= rep
['text'] % obj
2059 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
))
2062 fx
.write("/* Unknown or empty loop list %s */\n" % (var
))
2064 fx
.write(rep
['text'])
2065 if rep
['type'] == 'FTR':
2068 #--- dupl_report -----------------------------------------------------
2069 def dupl_report(self
):
2073 tmplist
= sorted(self
.eth_type_dupl
.keys())
2075 msg
= "The same type names for different types. Explicit type renaming is recommended.\n"
2077 for tt
in self
.eth_type_dupl
[t
]:
2078 msg
+= " %-20s %s\n" % (self
.type[tt
]['ethname'], tt
)
2079 warnings
.warn_explicit(msg
, UserWarning, '', 0)
2081 tmplist
= list(self
.eth_hf_dupl
.keys())
2084 msg
= "The same field names for different types. Explicit field renaming is recommended.\n"
2086 for tt
in list(self
.eth_hf_dupl
[f
].keys()):
2087 msg
+= " %-20s %-20s " % (self
.eth_hf_dupl
[f
][tt
], tt
)
2088 msg
+= ", ".join(self
.eth_hf
[self
.eth_hf_dupl
[f
][tt
]]['ref'])
2090 warnings
.warn_explicit(msg
, UserWarning, '', 0)
2092 #--- eth_do_output ------------------------------------------------------------
2093 def eth_do_output(self
):
2095 print("\n# Assignments")
2096 for a
in self
.assign_ord
:
2098 if (self
.assign
[a
]['virt']): v
= '*'
2099 print('{} {}'.format(v
, a
))
2100 print("\n# Value assignments")
2101 for a
in self
.vassign_ord
:
2102 print(' {}'.format(a
))
2103 print("\n# Information object assignments")
2104 for a
in self
.oassign_ord
:
2105 print(" %-12s (%s)" % (a
, self
.oassign
[a
].cls
))
2107 print("\n# Imported Types")
2108 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2110 for t
in self
.type_imp
:
2111 print("%-40s %-24s %-24s" % (t
, self
.type[t
]['import'], self
.type[t
]['proto']))
2112 print("\n# Imported Values")
2113 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2115 for t
in self
.value_imp
:
2116 print("%-40s %-24s %-24s" % (t
, self
.value
[t
]['import'], self
.value
[t
]['proto']))
2117 print("\n# Imported Object Classes")
2118 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2120 for t
in self
.objectclass_imp
:
2121 print("%-40s %-24s %-24s" % (t
, self
.objectclass
[t
]['import'], self
.objectclass
[t
]['proto']))
2122 print("\n# Exported Types")
2123 print("%-31s %s" % ("Wireshark type", "Export Flag"))
2125 for t
in self
.eth_export_ord
:
2126 print("%-31s 0x%02X" % (t
, self
.eth_type
[t
]['export']))
2127 print("\n# Exported Values")
2128 print("%-40s %s" % ("Wireshark name", "Value"))
2130 for v
in self
.eth_vexport_ord
:
2131 vv
= self
.eth_value
[v
]['value']
2132 if isinstance (vv
, Value
):
2133 vv
= vv
.to_str(self
)
2134 print("%-40s %s" % (v
, vv
))
2135 print("\n# ASN.1 Object Classes")
2136 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2138 for t
in self
.objectclass_ord
:
2139 print("%-40s " % (t
))
2140 print("\n# ASN.1 Types")
2141 print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type"))
2143 for t
in self
.type_ord
:
2144 print("%-49s %-24s %-24s" % (t
, self
.type[t
]['tname'], self
.type[t
]['ethname']))
2145 print("\n# Wireshark Types")
2146 print("Wireshark type References (ASN.1 types)")
2148 for t
in self
.eth_type_ord
:
2149 sys
.stdout
.write("%-31s %d" % (t
, len(self
.eth_type
[t
]['ref'])))
2150 print(', '.join(self
.eth_type
[t
]['ref']))
2151 print("\n# ASN.1 Values")
2152 print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value"))
2154 for v
in self
.value_ord
:
2155 vv
= self
.value
[v
]['value']
2156 if isinstance (vv
, Value
):
2157 vv
= vv
.to_str(self
)
2158 print("%-40s %-18s %-20s %s" % (v
, self
.value
[v
]['type'].eth_tname(), vv
, self
.value
[v
]['ethname']))
2159 #print "\n# Wireshark Values"
2160 #print "%-40s %s" % ("Wireshark name", "Value")
2162 #for v in self.eth_value_ord:
2163 # vv = self.eth_value[v]['value']
2164 # if isinstance (vv, Value):
2165 # vv = vv.to_str(self)
2166 # print "%-40s %s" % (v, vv)
2167 print("\n# ASN.1 Fields")
2168 print("ASN.1 unique name Wireshark name ASN.1 type")
2170 for f
in (self
.pdu_ord
+ self
.field_ord
):
2171 print("%-40s %-20s %s" % (f
, self
.field
[f
]['ethname'], self
.field
[f
]['type']))
2172 print("\n# Wireshark Fields")
2173 print("Wireshark name Wireshark type References (ASN.1 fields)")
2175 for f
in (self
.eth_hfpdu_ord
+ self
.eth_hf_ord
):
2176 sys
.stdout
.write("%-30s %-20s %s" % (f
, self
.eth_hf
[f
]['ethtype'], len(self
.eth_hf
[f
]['ref'])))
2177 print(', '.join(self
.eth_hf
[f
]['ref']))
2178 #print "\n# Order after dependencies"
2179 #print '\n'.join(self.eth_type_ord1)
2180 print("\n# Cyclic dependencies")
2181 for c
in self
.eth_dep_cycle
:
2182 print(' -> '.join(c
))
2184 self
.output
.outnm
= self
.outnm_opt
2185 if (not self
.output
.outnm
):
2186 self
.output
.outnm
= self
.proto
2187 self
.output
.outnm
= self
.output
.outnm
.replace('.', '-')
2188 if not self
.justexpcnf
:
2189 self
.eth_output_hf()
2190 self
.eth_output_ett()
2191 self
.eth_output_types()
2192 self
.eth_output_hf_arr()
2193 self
.eth_output_ett_arr()
2194 self
.eth_output_export()
2195 self
.eth_output_val()
2196 self
.eth_output_valexp()
2197 self
.eth_output_dis_hnd()
2198 self
.eth_output_dis_reg()
2199 self
.eth_output_dis_tab()
2200 self
.eth_output_syn_reg()
2201 self
.eth_output_tables()
2203 self
.eth_output_expcnf()
2205 def dbg_modules(self
):
2207 sys
.stdout
.write("%-30s " % (m
))
2208 dep
= self
.module
[m
][:]
2209 for i
in range(len(dep
)):
2210 if dep
[i
] not in self
.module
:
2211 dep
[i
] = '*' + dep
[i
]
2212 print(', '.join(dep
))
2213 # end of print_mod()
2214 (mod_ord
, mod_cyc
) = dependency_compute(self
.module_ord
, self
.module
, ignore_fn
= lambda t
: t
not in self
.module
)
2215 print("\n# ASN.1 Modules")
2216 print("Module name Dependency")
2219 for m
in (self
.module_ord
):
2221 new_ord
= new_ord
or (self
.module_ord
.index(m
) != mod_ord
.index(m
))
2223 print("\n# ASN.1 Modules - in dependency order")
2224 print("Module name Dependency")
2229 print("\nCyclic dependencies:")
2230 for i
in (list(range(len(mod_cyc
)))):
2231 print("%02d: %s" % (i
+ 1, str(mod_cyc
[i
])))
2234 #--- EthCnf -------------------------------------------------------------------
2243 self
.suppress_line
= False
2244 self
.include_path
= []
2245 self
.proto_root_name
= None
2246 # Value name Default value Duplicity check Usage check
2247 self
.tblcfg
['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2248 self
.tblcfg
['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2249 self
.tblcfg
['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2250 self
.tblcfg
['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2251 self
.tblcfg
['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2252 self
.tblcfg
['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2253 self
.tblcfg
['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2254 self
.tblcfg
['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2255 self
.tblcfg
['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2256 self
.tblcfg
['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2257 self
.tblcfg
['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2258 self
.tblcfg
['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2259 self
.tblcfg
['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2260 self
.tblcfg
['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2261 self
.tblcfg
['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2262 self
.tblcfg
['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2263 self
.tblcfg
['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2264 self
.tblcfg
['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2265 self
.tblcfg
['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2266 self
.tblcfg
['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2267 self
.tblcfg
['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2268 self
.tblcfg
['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2269 self
.tblcfg
['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2271 for k
in list(self
.tblcfg
.keys()) :
2275 def add_item(self
, table
, key
, fn
, lineno
, **kw
):
2276 if self
.tblcfg
[table
]['chk_dup'] and key
in self
.table
[table
]:
2277 warnings
.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2278 (table
, key
, self
.table
[table
][key
]['fn'], self
.table
[table
][key
]['lineno']),
2279 UserWarning, fn
, lineno
)
2281 self
.table
[table
][key
] = {'fn' : fn
, 'lineno' : lineno
, 'used' : False}
2282 self
.table
[table
][key
].update(kw
)
2283 self
.order
[table
].append(key
)
2285 def update_item(self
, table
, key
, fn
, lineno
, **kw
):
2286 if key
not in self
.table
[table
]:
2287 self
.table
[table
][key
] = {'fn' : fn
, 'lineno' : lineno
, 'used' : False}
2288 self
.order
[table
].append(key
)
2289 self
.table
[table
][key
][self
.tblcfg
[table
]['val_nm']] = {}
2290 self
.table
[table
][key
][self
.tblcfg
[table
]['val_nm']].update(kw
[self
.tblcfg
[table
]['val_nm']])
2292 def get_order(self
, table
):
2293 return self
.order
[table
]
2295 def check_item(self
, table
, key
):
2296 return key
in self
.table
[table
]
2298 def copy_item(self
, table
, dst_key
, src_key
):
2299 if (src_key
in self
.table
[table
]):
2300 self
.table
[table
][dst_key
] = self
.table
[table
][src_key
]
2302 def check_item_value(self
, table
, key
, **kw
):
2303 return key
in self
.table
[table
] and kw
.get('val_nm', self
.tblcfg
[table
]['val_nm']) in self
.table
[table
][key
]
2305 def use_item(self
, table
, key
, **kw
):
2306 vdflt
= kw
.get('val_dflt', self
.tblcfg
[table
]['val_dflt'])
2307 if key
not in self
.table
[table
]: return vdflt
2308 vname
= kw
.get('val_nm', self
.tblcfg
[table
]['val_nm'])
2309 #print "use_item() - set used for %s %s" % (table, key)
2310 self
.table
[table
][key
]['used'] = True
2311 return self
.table
[table
][key
].get(vname
, vdflt
)
2313 def omit_assignment(self
, type, ident
, module
):
2314 if self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', ident
):
2316 if self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*') or \
2317 self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2318 self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*/'+module
) or \
2319 self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module
):
2320 return self
.ectx
.conform
.use_item('NO_OMIT_ASSGN', ident
)
2323 def add_fn_line(self
, name
, ctx
, line
, fn
, lineno
):
2324 if name
not in self
.fn
:
2325 self
.fn
[name
] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2326 if (self
.fn
[name
][ctx
]):
2327 self
.fn
[name
][ctx
]['text'] += line
2329 self
.fn
[name
][ctx
] = {'text' : line
, 'used' : False,
2330 'fn' : fn
, 'lineno' : lineno
}
2331 def get_fn_presence(self
, name
):
2332 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2333 #if self.fn.has_key(name): print self.fn[name]
2334 return name
in self
.fn
2335 def get_fn_body_presence(self
, name
):
2336 return name
in self
.fn
and self
.fn
[name
]['FN_BODY']
2337 def get_fn_text(self
, name
, ctx
):
2338 if (name
not in self
.fn
):
2340 if (not self
.fn
[name
][ctx
]):
2342 self
.fn
[name
][ctx
]['used'] = True
2343 out
= self
.fn
[name
][ctx
]['text']
2344 if (not self
.suppress_line
):
2345 out
= '#line %u "%s"\n%s\n' % (self
.fn
[name
][ctx
]['lineno'], rel_dissector_path(self
.fn
[name
][ctx
]['fn']), out
)
2348 def add_pdu(self
, par
, fn
, lineno
):
2349 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2350 (reg
, hidden
) = (None, False)
2351 if (len(par
) > 1): reg
= par
[1]
2352 if (reg
and reg
[0]=='@'): (reg
, hidden
) = (reg
[1:], True)
2353 attr
= {'new' : False, 'reg' : reg
, 'hidden' : hidden
, 'need_decl' : False, 'export' : False}
2354 self
.add_item('PDU', par
[0], attr
=attr
, fn
=fn
, lineno
=lineno
)
2357 def add_syntax(self
, par
, fn
, lineno
):
2358 #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno)
2359 if( (len(par
) >=2)):
2362 name
= '"'+par
[0]+'"'
2363 attr
= { 'pdu' : par
[0] }
2364 self
.add_item('SYNTAX', name
, attr
=attr
, fn
=fn
, lineno
=lineno
)
2367 def add_register(self
, pdu
, par
, fn
, lineno
):
2368 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2369 if (par
[0] in ('N', 'NUM')): rtype
= 'NUM'; (pmin
, pmax
) = (2, 2)
2370 elif (par
[0] in ('S', 'STR')): rtype
= 'STR'; (pmin
, pmax
) = (2, 2)
2371 elif (par
[0] in ('B', 'BER')): rtype
= 'BER'; (pmin
, pmax
) = (1, 2)
2372 elif (par
[0] in ('P', 'PER')): rtype
= 'PER'; (pmin
, pmax
) = (1, 2)
2373 elif (par
[0] in ('O', 'OER')): rtype
= 'OER'; (pmin
, pmax
) = (1, 2)
2374 else: warnings
.warn_explicit("Unknown registration type '%s'" % (par
[2]), UserWarning, fn
, lineno
); return
2375 if ((len(par
)-1) < pmin
):
2376 warnings
.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype
, pmin
), UserWarning, fn
, lineno
)
2378 if ((len(par
)-1) > pmax
):
2379 warnings
.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype
, pmax
), UserWarning, fn
, lineno
)
2380 attr
= {'pdu' : pdu
, 'rtype' : rtype
}
2381 if (rtype
in ('NUM', 'STR')):
2382 attr
['rtable'] = par
[1]
2383 attr
['rport'] = par
[2]
2384 rkey
= '/'.join([rtype
, attr
['rtable'], attr
['rport']])
2385 elif (rtype
in ('BER', 'PER', 'OER')):
2386 attr
['roid'] = par
[1]
2387 attr
['roidname'] = '""'
2389 attr
['roidname'] = par
[2]
2390 elif attr
['roid'][0] != '"':
2391 attr
['roidname'] = '"' + attr
['roid'] + '"'
2392 rkey
= '/'.join([rtype
, attr
['roid']])
2393 self
.add_item('REGISTER', rkey
, attr
=attr
, fn
=fn
, lineno
=lineno
)
2395 def check_par(self
, par
, pmin
, pmax
, fn
, lineno
):
2396 for i
in range(len(par
)):
2400 if par
[i
][0] == '#':
2404 warnings
.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin
), UserWarning, fn
, lineno
)
2406 if (pmax
>= 0) and (len(par
) > pmax
):
2407 warnings
.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax
), UserWarning, fn
, lineno
)
2412 def get_par(line
, pmin
, pmax
, fn
, lineno
):
2413 par
= line
.split(None, pmax
)
2414 par
= self
.check_par(par
, pmin
, pmax
, fn
, lineno
)
2417 def get_par_nm(line
, pmin
, pmax
, fn
, lineno
):
2419 par
= line
.split(None, pmax
)
2422 for i
in range(len(par
)):
2423 if par
[i
][0] == '#':
2427 warnings
.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin
), UserWarning, fn
, lineno
)
2434 nmpar_first
= re
.compile(r
'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2435 nmpar_next
= re
.compile(r
'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2436 nmpar_end
= re
.compile(r
'\s*$')
2437 result
= nmpar_first
.search(nmpar
)
2440 k
= result
.group('attr')
2442 result
= nmpar_next
.search(nmpar
, pos
)
2447 p2
= nmpar_end
.search(nmpar
, pos
).start()
2457 directive
= re
.compile(r
'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2458 cdirective
= re
.compile(r
'^\s*##')
2459 report
= re
.compile(r
'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2460 comment
= re
.compile(r
'^\s*#[^.#]')
2461 empty
= re
.compile(r
'^\s*$')
2464 default_flags
= 0x00
2477 fn
, f
, lineno
, is_import
= frec
['fn'], frec
['f'], frec
['lineno'], frec
['is_import']
2481 if comment
.search(line
): continue
2482 result
= directive
.search(line
)
2483 if result
: # directive
2484 rep_result
= report
.search(result
.group('name'))
2485 if result
.group('name') == 'END_OF_CNF':
2487 elif result
.group('name') == 'OPT':
2488 ctx
= result
.group('name')
2489 par
= get_par(line
[result
.end():], 0, -1, fn
=fn
, lineno
=lineno
)
2490 if not par
: continue
2491 self
.set_opt(par
[0], par
[1:], fn
, lineno
)
2493 elif result
.group('name') in ('PDU', 'REGISTER',
2494 'MODULE', 'MODULE_IMPORT',
2495 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2496 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2497 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2498 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR',
2500 ctx
= result
.group('name')
2501 elif result
.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2502 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2503 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2504 ctx
= result
.group('name')
2506 if ctx
in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2508 if ctx
in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2510 par
= get_par(line
[result
.end():], 0, 1, fn
=fn
, lineno
=lineno
)
2513 self
.add_item('OMIT_ASSIGNMENT', key
, omit
=True, fn
=fn
, lineno
=lineno
)
2514 if ctx
in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2515 ctx
= 'NO_OMIT_ASSGN'
2518 elif result
.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2519 ctx
= result
.group('name')
2520 default_flags
= EF_TYPE|EF_VALS
2521 if ctx
== 'MODULE_EXPORTS':
2523 default_flags |
= EF_MODULE
2524 if ctx
== 'EXPORTS':
2525 par
= get_par(line
[result
.end():], 0, 5, fn
=fn
, lineno
=lineno
)
2527 par
= get_par(line
[result
.end():], 0, 1, fn
=fn
, lineno
=lineno
)
2528 if not par
: continue
2530 if (par
[0] == 'WITH_VALS'): default_flags |
= EF_TYPE|EF_VALS
2531 elif (par
[0] == 'WITHOUT_VALS'): default_flags |
= EF_TYPE
; default_flags
&= ~EF_VALS
2532 elif (par
[0] == 'ONLY_VALS'): default_flags
&= ~EF_TYPE
; default_flags |
= EF_VALS
2533 elif (ctx
== 'EXPORTS'): p
= 0
2534 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[0]), UserWarning, fn
, lineno
)
2535 for i
in range(p
, len(par
)):
2536 if (par
[i
] == 'ONLY_ENUM'): default_flags
&= ~
(EF_TYPE|EF_VALS
); default_flags |
= EF_ENUM
2537 elif (par
[i
] == 'WITH_ENUM'): default_flags |
= EF_ENUM
2538 elif (par
[i
] == 'VALS_WITH_TABLE'): default_flags |
= EF_TABLE
2539 elif (par
[i
] == 'WS_DLL'): default_flags |
= EF_WS_DLL
2540 elif (par
[i
] == 'EXTERN'): default_flags |
= EF_EXTERN
2541 elif (par
[i
] == 'NO_PROT_PREFIX'): default_flags |
= EF_NO_PROT
2542 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2543 elif result
.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2544 ctx
= result
.group('name')
2545 default_flags
= EF_ENUM
2546 if ctx
== 'MAKE_ENUM': default_flags |
= EF_NO_PROT|EF_NO_TYPE
2547 if ctx
== 'MAKE_DEFINES': default_flags |
= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2548 par
= get_par(line
[result
.end():], 0, 3, fn
=fn
, lineno
=lineno
)
2549 for i
in range(0, len(par
)):
2550 if (par
[i
] == 'NO_PROT_PREFIX'): default_flags |
= EF_NO_PROT
2551 elif (par
[i
] == 'PROT_PREFIX'): default_flags
&= ~ EF_NO_PROT
2552 elif (par
[i
] == 'NO_TYPE_PREFIX'): default_flags |
= EF_NO_TYPE
2553 elif (par
[i
] == 'TYPE_PREFIX'): default_flags
&= ~ EF_NO_TYPE
2554 elif (par
[i
] == 'UPPER_CASE'): default_flags |
= EF_UCASE
2555 elif (par
[i
] == 'NO_UPPER_CASE'): default_flags
&= ~EF_UCASE
2556 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2557 elif result
.group('name') == 'USE_VALS_EXT':
2558 ctx
= result
.group('name')
2559 default_flags
= 0xFF
2560 elif result
.group('name') == 'FN_HDR':
2562 if (ctx
in ('FN_PARS',)) and name
: minp
= 0
2563 par
= get_par(line
[result
.end():], minp
, 1, fn
=fn
, lineno
=lineno
)
2564 if (not par
) and (minp
> 0): continue
2565 ctx
= result
.group('name')
2566 if par
: name
= par
[0]
2567 elif result
.group('name') == 'FN_FTR':
2569 if (ctx
in ('FN_PARS','FN_HDR')) and name
: minp
= 0
2570 par
= get_par(line
[result
.end():], minp
, 1, fn
=fn
, lineno
=lineno
)
2571 if (not par
) and (minp
> 0): continue
2572 ctx
= result
.group('name')
2573 if par
: name
= par
[0]
2574 elif result
.group('name') == 'FN_BODY':
2575 par
= get_par_nm(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2576 if not par
: continue
2577 ctx
= result
.group('name')
2580 self
.add_item('FN_PARS', name
, pars
=par
[1], fn
=fn
, lineno
=lineno
)
2581 elif result
.group('name') == 'FN_PARS':
2582 par
= get_par_nm(line
[result
.end():], 0, 1, fn
=fn
, lineno
=lineno
)
2583 ctx
= result
.group('name')
2588 self
.add_item(ctx
, name
, pars
={}, fn
=fn
, lineno
=lineno
)
2590 self
.add_item(ctx
, par
[0], pars
=par
[1], fn
=fn
, lineno
=lineno
)
2592 elif result
.group('name') == 'CLASS':
2593 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2594 if not par
: continue
2595 ctx
= result
.group('name')
2597 add_class_ident(name
)
2598 if not name
.split('$')[-1].isupper():
2599 warnings
.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name
),
2600 UserWarning, fn
, lineno
)
2601 elif result
.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2602 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2603 if not par
: continue
2604 self
.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids
={par
[0] : par
[0]}, fn
=fn
, lineno
=lineno
)
2605 elif rep_result
: # Reports
2606 num
= rep_result
.group('num')
2607 type = rep_result
.group('type')
2609 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2610 if not par
: continue
2612 par
= get_par(line
[result
.end():], 0, 0, fn
=fn
, lineno
=lineno
)
2613 rep
= { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn
, 'lineno' : lineno
}
2616 self
.report
.setdefault(num
, []).append(rep
)
2619 elif result
.group('name') in ('INCLUDE', 'IMPORT') :
2620 is_imp
= result
.group('name') == 'IMPORT'
2621 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2623 warnings
.warn_explicit("%s requires parameter" % (result
.group('name'),), UserWarning, fn
, lineno
)
2626 #print "Try include: %s" % (fname)
2627 if (not os
.path
.exists(fname
)):
2628 fname
= os
.path
.join(os
.path
.split(fn
)[0], par
[0])
2629 #print "Try include: %s" % (fname)
2631 while not os
.path
.exists(fname
) and (i
< len(self
.include_path
)):
2632 fname
= os
.path
.join(self
.include_path
[i
], par
[0])
2633 #print "Try include: %s" % (fname)
2635 if (not os
.path
.exists(fname
)):
2637 continue # just ignore
2639 fname
= par
[0] # report error
2640 fnew
= open(fname
, "r")
2641 stack
.append({'fn' : fn
, 'f' : f
, 'lineno' : lineno
, 'is_import' : is_import
})
2642 fn
, f
, lineno
, is_import
= par
[0], fnew
, 0, is_imp
2643 elif result
.group('name') == 'END':
2646 warnings
.warn_explicit("Unknown directive '%s'" % (result
.group('name')), UserWarning, fn
, lineno
)
2649 if not empty
.match(line
):
2650 warnings
.warn_explicit("Non-empty line in empty context", UserWarning, fn
, lineno
)
2652 if empty
.match(line
): continue
2653 par
= get_par(line
, 1, -1, fn
=fn
, lineno
=lineno
)
2654 if not par
: continue
2655 self
.set_opt(par
[0], par
[1:], fn
, lineno
)
2656 elif ctx
in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2657 if empty
.match(line
): continue
2658 if ctx
== 'EXPORTS':
2659 par
= get_par(line
, 1, 6, fn
=fn
, lineno
=lineno
)
2661 par
= get_par(line
, 1, 2, fn
=fn
, lineno
=lineno
)
2662 if not par
: continue
2663 flags
= default_flags
2666 if (par
[1] == 'WITH_VALS'): flags |
= EF_TYPE|EF_VALS
2667 elif (par
[1] == 'WITHOUT_VALS'): flags |
= EF_TYPE
; flags
&= ~EF_VALS
2668 elif (par
[1] == 'ONLY_VALS'): flags
&= ~EF_TYPE
; flags |
= EF_VALS
2669 elif (ctx
== 'EXPORTS'): p
= 1
2670 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[1]), UserWarning, fn
, lineno
)
2671 for i
in range(p
, len(par
)):
2672 if (par
[i
] == 'ONLY_ENUM'): flags
&= ~
(EF_TYPE|EF_VALS
); flags |
= EF_ENUM
2673 elif (par
[i
] == 'WITH_ENUM'): flags |
= EF_ENUM
2674 elif (par
[i
] == 'VALS_WITH_TABLE'): flags |
= EF_TABLE
2675 elif (par
[i
] == 'WS_DLL'): flags |
= EF_WS_DLL
2676 elif (par
[i
] == 'EXTERN'): flags |
= EF_EXTERN
2677 elif (par
[i
] == 'NO_PROT_PREFIX'): flags |
= EF_NO_PROT
2678 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2679 self
.add_item(ctx
, par
[0], flag
=flags
, fn
=fn
, lineno
=lineno
)
2680 elif ctx
in ('MAKE_ENUM', 'MAKE_DEFINES'):
2681 if empty
.match(line
): continue
2682 par
= get_par(line
, 1, 4, fn
=fn
, lineno
=lineno
)
2683 if not par
: continue
2684 flags
= default_flags
2685 for i
in range(1, len(par
)):
2686 if (par
[i
] == 'NO_PROT_PREFIX'): flags |
= EF_NO_PROT
2687 elif (par
[i
] == 'PROT_PREFIX'): flags
&= ~ EF_NO_PROT
2688 elif (par
[i
] == 'NO_TYPE_PREFIX'): flags |
= EF_NO_TYPE
2689 elif (par
[i
] == 'TYPE_PREFIX'): flags
&= ~ EF_NO_TYPE
2690 elif (par
[i
] == 'UPPER_CASE'): flags |
= EF_UCASE
2691 elif (par
[i
] == 'NO_UPPER_CASE'): flags
&= ~EF_UCASE
2692 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2693 self
.add_item('MAKE_ENUM', par
[0], flag
=flags
, fn
=fn
, lineno
=lineno
)
2694 elif ctx
== 'USE_VALS_EXT':
2695 if empty
.match(line
): continue
2696 par
= get_par(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2697 if not par
: continue
2698 flags
= default_flags
2699 self
.add_item('USE_VALS_EXT', par
[0], flag
=flags
, fn
=fn
, lineno
=lineno
)
2701 if empty
.match(line
): continue
2702 par
= get_par(line
, 1, 5, fn
=fn
, lineno
=lineno
)
2703 if not par
: continue
2704 self
.add_pdu(par
[0:2], fn
, lineno
)
2706 self
.add_register(par
[0], par
[2:5], fn
, lineno
)
2707 elif ctx
== 'SYNTAX':
2708 if empty
.match(line
): continue
2709 par
= get_par(line
, 1, 2, fn
=fn
, lineno
=lineno
)
2710 if not par
: continue
2711 if not self
.check_item('PDU', par
[0]):
2712 self
.add_pdu(par
[0:1], fn
, lineno
)
2713 self
.add_syntax(par
, fn
, lineno
)
2714 elif ctx
== 'REGISTER':
2715 if empty
.match(line
): continue
2716 par
= get_par(line
, 3, 4, fn
=fn
, lineno
=lineno
)
2717 if not par
: continue
2718 if not self
.check_item('PDU', par
[0]):
2719 self
.add_pdu(par
[0:1], fn
, lineno
)
2720 self
.add_register(par
[0], par
[1:4], fn
, lineno
)
2721 elif ctx
in ('MODULE', 'MODULE_IMPORT'):
2722 if empty
.match(line
): continue
2723 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2724 if not par
: continue
2725 self
.add_item('MODULE', par
[0], proto
=par
[1], fn
=fn
, lineno
=lineno
)
2726 elif ctx
== 'IMPORT_TAG':
2727 if empty
.match(line
): continue
2728 par
= get_par(line
, 3, 3, fn
=fn
, lineno
=lineno
)
2729 if not par
: continue
2730 self
.add_item(ctx
, par
[0], ttag
=(par
[1], par
[2]), fn
=fn
, lineno
=lineno
)
2731 elif ctx
== 'OMIT_ASSIGNMENT':
2732 if empty
.match(line
): continue
2733 par
= get_par(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2734 if not par
: continue
2735 self
.add_item(ctx
, par
[0], omit
=True, fn
=fn
, lineno
=lineno
)
2736 elif ctx
== 'NO_OMIT_ASSGN':
2737 if empty
.match(line
): continue
2738 par
= get_par(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2739 if not par
: continue
2740 self
.add_item(ctx
, par
[0], omit
=False, fn
=fn
, lineno
=lineno
)
2741 elif ctx
== 'VIRTUAL_ASSGN':
2742 if empty
.match(line
): continue
2743 par
= get_par(line
, 2, -1, fn
=fn
, lineno
=lineno
)
2744 if not par
: continue
2745 if (len(par
[1].split('/')) > 1) and not self
.check_item('SET_TYPE', par
[1]):
2746 self
.add_item('SET_TYPE', par
[1], type=par
[0], fn
=fn
, lineno
=lineno
)
2747 self
.add_item('VIRTUAL_ASSGN', par
[1], name
=par
[0], fn
=fn
, lineno
=lineno
)
2749 self
.add_item('SET_TYPE', nm
, type=par
[0], fn
=fn
, lineno
=lineno
)
2750 if not par
[0][0].isupper():
2751 warnings
.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par
[0]),
2752 UserWarning, fn
, lineno
)
2753 elif ctx
== 'SET_TYPE':
2754 if empty
.match(line
): continue
2755 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2756 if not par
: continue
2757 if not self
.check_item('VIRTUAL_ASSGN', par
[0]):
2758 self
.add_item('SET_TYPE', par
[0], type=par
[1], fn
=fn
, lineno
=lineno
)
2759 if not par
[1][0].isupper():
2760 warnings
.warn_explicit("Set type should have uppercase name (%s)" % (par
[1]),
2761 UserWarning, fn
, lineno
)
2762 elif ctx
== 'ASSIGN_VALUE_TO_TYPE':
2763 if empty
.match(line
): continue
2764 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2765 if not par
: continue
2766 self
.add_item(ctx
, par
[0], name
=par
[1], fn
=fn
, lineno
=lineno
)
2767 elif ctx
== 'TYPE_RENAME':
2768 if empty
.match(line
): continue
2769 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2770 if not par
: continue
2771 self
.add_item('TYPE_RENAME', par
[0], eth_name
=par
[1], fn
=fn
, lineno
=lineno
)
2772 if not par
[1][0].isupper():
2773 warnings
.warn_explicit("Type should be renamed to uppercase name (%s)" % (par
[1]),
2774 UserWarning, fn
, lineno
)
2775 elif ctx
== 'FIELD_RENAME':
2776 if empty
.match(line
): continue
2777 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2778 if not par
: continue
2779 self
.add_item('FIELD_RENAME', par
[0], eth_name
=par
[1], fn
=fn
, lineno
=lineno
)
2780 if not par
[1][0].islower():
2781 warnings
.warn_explicit("Field should be renamed to lowercase name (%s)" % (par
[1]),
2782 UserWarning, fn
, lineno
)
2783 elif ctx
== 'TF_RENAME':
2784 if empty
.match(line
): continue
2785 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2786 if not par
: continue
2787 tmpu
= par
[1][0].upper() + par
[1][1:]
2788 tmpl
= par
[1][0].lower() + par
[1][1:]
2789 self
.add_item('TYPE_RENAME', par
[0], eth_name
=tmpu
, fn
=fn
, lineno
=lineno
)
2790 if not tmpu
[0].isupper():
2791 warnings
.warn_explicit("Type should be renamed to uppercase name (%s)" % (par
[1]),
2792 UserWarning, fn
, lineno
)
2793 self
.add_item('FIELD_RENAME', par
[0], eth_name
=tmpl
, fn
=fn
, lineno
=lineno
)
2794 if not tmpl
[0].islower():
2795 warnings
.warn_explicit("Field should be renamed to lowercase name (%s)" % (par
[1]),
2796 UserWarning, fn
, lineno
)
2797 elif ctx
in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2798 if empty
.match(line
): continue
2799 par
= get_par_nm(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2800 if not par
: continue
2801 self
.add_item(ctx
, par
[0], attr
=par
[1], fn
=fn
, lineno
=lineno
)
2802 elif ctx
== 'FN_PARS':
2803 if empty
.match(line
): continue
2805 par
= get_par_nm(line
, 0, 0, fn
=fn
, lineno
=lineno
)
2807 par
= get_par_nm(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2808 if not par
: continue
2810 self
.update_item(ctx
, name
, pars
=par
[0], fn
=fn
, lineno
=lineno
)
2812 self
.add_item(ctx
, par
[0], pars
=par
[1], fn
=fn
, lineno
=lineno
)
2813 elif ctx
in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2814 result
= cdirective
.search(line
)
2815 if result
: # directive
2816 line
= '#' + line
[result
.end():]
2817 self
.add_fn_line(name
, ctx
, line
, fn
=fn
, lineno
=lineno
)
2818 elif ctx
== 'CLASS':
2819 if empty
.match(line
): continue
2820 par
= get_par(line
, 1, 3, fn
=fn
, lineno
=lineno
)
2821 if not par
: continue
2822 if not set_type_to_class(name
, par
[0], par
[1:]):
2823 warnings
.warn_explicit("Could not set type of class member %s.&%s to %s" % (name
, par
[0], par
[1]),
2824 UserWarning, fn
, lineno
)
2825 elif ctx
== 'TABLE':
2826 self
.report
[name
][-1]['text'] += line
2828 def set_opt(self
, opt
, par
, fn
, lineno
):
2829 #print("set_opt: %s, %s" % (opt, par))
2831 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2833 self
.include_path
.append(relpath(par
[0]))
2834 elif opt
in ("-b", "BER", "CER", "DER"):
2835 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2836 self
.ectx
.encoding
= 'ber'
2837 elif opt
in ("PER",):
2838 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2839 self
.ectx
.encoding
= 'per'
2840 elif opt
in ("OER",):
2841 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2842 self
.ectx
.encoding
= 'oer'
2843 elif opt
in ("-p", "PROTO"):
2844 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2846 self
.ectx
.proto_opt
= par
[0]
2847 self
.ectx
.merge_modules
= True
2848 elif opt
in ("ALIGNED",):
2849 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2850 self
.ectx
.aligned
= True
2851 elif opt
in ("-u", "UNALIGNED"):
2852 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2853 self
.ectx
.aligned
= False
2854 elif opt
in ("PROTO_ROOT_NAME"):
2855 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2857 self
.proto_root_name
= par
[0]
2858 elif opt
in ("-d",):
2859 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2861 self
.ectx
.dbgopt
= par
[0]
2862 elif opt
in ("-e",):
2863 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2864 self
.ectx
.expcnf
= True
2865 elif opt
in ("-S",):
2866 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2867 self
.ectx
.merge_modules
= True
2868 elif opt
in ("GROUP_BY_PROT",):
2869 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2870 self
.ectx
.group_by_prot
= True
2871 elif opt
in ("-o",):
2872 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2874 self
.ectx
.outnm_opt
= par
[0]
2875 elif opt
in ("-O",):
2876 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2878 self
.ectx
.output
.outdir
= relpath(par
[0])
2879 elif opt
in ("-s",):
2880 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2882 self
.ectx
.output
.single_file
= relpath(par
[0])
2883 elif opt
in ("-k",):
2884 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2885 self
.ectx
.output
.keep
= True
2886 elif opt
in ("-L",):
2887 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2888 self
.suppress_line
= True
2889 elif opt
in ("EMBEDDED_PDV_CB",):
2890 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2892 self
.ectx
.default_embedded_pdv_cb
= par
[0]
2893 elif opt
in ("EXTERNAL_TYPE_CB",):
2894 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2896 self
.ectx
.default_external_type_cb
= par
[0]
2897 elif opt
in ("-r",):
2898 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2900 self
.ectx
.remove_prefix
= par
[0]
2902 warnings
.warn_explicit("Unknown option %s" % (opt
),
2903 UserWarning, fn
, lineno
)
2905 def dbg_print(self
):
2906 print("\n# Conformance values")
2907 print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value"))
2909 tbls
= sorted(self
.table
.keys())
2911 keys
= sorted(self
.table
[t
].keys())
2913 print("%-15s %4s %-15s %-20s %s" % (
2914 self
.table
[t
][k
]['fn'], self
.table
[t
][k
]['lineno'], t
, k
, str(self
.table
[t
][k
][self
.tblcfg
[t
]['val_nm']])))
2916 def unused_report(self
):
2917 tbls
= sorted(self
.table
.keys())
2919 if not self
.tblcfg
[t
]['chk_use']: continue
2920 keys
= sorted(self
.table
[t
].keys())
2922 if not self
.table
[t
][k
]['used']:
2923 warnings
.warn_explicit("Unused %s for %s" % (t
, k
),
2924 UserWarning, self
.table
[t
][k
]['fn'], self
.table
[t
][k
]['lineno'])
2925 fnms
= list(self
.fn
.keys())
2928 keys
= sorted(self
.fn
[f
].keys())
2930 if not self
.fn
[f
][k
]: continue
2931 if not self
.fn
[f
][k
]['used']:
2932 warnings
.warn_explicit("Unused %s for %s" % (k
, f
),
2933 UserWarning, self
.fn
[f
][k
]['fn'], self
.fn
[f
][k
]['lineno'])
2935 #--- EthOut -------------------------------------------------------------------
2941 self
.single_file
= None
2942 self
.created_files
= {}
2943 self
.created_files_ord
= []
2946 def outcomment(self
, ln
, comment
=None):
2948 return '%s %s\n' % (comment
, ln
)
2950 return '/* %-74s */\n' % (ln
)
2952 def created_file_add(self
, name
, keep_anyway
):
2953 name
= os
.path
.normcase(os
.path
.abspath(name
))
2954 if name
not in self
.created_files
:
2955 self
.created_files_ord
.append(name
)
2956 self
.created_files
[name
] = keep_anyway
2958 self
.created_files
[name
] = self
.created_files
[name
] or keep_anyway
2960 def created_file_exists(self
, name
):
2961 name
= os
.path
.normcase(os
.path
.abspath(name
))
2962 return name
in self
.created_files
2964 #--- output_fname -------------------------------------------------------
2965 def output_fname(self
, ftype
, ext
='c'):
2967 if ext
not in ('cnf',):
2974 #--- file_open -------------------------------------------------------
2975 def file_open(self
, ftype
, ext
='c'):
2976 fn
= self
.output_fname(ftype
, ext
=ext
)
2977 if self
.created_file_exists(fn
):
2984 fx
.write(self
.fhdr(fn
, comment
= comment
))
2986 if (not self
.single_file
and not self
.created_file_exists(fn
)):
2987 fx
.write(self
.fhdr(fn
))
2988 if not self
.ectx
.merge_modules
:
2991 if self
.ectx
.groups():
2993 if (len(self
.ectx
.modules
) > 1):
2995 for (m
, p
) in self
.ectx
.modules
:
2998 mstr
+= "Module %s" % (self
.ectx
.Module())
2999 mstr
+= " --- --- ---"
3000 fx
.write(self
.outcomment(mstr
, comment
))
3003 #--- file_close -------------------------------------------------------
3004 def file_close(self
, fx
, discard
=False, keep_anyway
=False):
3006 if discard
and not self
.created_file_exists(fx
.name
):
3009 self
.created_file_add(fx
.name
, keep_anyway
)
3010 #--- fhdr -------------------------------------------------------
3011 def fhdr(self
, fn
, comment
=None):
3013 out
+= self
.outcomment('Do not modify this file. Changes will be overwritten.', comment
)
3014 out
+= self
.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment
)
3015 out
+= self
.outcomment(os
.path
.basename(fn
), comment
)
3016 out
+= self
.outcomment(' '.join(['asn2wrs.py'] + sys
.argv
[1:]), comment
)
3018 # Make Windows path separator look like Unix path separator
3019 out
= out
.replace('\\', '/')
3020 # Change absolute paths and relative paths generated outside
3021 # source directory to paths relative to asn1/<proto> subdir.
3022 out
= re
.sub(r
'(\s)[./A-Z]\S*/dissectors\b', r
'\1../..', out
)
3023 out
= re
.sub(r
'(\s)[./A-Z]\S*/asn1/\S*?([\s/])', r
'\1.\2', out
)
3026 #--- dbg_print -------------------------------------------------------
3027 def dbg_print(self
):
3028 print("\n# Output files")
3029 print("\n".join(self
.created_files_ord
))
3032 #--- make_single_file -------------------------------------------------------
3033 def make_single_file(self
, suppress_line
):
3034 if (not self
.single_file
): return
3035 in_nm
= self
.single_file
+ '.c'
3036 out_nm
= os
.path
.join(self
.outdir
, self
.output_fname(''))
3037 self
.do_include(out_nm
, in_nm
, suppress_line
)
3038 in_nm
= self
.single_file
+ '.h'
3039 if (os
.path
.exists(in_nm
)):
3040 out_nm
= os
.path
.join(self
.outdir
, self
.output_fname('', ext
='h'))
3041 self
.do_include(out_nm
, in_nm
, suppress_line
)
3043 for fn
in self
.created_files_ord
:
3044 if not self
.created_files
[fn
]:
3047 #--- do_include -------------------------------------------------------
3048 def do_include(self
, out_nm
, in_nm
, suppress_line
):
3049 def check_file(fn
, fnlist
):
3050 fnfull
= os
.path
.normcase(os
.path
.abspath(fn
))
3051 if (fnfull
in fnlist
and os
.path
.exists(fnfull
)):
3052 return os
.path
.normpath(fn
)
3054 fin
= open(in_nm
, "r")
3055 fout
= open(out_nm
, "w")
3056 fout
.write(self
.fhdr(out_nm
))
3057 if (not suppress_line
):
3058 fout
.write('/* Input file: ' + os
.path
.basename(in_nm
) +' */\n')
3060 fout
.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm
)))
3062 include
= re
.compile(r
'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re
.IGNORECASE
)
3067 cont_linenum
= cont_linenum
+ 1
3068 line
= fin
.readline()
3069 if (line
== ''): break
3071 result
= include
.search(line
)
3072 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
3074 ifile
= check_file(os
.path
.join(os
.path
.split(in_nm
)[0], result
.group('fname')), self
.created_files
)
3076 ifile
= check_file(os
.path
.join(self
.outdir
, result
.group('fname')), self
.created_files
)
3078 ifile
= check_file(result
.group('fname'), self
.created_files
)
3080 if (not suppress_line
):
3082 fout
.write('/*--- Included file: ' + ifile
+ ' ---*/\n')
3083 fout
.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile
)))
3084 finc
= open(ifile
, "r")
3085 fout
.write(finc
.read())
3086 if (not suppress_line
):
3088 fout
.write('/*--- End of included file: ' + ifile
+ ' ---*/\n')
3089 fout
.write('#line %u "%s"\n' % (cont_linenum
+1, rel_dissector_path(in_nm
)) )
3098 #--- Node ---------------------------------------------------------------------
3100 def __init__(self
,*args
, **kw
):
3102 self
.type = self
.__class
__.__name
__
3104 assert (len(args
) == 1)
3106 self
.__dict
__.update (kw
)
3107 def str_child (self
, key
, child
, depth
):
3108 indent
= " " * (2 * depth
)
3109 keystr
= indent
+ key
+ ": "
3110 if key
== 'type': # already processed in str_depth
3112 if isinstance (child
, Node
): # ugh
3113 return keystr
+ "\n" + child
.str_depth (depth
+1)
3114 if isinstance(child
, type ([])):
3117 if isinstance (x
, Node
):
3118 l
.append (x
.str_depth (depth
+1))
3120 l
.append (indent
+ " " + str(x
) + "\n")
3121 return keystr
+ "[\n" + ''.join(l
) + indent
+ "]\n"
3123 return keystr
+ str (child
) + "\n"
3124 def str_depth (self
, depth
): # ugh
3125 indent
= " " * (2 * depth
)
3126 l
= ["%s%s" % (indent
, self
.type)]
3127 l
.append ("".join ([self
.str_child (k_v
[0], k_v
[1], depth
+ 1) for k_v
in list(self
.__dict
__.items ())]))
3128 return "\n".join (l
)
3130 return "\n" + self
.str_depth (0)
3131 def to_python (self
, ctx
):
3132 return self
.str_depth (ctx
.indent_lev
)
3134 def eth_reg(self
, ident
, ectx
):
3137 def fld_obj_repr(self
, ectx
):
3138 return "/* TO DO %s */" % (str(self
))
3141 #--- ValueAssignment -------------------------------------------------------------
3142 class ValueAssignment (Node
):
3143 def __init__(self
,*args
, **kw
) :
3144 Node
.__init
__ (self
,*args
, **kw
)
3146 def eth_reg(self
, ident
, ectx
):
3147 if ectx
.conform
.omit_assignment('V', self
.ident
, ectx
.Module()): return # Assignment to omit
3148 ectx
.eth_reg_vassign(self
)
3149 ectx
.eth_reg_value(self
.ident
, self
.typ
, self
.val
)
3151 #--- ObjectAssignment -------------------------------------------------------------
3152 class ObjectAssignment (Node
):
3153 def __init__(self
,*args
, **kw
) :
3154 Node
.__init
__ (self
,*args
, **kw
)
3156 def __eq__(self
, other
):
3157 if self
.cls
!= other
.cls
:
3159 if len(self
.val
) != len(other
.val
):
3161 for f
in (list(self
.val
.keys())):
3162 if f
not in other
.val
:
3164 if isinstance(self
.val
[f
], Node
) and isinstance(other
.val
[f
], Node
):
3165 if not self
.val
[f
].fld_obj_eq(other
.val
[f
]):
3168 if str(self
.val
[f
]) != str(other
.val
[f
]):
3172 def eth_reg(self
, ident
, ectx
):
3173 def make_virtual_type(cls
, field
, prefix
):
3174 if isinstance(self
.val
, str): return
3175 if field
in self
.val
and not isinstance(self
.val
[field
], Type_Ref
):
3176 vnm
= prefix
+ '-' + self
.ident
3177 virtual_tr
= Type_Ref(val
= vnm
)
3179 self
.val
[field
] = virtual_tr
3180 ectx
.eth_reg_assign(vnm
, t
, virt
=True)
3181 ectx
.eth_reg_type(vnm
, t
)
3182 t
.eth_reg_sub(vnm
, ectx
)
3183 if field
in self
.val
and ectx
.conform
.check_item('PDU', cls
+ '.' + field
):
3184 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
))
3186 # end of make_virtual_type()
3187 if ectx
.conform
.omit_assignment('V', self
.ident
, ectx
.Module()): return # Assignment to omit
3188 self
.module
= ectx
.Module()
3189 ectx
.eth_reg_oassign(self
)
3190 if (self
.cls
== 'TYPE-IDENTIFIER') or (self
.cls
== 'ABSTRACT-SYNTAX'):
3191 make_virtual_type(self
.cls
, '&Type', 'TYPE')
3192 if (self
.cls
== 'OPERATION'):
3193 make_virtual_type(self
.cls
, '&ArgumentType', 'ARG')
3194 make_virtual_type(self
.cls
, '&ResultType', 'RES')
3195 if (self
.cls
== 'ERROR'):
3196 make_virtual_type(self
.cls
, '&ParameterType', 'PAR')
3199 #--- Type ---------------------------------------------------------------------
3201 def __init__(self
,*args
, **kw
) :
3205 self
.named_list
= None
3206 Node
.__init
__ (self
,*args
, **kw
)
3209 if self
.name
is None :
3214 def HasConstraint(self
):
3215 if self
.constr
is None :
3220 def HasSizeConstraint(self
):
3221 return self
.HasConstraint() and self
.constr
.IsSize()
3223 def HasValueConstraint(self
):
3224 return self
.HasConstraint() and self
.constr
.IsValue()
3226 def HasPermAlph(self
):
3227 return self
.HasConstraint() and self
.constr
.IsPermAlph()
3229 def HasContentsConstraint(self
):
3230 return self
.HasConstraint() and self
.constr
.IsContents()
3232 def HasOwnTag(self
):
3233 return len(self
.tags
) > 0
3235 def HasImplicitTag(self
, ectx
):
3236 return (self
.HasOwnTag() and self
.tags
[0].IsImplicit(ectx
))
3238 def IndetermTag(self
, ectx
):
3241 def AddTag(self
, tag
):
3242 self
.tags
[0:0] = [tag
]
3244 def GetTag(self
, ectx
):
3245 #print "GetTag(%s)\n" % self.name;
3246 if (self
.HasOwnTag()):
3247 return self
.tags
[0].GetTag(ectx
)
3249 return self
.GetTTag(ectx
)
3251 def GetTTag(self
, ectx
):
3252 print("#Unhandled GetTTag() in %s" % (self
.type))
3253 print(self
.str_depth(1))
3254 return ('BER_CLASS_unknown', 'TAG_unknown')
3256 def SetName(self
, name
):
3259 def AddConstraint(self
, constr
):
3260 if not self
.HasConstraint():
3261 self
.constr
= constr
3263 self
.constr
= Constraint(type = 'Intersection', subtype
= [self
.constr
, constr
])
3265 def eth_tname(self
):
3266 return '#' + self
.type + '_' + str(id(self
))
3268 def eth_ftype(self
, ectx
):
3269 return ('FT_NONE', 'BASE_NONE')
3271 def eth_strings(self
):
3274 def eth_omit_field(self
):
3277 def eth_need_tree(self
):
3280 def eth_has_vals(self
):
3283 def eth_has_enum(self
, tname
, ectx
):
3284 return self
.eth_has_vals() and (ectx
.eth_type
[tname
]['enum'] & EF_ENUM
)
3286 def eth_need_pdu(self
, ectx
):
3289 def eth_named_bits(self
):
3292 def eth_reg_sub(self
, ident
, ectx
):
3295 def get_components(self
, ectx
):
3296 print("#Unhandled get_components() in %s" % (self
.type))
3297 print(self
.str_depth(1))
3300 def sel_req(self
, sel
, ectx
):
3301 print("#Selection '%s' required for non-CHOICE type %s" % (sel
, self
.type))
3302 print(self
.str_depth(1))
3304 def fld_obj_eq(self
, other
):
3305 return isinstance(other
, Type
) and (self
.eth_tname() == other
.eth_tname())
3307 def eth_reg(self
, ident
, ectx
, tstrip
=0, tagflag
=False, selflag
=False, idx
='', parent
=None):
3308 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3310 if (ectx
.NeedTags() and (len(self
.tags
) > tstrip
)):
3312 for i
in range(len(self
.tags
)-1, tstrip
-1, -1):
3313 tagged_type
= TaggedType(val
=tagged_type
, tstrip
=i
)
3314 tagged_type
.AddTag(self
.tags
[i
])
3315 if not tagflag
: # 1st tagged level
3316 if self
.IsNamed() and not selflag
:
3317 tagged_type
.SetName(self
.name
)
3318 tagged_type
.eth_reg(ident
, ectx
, tstrip
=1, tagflag
=tagflag
, idx
=idx
, parent
=parent
)
3321 if ident
and self
.IsNamed() and not tagflag
and not selflag
:
3322 nm
= ident
+ '/' + self
.name
3325 elif self
.IsNamed():
3327 if not ident
and ectx
.conform
.omit_assignment('T', nm
, ectx
.Module()): return # Assignment to omit
3328 if not ident
: # Assignment
3329 ectx
.eth_reg_assign(nm
, self
)
3330 if self
.type == 'Type_Ref' and not self
.tr_need_own_fn(ectx
):
3331 ectx
.eth_reg_type(nm
, self
)
3332 virtual_tr
= Type_Ref(val
=ectx
.conform
.use_item('SET_TYPE', nm
))
3333 if (self
.type == 'Type_Ref') or ectx
.conform
.check_item('SET_TYPE', nm
):
3334 if ident
and (ectx
.conform
.check_item('TYPE_RENAME', nm
) or ectx
.conform
.get_fn_presence(nm
) or selflag
):
3335 if ectx
.conform
.check_item('SET_TYPE', nm
):
3336 ectx
.eth_reg_type(nm
, virtual_tr
) # dummy Type Reference
3338 ectx
.eth_reg_type(nm
, self
) # new type
3340 elif ectx
.conform
.check_item('SET_TYPE', nm
):
3341 trnm
= ectx
.conform
.use_item('SET_TYPE', nm
)
3342 elif (self
.type == 'Type_Ref') and self
.tr_need_own_fn(ectx
):
3343 ectx
.eth_reg_type(nm
, self
) # need own function, e.g. for constraints
3348 ectx
.eth_reg_type(nm
, self
, mod
= ectx
.Module())
3350 if ectx
.conform
.check_item('VIRTUAL_ASSGN', nm
):
3351 vnm
= ectx
.conform
.use_item('VIRTUAL_ASSGN', nm
)
3352 ectx
.eth_reg_assign(vnm
, self
, virt
=True)
3353 ectx
.eth_reg_type(vnm
, self
)
3354 self
.eth_reg_sub(vnm
, ectx
)
3355 if parent
and (ectx
.type[parent
]['val'].type == 'TaggedType'):
3356 ectx
.type[parent
]['val'].eth_set_val_name(parent
, trnm
, ectx
)
3357 if ident
and not tagflag
and not self
.eth_omit_field():
3358 ectx
.eth_reg_field(nm
, trnm
, idx
=idx
, parent
=parent
, impl
=self
.HasImplicitTag(ectx
))
3359 if ectx
.conform
.check_item('SET_TYPE', nm
):
3360 virtual_tr
.eth_reg_sub(nm
, ectx
)
3362 self
.eth_reg_sub(nm
, ectx
)
3364 def eth_get_size_constr(self
, ectx
):
3365 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3366 if self
.HasSizeConstraint():
3367 if self
.constr
.IsSize():
3368 (minv
, maxv
, ext
) = self
.constr
.GetSize(ectx
)
3369 if (self
.constr
.type == 'Intersection'):
3370 if self
.constr
.subtype
[0].IsSize():
3371 (minv
, maxv
, ext
) = self
.constr
.subtype
[0].GetSize(ectx
)
3372 elif self
.constr
.subtype
[1].IsSize():
3373 (minv
, maxv
, ext
) = self
.constr
.subtype
[1].GetSize(ectx
)
3374 if minv
== 'MIN': minv
= 'NO_BOUND'
3375 if maxv
== 'MAX': maxv
= 'NO_BOUND'
3376 if (ext
): ext
= 'true'
3378 return (minv
, maxv
, ext
)
3380 def eth_get_value_constr(self
, ectx
, named_list
=[]):
3381 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3382 if self
.HasValueConstraint():
3383 # If this is a subclass (Type_Ref), we may have passed in the
3384 # NamedNumberList of the parent class. Otherwise use our own,
3386 named_list
= named_list
or self
.named_list
3387 (minv
, maxv
, ext
) = self
.constr
.GetValue(ectx
, named_list
)
3388 if minv
== 'MIN': minv
= 'NO_BOUND'
3389 if maxv
== 'MAX': maxv
= 'NO_BOUND'
3390 if str(minv
).isdigit():
3392 elif (str(minv
)[0] == "-") and str(minv
)[1:].isdigit():
3393 if (int(minv
) == -(2**31)):
3395 elif (int(minv
) < -(2**31)):
3396 minv
= "INT64_C(%s)" % (str(minv
))
3397 if str(maxv
).isdigit():
3398 if (int(maxv
) >= 2**32):
3399 maxv
= "UINT64_C(%s)" % (str(maxv
))
3402 if (ext
): ext
= 'true'
3404 return (minv
, maxv
, ext
)
3406 def eth_get_alphabet_constr(self
, ectx
):
3407 (alph
, alphlen
) = ('NULL', '0')
3408 if self
.HasPermAlph():
3409 alph
= self
.constr
.GetPermAlph(ectx
)
3412 if (alph
!= 'NULL'):
3413 if (((alph
[0] + alph
[-1]) == '""') and (not alph
.count('"', 1, -1))):
3414 alphlen
= str(len(alph
) - 2)
3416 alphlen
= 'strlen(%s)' % (alph
)
3417 return (alph
, alphlen
)
3419 def eth_type_vals(self
, tname
, ectx
):
3420 if self
.eth_has_vals():
3421 print("#Unhandled eth_type_vals('%s') in %s" % (tname
, self
.type))
3422 print(self
.str_depth(1))
3425 def eth_type_enum(self
, tname
, ectx
):
3426 if self
.eth_has_enum(tname
, ectx
):
3427 print("#Unhandled eth_type_enum('%s') in %s" % (tname
, self
.type))
3428 print(self
.str_depth(1))
3431 def eth_type_default_table(self
, ectx
, tname
):
3434 def eth_type_default_body(self
, ectx
, tname
):
3435 print("#Unhandled eth_type_default_body('%s') in %s" % (tname
, self
.type))
3436 print(self
.str_depth(1))
3439 def eth_type_default_pars(self
, ectx
, tname
):
3446 'OFFSET' : 'offset',
3448 'HF_INDEX' : 'hf_index',
3450 'IMPLICIT_TAG' : 'implicit_tag',
3452 if (ectx
.eth_type
[tname
]['tree']):
3453 pars
['ETT_INDEX'] = ectx
.eth_type
[tname
]['tree']
3454 if (ectx
.merge_modules
):
3457 pars
['PROTOP'] = ectx
.eth_type
[tname
]['proto'] + '_'
3460 def eth_type_fn(self
, proto
, tname
, ectx
):
3461 body
= self
.eth_type_default_body(ectx
, tname
)
3462 pars
= self
.eth_type_default_pars(ectx
, tname
)
3463 if ectx
.conform
.check_item('FN_PARS', tname
):
3464 pars
.update(ectx
.conform
.use_item('FN_PARS', tname
))
3465 elif ectx
.conform
.check_item('FN_PARS', ectx
.eth_type
[tname
]['ref'][0]):
3466 pars
.update(ectx
.conform
.use_item('FN_PARS', ectx
.eth_type
[tname
]['ref'][0]))
3467 pars
['DEFAULT_BODY'] = body
3469 for k
in list(pars
.keys()):
3471 pars
[k
] = pars
[k
] % pars
3472 except (ValueError,TypeError):
3473 raise sys
.exc_info()[0]("%s\n%s" % (str(pars
), sys
.exc_info()[1]))
3475 out
+= self
.eth_type_default_table(ectx
, tname
) % pars
3476 out
+= ectx
.eth_type_fn_hdr(tname
)
3477 out
+= ectx
.eth_type_fn_body(tname
, body
, pars
=pars
)
3478 out
+= ectx
.eth_type_fn_ftr(tname
)
3481 #--- Value --------------------------------------------------------------------
3483 def __init__(self
,*args
, **kw
) :
3485 Node
.__init
__ (self
,*args
, **kw
)
3487 def SetName(self
, name
) :
3490 def to_str(self
, ectx
):
3491 return str(self
.val
)
3496 def fld_obj_repr(self
, ectx
):
3497 return self
.to_str(ectx
)
3499 #--- Value_Ref -----------------------------------------------------------------
3500 class Value_Ref (Value
):
3501 def to_str(self
, ectx
):
3502 return asn2c(self
.val
)
3504 #--- ObjectClass ---------------------------------------------------------------------
3505 class ObjectClass (Node
):
3506 def __init__(self
,*args
, **kw
) :
3508 Node
.__init
__ (self
,*args
, **kw
)
3510 def SetName(self
, name
):
3512 add_class_ident(self
.name
)
3514 def eth_reg(self
, ident
, ectx
):
3515 if ectx
.conform
.omit_assignment('C', self
.name
, ectx
.Module()): return # Assignment to omit
3516 ectx
.eth_reg_objectclass(self
.name
, self
)
3518 #--- Class_Ref -----------------------------------------------------------------
3519 class Class_Ref (ObjectClass
):
3522 #--- ObjectClassDefn ---------------------------------------------------------------------
3523 class ObjectClassDefn (ObjectClass
):
3524 def reg_types(self
):
3525 for fld
in self
.fields
:
3526 repr = fld
.fld_repr()
3527 set_type_to_class(self
.name
, repr[0], repr[1:])
3530 #--- Tag ---------------------------------------------------------------
3532 def to_python (self
, ctx
):
3533 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx
, self
.tag
.cls
,
3536 self
.typ
.to_python (ctx
))
3537 def IsImplicit(self
, ectx
):
3538 return ((self
.mode
== 'IMPLICIT') or ((self
.mode
== 'default') and (ectx
.tag_def
!= 'EXPLICIT')))
3540 def GetTag(self
, ectx
):
3542 if (self
.cls
== 'UNIVERSAL'): tc
= 'BER_CLASS_UNI'
3543 elif (self
.cls
== 'APPLICATION'): tc
= 'BER_CLASS_APP'
3544 elif (self
.cls
== 'CONTEXT'): tc
= 'BER_CLASS_CON'
3545 elif (self
.cls
== 'PRIVATE'): tc
= 'BER_CLASS_PRI'
3546 return (tc
, self
.num
)
3548 def eth_tname(self
):
3550 if (self
.cls
== 'UNIVERSAL'): n
= 'U'
3551 elif (self
.cls
== 'APPLICATION'): n
= 'A'
3552 elif (self
.cls
== 'CONTEXT'): n
= 'C'
3553 elif (self
.cls
== 'PRIVATE'): n
= 'P'
3554 return n
+ str(self
.num
)
3556 #--- Constraint ---------------------------------------------------------------
3558 class Constraint (Node
):
3559 def to_python (self
, ctx
):
3560 print("Ignoring constraint:", self
.type)
3561 return self
.subtype
.typ
.to_python (ctx
)
3563 return "Constraint: type=%s, subtype=%s" % (self
.type, self
.subtype
)
3565 def eth_tname(self
):
3566 return '#' + self
.type + '_' + str(id(self
))
3569 return (self
.type == 'Size' and self
.subtype
.IsValue()) \
3570 or (self
.type == 'Intersection' and (self
.subtype
[0].IsSize() or self
.subtype
[1].IsSize())) \
3572 def GetSize(self
, ectx
):
3573 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3575 if self
.type == 'Size':
3576 (minv
, maxv
, ext
) = self
.subtype
.GetValue(ectx
)
3577 ext
= ext
or (hasattr(self
, 'ext') and self
.ext
)
3578 elif self
.type == 'Intersection':
3579 if self
.subtype
[0].IsSize() and not self
.subtype
[1].IsSize():
3580 (minv
, maxv
, ext
) = self
.subtype
[0].GetSize(ectx
)
3581 elif not self
.subtype
[0].IsSize() and self
.subtype
[1].IsSize():
3582 (minv
, maxv
, ext
) = self
.subtype
[1].GetSize(ectx
)
3583 return (minv
, maxv
, ext
)
3586 return self
.type == 'SingleValue' \
3587 or self
.type == 'ValueRange' \
3588 or (self
.type == 'Intersection' and (self
.subtype
[0].IsValue() or self
.subtype
[1].IsValue())) \
3589 or (self
.type == 'Union' and (self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue()))
3591 def GetValue(self
, ectx
, named_list
=[]):
3592 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3594 if self
.type == 'SingleValue':
3595 minv
= ectx
.value_get_eth(self
.subtype
)
3597 minv
= next((e
.val
for e
in named_list
if minv
== e
.ident
), minv
)
3599 # named_list is not an iterable, e.g. None
3602 ext
= hasattr(self
, 'ext') and self
.ext
3603 elif self
.type == 'ValueRange':
3604 minv
= ectx
.value_get_eth(self
.subtype
[0])
3605 maxv
= ectx
.value_get_eth(self
.subtype
[1])
3607 minv
= next((e
.val
for e
in named_list
if minv
== e
.ident
), minv
)
3608 maxv
= next((e
.val
for e
in named_list
if maxv
== e
.ident
), maxv
)
3610 # named_list is not an iterable
3612 ext
= hasattr(self
, 'ext') and self
.ext
3613 elif self
.type == 'Intersection':
3614 if self
.subtype
[0].IsValue() and not self
.subtype
[1].IsValue():
3615 (minv
, maxv
, ext
) = self
.subtype
[0].GetValue(ectx
, named_list
)
3616 elif not self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue():
3617 (minv
, maxv
, ext
) = self
.subtype
[1].GetValue(ectx
, named_list
)
3618 elif self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue():
3619 v0
= self
.subtype
[0].GetValue(ectx
, named_list
)
3620 v1
= self
.subtype
[1].GetValue(ectx
, named_list
)
3621 (minv
, maxv
, ext
) = (ectx
.value_max(v0
[0],v1
[0]), ectx
.value_min(v0
[1],v1
[1]), v0
[2] and v1
[2])
3622 elif self
.type == 'Union':
3623 if self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue():
3624 v0
= self
.subtype
[0].GetValue(ectx
, named_list
)
3625 v1
= self
.subtype
[1].GetValue(ectx
, named_list
)
3626 (minv
, maxv
, ext
) = (ectx
.value_min(v0
[0],v1
[0]), ectx
.value_max(v0
[1],v1
[1]), hasattr(self
, 'ext') and self
.ext
)
3627 return (minv
, maxv
, ext
)
3629 def IsAlphabet(self
):
3630 return self
.type == 'SingleValue' \
3631 or self
.type == 'ValueRange' \
3632 or (self
.type == 'Intersection' and (self
.subtype
[0].IsAlphabet() or self
.subtype
[1].IsAlphabet())) \
3633 or (self
.type == 'Union' and (self
.subtype
[0].IsAlphabet() and self
.subtype
[1].IsAlphabet()))
3635 def GetAlphabet(self
, ectx
):
3637 if self
.IsAlphabet():
3638 if self
.type == 'SingleValue':
3639 alph
= ectx
.value_get_eth(self
.subtype
)
3640 elif self
.type == 'ValueRange':
3641 if ((len(self
.subtype
[0]) == 3) and ((self
.subtype
[0][0] + self
.subtype
[0][-1]) == '""') \
3642 and (len(self
.subtype
[1]) == 3) and ((self
.subtype
[1][0] + self
.subtype
[1][-1]) == '""')):
3644 for c
in range(ord(self
.subtype
[0][1]), ord(self
.subtype
[1][1]) + 1):
3647 elif self
.type == 'Union':
3648 if self
.subtype
[0].IsAlphabet() and self
.subtype
[1].IsAlphabet():
3649 a0
= self
.subtype
[0].GetAlphabet(ectx
)
3650 a1
= self
.subtype
[1].GetAlphabet(ectx
)
3651 if (((a0
[0] + a0
[-1]) == '""') and not a0
.count('"', 1, -1) \
3652 and ((a1
[0] + a1
[-1]) == '""') and not a1
.count('"', 1, -1)):
3653 alph
= '"' + a0
[1:-1] + a1
[1:-1] + '"'
3655 alph
= a0
+ ' ' + a1
3658 def IsPermAlph(self
):
3659 return self
.type == 'From' and self
.subtype
.IsAlphabet() \
3660 or (self
.type == 'Intersection' and (self
.subtype
[0].IsPermAlph() or self
.subtype
[1].IsPermAlph())) \
3662 def GetPermAlph(self
, ectx
):
3664 if self
.IsPermAlph():
3665 if self
.type == 'From':
3666 alph
= self
.subtype
.GetAlphabet(ectx
)
3667 elif self
.type == 'Intersection':
3668 if self
.subtype
[0].IsPermAlph() and not self
.subtype
[1].IsPermAlph():
3669 alph
= self
.subtype
[0].GetPermAlph(ectx
)
3670 elif not self
.subtype
[0].IsPermAlph() and self
.subtype
[1].IsPermAlph():
3671 alph
= self
.subtype
[1].GetPermAlph(ectx
)
3674 def IsContents(self
):
3675 return self
.type == 'Contents' \
3676 or (self
.type == 'Intersection' and (self
.subtype
[0].IsContents() or self
.subtype
[1].IsContents())) \
3678 def GetContents(self
, ectx
):
3680 if self
.IsContents():
3681 if self
.type == 'Contents':
3682 if self
.subtype
.type == 'Type_Ref':
3683 contents
= self
.subtype
.val
3684 elif self
.type == 'Intersection':
3685 if self
.subtype
[0].IsContents() and not self
.subtype
[1].IsContents():
3686 contents
= self
.subtype
[0].GetContents(ectx
)
3687 elif not self
.subtype
[0].IsContents() and self
.subtype
[1].IsContents():
3688 contents
= self
.subtype
[1].GetContents(ectx
)
3691 def IsNegativ(self
):
3693 return isinstance(sval
, str) and (sval
[0] == '-')
3694 if self
.type == 'SingleValue':
3695 return is_neg(self
.subtype
)
3696 elif self
.type == 'ValueRange':
3697 if self
.subtype
[0] == 'MIN': return True
3698 return is_neg(self
.subtype
[0])
3701 def eth_constrname(self
):
3703 if isinstance(val
, Value_Ref
):
3704 return asn2c(val
.val
)
3707 return 'M' + str(-int(val
))
3709 return str(int(val
))
3710 except (ValueError, TypeError):
3711 return asn2c(str(val
))
3714 if hasattr(self
, 'ext') and self
.ext
:
3716 if self
.type == 'SingleValue':
3717 return int2str(self
.subtype
) + ext
3718 elif self
.type == 'ValueRange':
3719 return int2str(self
.subtype
[0]) + '_' + int2str(self
.subtype
[1]) + ext
3720 elif self
.type == 'Size':
3721 return 'SIZE_' + self
.subtype
.eth_constrname() + ext
3723 if (not hasattr(self
, 'constr_num')):
3726 self
.constr_num
= constr_cnt
3727 return 'CONSTR%03d%s' % (self
.constr_num
, ext
)
3729 def Needs64b(self
, ectx
):
3730 (minv
, maxv
, ext
) = self
.GetValue(ectx
)
3731 if ((str(minv
).isdigit() or ((str(minv
)[0] == "-") and str(minv
)[1:].isdigit())) \
3732 and (str(maxv
).isdigit() or ((str(maxv
)[0] == "-") and str(maxv
)[1:].isdigit())) \
3733 and ((abs(int(maxv
) - int(minv
)) >= 2**32) or (int(minv
) < -2**31) or (int(maxv
) >= 2**32))) \
3734 or (maxv
== 'MAX') or (minv
== 'MIN'):
3738 class Module (Node
):
3739 def to_python (self
, ctx
):
3740 ctx
.tag_def
= self
.tag_def
.dfl_tag
3742 %s""" % (self
.ident
, self
.body
.to_python (ctx
))
3745 return self
.ident
.val
3747 def get_proto(self
, ectx
):
3751 prot
= ectx
.conform
.use_item('MODULE', self
.get_name(), val_dflt
=self
.get_name())
3754 def to_eth(self
, ectx
):
3755 ectx
.tags_def
= 'EXPLICIT' # default = explicit
3756 ectx
.proto
= self
.get_proto(ectx
)
3757 ectx
.tag_def
= self
.tag_def
.dfl_tag
3758 ectx
.eth_reg_module(self
)
3759 self
.body
.to_eth(ectx
)
3761 class Module_Body (Node
):
3762 def to_python (self
, ctx
):
3763 # XXX handle exports, imports.
3764 list = [x
.to_python (ctx
) for x
in self
.assign_list
]
3765 list = [a
for a
in list if a
!= '']
3766 return "\n".join(list)
3768 def to_eth(self
, ectx
):
3770 ectx
.eth_exports(self
.exports
)
3772 for i
in self
.imports
:
3774 proto
= ectx
.conform
.use_item('MODULE', mod
, val_dflt
=mod
)
3775 ectx
.eth_module_dep_add(ectx
.Module(), mod
)
3776 for s
in i
.symbol_list
:
3777 if isinstance(s
, Type_Ref
):
3778 ectx
.eth_import_type(s
.val
, mod
, proto
)
3779 elif isinstance(s
, Value_Ref
):
3780 ectx
.eth_import_value(s
.val
, mod
, proto
)
3781 elif isinstance(s
, Class_Ref
):
3782 ectx
.eth_import_class(s
.val
, mod
, proto
)
3784 msg
= 'Unknown kind of imported symbol %s from %s' % (str(s
), mod
)
3785 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3787 for a
in self
.assign_list
:
3790 class Default_Tags (Node
):
3791 def to_python (self
, ctx
): # not to be used directly
3794 # XXX should just calculate dependencies as we go along.
3795 def calc_dependencies (node
, dict, trace
= 0):
3796 if not hasattr (node
, '__dict__'):
3797 if trace
: print("#returning, node=", node
)
3799 if isinstance (node
, Type_Ref
):
3801 if trace
: print("#Setting", node
.val
)
3803 for (a
, val
) in list(node
.__dict
__.items ()):
3804 if trace
: print("# Testing node ", node
, "attr", a
, " val", val
)
3807 elif isinstance (val
, Node
):
3808 calc_dependencies (val
, dict, trace
)
3809 elif isinstance (val
, type ([])):
3811 calc_dependencies (v
, dict, trace
)
3814 class Type_Assign (Node
):
3815 def __init__ (self
, *args
, **kw
):
3816 Node
.__init
__ (self
, *args
, **kw
)
3817 if isinstance (self
.val
, Tag
): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3818 to_test
= self
.val
.typ
3821 if isinstance (to_test
, SequenceType
):
3822 to_test
.sequence_name
= self
.name
.name
3824 def to_python (self
, ctx
):
3826 calc_dependencies (self
.val
, dep_dict
, 0)
3827 depend_list
= list(dep_dict
.keys ())
3828 return ctx
.register_assignment (self
.name
.name
,
3829 self
.val
.to_python (ctx
),
3832 class PyQuote (Node
):
3833 def to_python (self
, ctx
):
3834 return ctx
.register_pyquote (self
.val
)
3836 #--- Type_Ref -----------------------------------------------------------------
3837 class Type_Ref (Type
):
3838 def to_python (self
, ctx
):
3841 def eth_reg_sub(self
, ident
, ectx
):
3842 ectx
.eth_dep_add(ident
, self
.val
)
3844 def eth_tname(self
):
3845 if self
.HasSizeConstraint() or self
.HasValueConstraint():
3846 return asn2c(self
.val
) + '_' + self
.constr
.eth_constrname()
3848 return asn2c(self
.val
)
3850 def tr_need_own_fn(self
, ectx
):
3851 return (ectx
.Per() or ectx
.Oer()) and (self
.HasSizeConstraint() or self
.HasValueConstraint())
3853 def fld_obj_repr(self
, ectx
):
3856 def get_components(self
, ectx
):
3857 if self
.val
not in ectx
.type or ectx
.type[self
.val
]['import']:
3858 msg
= "Can not get COMPONENTS OF %s which is imported type" % (self
.val
)
3859 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3862 return ectx
.type[self
.val
]['val'].get_components(ectx
)
3864 def GetTTag(self
, ectx
):
3865 #print "GetTTag(%s)\n" % self.val;
3866 if (ectx
.type[self
.val
]['import']):
3867 if 'ttag' not in ectx
.type[self
.val
]:
3868 ttag
= ectx
.get_ttag_from_all(self
.val
, ectx
.type[self
.val
]['import'])
3869 if not ttag
and not ectx
.conform
.check_item('IMPORT_TAG', self
.val
):
3870 msg
= 'Missing tag information for imported type %s from %s (%s)' % (self
.val
, ectx
.type[self
.val
]['import'], ectx
.type[self
.val
]['proto'])
3871 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3872 ttag
= ('-1/*imported*/', '-1/*imported*/')
3873 ectx
.type[self
.val
]['ttag'] = ectx
.conform
.use_item('IMPORT_TAG', self
.val
, val_dflt
=ttag
)
3874 return ectx
.type[self
.val
]['ttag']
3876 return ectx
.type[self
.val
]['val'].GetTag(ectx
)
3878 def IndetermTag(self
, ectx
):
3879 if (ectx
.type[self
.val
]['import']):
3882 return ectx
.type[self
.val
]['val'].IndetermTag(ectx
)
3884 def eth_get_value_constr(self
, ectx
):
3885 # NamedNumberList of the parent type
3886 named_list
= ectx
.type[self
.val
]['val'].named_list
3887 return super(Type_Ref
, self
).eth_get_value_constr(ectx
, named_list
)
3889 def eth_type_default_pars(self
, ectx
, tname
):
3891 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
3894 t
= ectx
.type[self
.val
]['ethname']
3895 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
3896 pars
['TYPE_REF_TNAME'] = t
3897 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3898 if self
.HasSizeConstraint():
3899 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
3900 elif self
.HasValueConstraint():
3901 # We ought to enforce X.680 51.4.2 - 'All values in the "ValueRange"
3902 # are required to be in the root of the parent type' by examining
3903 # MIN_VAL and MAX_VAL of the parent type.
3904 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_value_constr(ectx
)
3907 def eth_type_default_body(self
, ectx
, tname
):
3909 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3910 par
=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3911 elif (ectx
.Per() or ectx
.Oer()):
3912 if self
.HasSizeConstraint():
3913 body
= ectx
.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret
='offset',
3914 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3915 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3916 elif self
.HasValueConstraint() and isinstance(ectx
.type[self
.val
]['val'], IntegerType
):
3917 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret
='offset',
3918 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3919 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
3921 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3922 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3924 body
= '#error Can not decode %s' % (tname
)
3927 #--- SelectionType ------------------------------------------------------------
3928 class SelectionType (Type
):
3929 def to_python (self
, ctx
):
3932 def sel_of_typeref(self
):
3933 return self
.typ
.type == 'Type_Ref'
3935 def eth_reg_sub(self
, ident
, ectx
):
3936 if not self
.sel_of_typeref():
3939 self
.seltype
= ectx
.eth_sel_req(self
.typ
.val
, self
.sel
)
3940 ectx
.eth_dep_add(ident
, self
.seltype
)
3942 def eth_ftype(self
, ectx
):
3943 (ftype
, display
) = ('FT_NONE', 'BASE_NONE')
3944 if self
.sel_of_typeref() and not ectx
.type[self
.seltype
]['import']:
3945 (ftype
, display
) = ectx
.type[self
.typ
.val
]['val'].eth_ftype_sel(self
.sel
, ectx
)
3946 return (ftype
, display
)
3948 def GetTTag(self
, ectx
):
3949 #print "GetTTag(%s)\n" % self.seltype;
3950 if (ectx
.type[self
.seltype
]['import']):
3951 if 'ttag' not in ectx
.type[self
.seltype
]:
3952 if not ectx
.conform
.check_item('IMPORT_TAG', self
.seltype
):
3953 msg
= 'Missing tag information for imported type %s from %s (%s)' % (self
.seltype
, ectx
.type[self
.seltype
]['import'], ectx
.type[self
.seltype
]['proto'])
3954 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3955 ectx
.type[self
.seltype
]['ttag'] = ectx
.conform
.use_item('IMPORT_TAG', self
.seltype
, val_dflt
=('-1 /*imported*/', '-1 /*imported*/'))
3956 return ectx
.type[self
.seltype
]['ttag']
3958 return ectx
.type[self
.typ
.val
]['val'].GetTTagSel(self
.sel
, ectx
)
3960 def eth_type_default_pars(self
, ectx
, tname
):
3961 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
3962 if self
.sel_of_typeref():
3963 t
= ectx
.type[self
.seltype
]['ethname']
3964 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
3965 pars
['TYPE_REF_TNAME'] = t
3966 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3969 def eth_type_default_body(self
, ectx
, tname
):
3970 if not self
.sel_of_typeref():
3971 body
= '#error Can not decode %s' % (tname
)
3973 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3974 par
=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3975 elif (ectx
.Per() or ectx
.Oer()):
3976 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3977 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3979 body
= '#error Can not decode %s' % (tname
)
3982 #--- TaggedType -----------------------------------------------------------------
3983 class TaggedType (Type
):
3984 def eth_tname(self
):
3986 for i
in range(self
.tstrip
, len(self
.val
.tags
)):
3987 tn
+= self
.val
.tags
[i
].eth_tname()
3989 tn
+= self
.val
.eth_tname()
3992 def eth_set_val_name(self
, ident
, val_name
, ectx
):
3993 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3994 self
.val_name
= val_name
3995 ectx
.eth_dep_add(ident
, self
.val_name
)
3997 def eth_reg_sub(self
, ident
, ectx
):
3998 self
.val_name
= ident
+ '/' + UNTAG_TYPE_NAME
3999 self
.val
.eth_reg(self
.val_name
, ectx
, tstrip
=self
.tstrip
+1, tagflag
=True, parent
=ident
)
4001 def GetTTag(self
, ectx
):
4002 #print "GetTTag(%s)\n" % self.seltype;
4003 return self
.GetTag(ectx
)
4005 def eth_ftype(self
, ectx
):
4006 return self
.val
.eth_ftype(ectx
)
4008 def eth_type_default_pars(self
, ectx
, tname
):
4009 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4010 t
= ectx
.type[self
.val_name
]['ethname']
4011 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
4012 pars
['TYPE_REF_TNAME'] = t
4013 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4014 (pars
['TAG_CLS'], pars
['TAG_TAG']) = self
.GetTag(ectx
)
4015 if self
.HasImplicitTag(ectx
):
4016 pars
['TAG_IMPL'] = 'true'
4018 pars
['TAG_IMPL'] = 'false'
4021 def eth_type_default_body(self
, ectx
, tname
):
4023 body
= ectx
.eth_fn_call('dissect_%(ER)s_tagged_type', ret
='offset',
4024 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4025 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
4027 body
= '#error Can not decode tagged_type %s' % (tname
)
4030 #--- SqType -----------------------------------------------------------
4031 class SqType (Type
):
4032 def out_item(self
, f
, val
, optional
, ext
, ectx
):
4033 if (val
.eth_omit_field()):
4034 t
= ectx
.type[val
.ident
]['ethname']
4035 fullname
= ectx
.dummy_eag_field
4037 ef
= ectx
.field
[f
]['ethname']
4038 t
= ectx
.eth_hf
[ef
]['ethtype']
4039 fullname
= ectx
.eth_hf
[ef
]['fullname']
4041 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
4042 #print val.str_depth(1)
4045 opt
= 'BER_FLAGS_OPTIONAL'
4046 if (not val
.HasOwnTag()):
4047 if (opt
): opt
+= '|'
4048 opt
+= 'BER_FLAGS_NOOWNTAG'
4049 elif (val
.HasImplicitTag(ectx
)):
4050 if (opt
): opt
+= '|'
4051 opt
+= 'BER_FLAGS_IMPLTAG'
4052 if (val
.IndetermTag(ectx
)):
4053 if (opt
): opt
+= '|'
4054 opt
+= 'BER_FLAGS_NOTCHKTAG'
4055 if (not opt
): opt
= '0'
4058 opt
= 'ASN1_OPTIONAL'
4060 opt
= 'ASN1_NOT_OPTIONAL'
4062 (tc
, tn
) = val
.GetTag(ectx
)
4063 out
= ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4064 % ('&'+fullname
, tc
, tn
, opt
, ectx
.eth_type
[t
]['proto'], t
)
4065 elif (ectx
.Per() or ectx
.Oer()):
4066 out
= ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
4067 % ('&'+fullname
, ext
, opt
, ectx
.eth_type
[t
]['proto'], t
)
4072 #--- SeqType -----------------------------------------------------------
4073 class SeqType (SqType
):
4075 def all_components(self
):
4076 lst
= self
.elt_list
[:]
4077 if hasattr(self
, 'ext_list'):
4078 lst
.extend(self
.ext_list
)
4079 if hasattr(self
, 'elt_list2'):
4080 lst
.extend(self
.elt_list2
)
4083 def need_components(self
):
4084 lst
= self
.all_components()
4086 if e
.type == 'components_of':
4090 def expand_components(self
, ectx
):
4091 while self
.need_components():
4092 for i
in range(len(self
.elt_list
)):
4093 if self
.elt_list
[i
].type == 'components_of':
4094 comp
= self
.elt_list
[i
].typ
.get_components(ectx
)
4095 self
.elt_list
[i
:i
+1] = comp
4097 if hasattr(self
, 'ext_list'):
4098 for i
in range(len(self
.ext_list
)):
4099 if self
.ext_list
[i
].type == 'components_of':
4100 comp
= self
.ext_list
[i
].typ
.get_components(ectx
)
4101 self
.ext_list
[i
:i
+1] = comp
4103 if hasattr(self
, 'elt_list2'):
4104 for i
in range(len(self
.elt_list2
)):
4105 if self
.elt_list2
[i
].type == 'components_of':
4106 comp
= self
.elt_list2
[i
].typ
.get_components(ectx
)
4107 self
.elt_list2
[i
:i
+1] = comp
4110 def get_components(self
, ectx
):
4111 lst
= self
.elt_list
[:]
4112 if hasattr(self
, 'elt_list2'):
4113 lst
.extend(self
.elt_list2
)
4116 def eth_reg_sub(self
, ident
, ectx
, components_available
=False):
4117 # check if autotag is required
4119 if (ectx
.NeedTags() and (ectx
.tag_def
== 'AUTOMATIC')):
4121 lst
= self
.all_components()
4122 for e
in (self
.elt_list
):
4123 if e
.val
.HasOwnTag(): autotag
= False
4125 # expand COMPONENTS OF
4126 if self
.need_components():
4127 if components_available
:
4128 self
.expand_components(ectx
)
4130 ectx
.eth_comp_req(ident
)
4132 # extension addition groups
4133 if hasattr(self
, 'ext_list'):
4134 if (ectx
.Per() or ectx
.Oer()): # add names
4136 for e
in (self
.ext_list
):
4137 if isinstance(e
.val
, ExtensionAdditionGroup
):
4138 e
.val
.parent_ident
= ident
4139 e
.val
.parent_tname
= ectx
.type[ident
]['tname']
4141 e
.val
.SetName("eag_v%s" % (e
.val
.ver
))
4143 e
.val
.SetName("eag_%d" % (eag_num
))
4147 for e
in (self
.ext_list
):
4148 if isinstance(e
.val
, ExtensionAdditionGroup
):
4149 new_ext_list
.extend(e
.val
.elt_list
)
4151 new_ext_list
.append(e
)
4152 self
.ext_list
= new_ext_list
4156 for e
in (self
.elt_list
):
4157 e
.val
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4159 if autotag
and hasattr(self
, 'elt_list2'):
4160 for e
in (self
.elt_list2
):
4161 e
.val
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4163 if autotag
and hasattr(self
, 'ext_list'):
4164 for e
in (self
.ext_list
):
4165 e
.val
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4167 # register components
4168 for e
in (self
.elt_list
):
4169 e
.val
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4170 if hasattr(self
, 'ext_list'):
4171 for e
in (self
.ext_list
):
4172 e
.val
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4173 if hasattr(self
, 'elt_list2'):
4174 for e
in (self
.elt_list2
):
4175 e
.val
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4177 def eth_type_default_table(self
, ectx
, tname
):
4178 #print ("eth_type_default_table(tname='%s')" % (tname))
4179 fname
= ectx
.eth_type
[tname
]['ref'][0]
4180 table
= "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
4181 if hasattr(self
, 'ext_list'):
4182 ext
= 'ASN1_EXTENSION_ROOT'
4184 ext
= 'ASN1_NO_EXTENSIONS'
4185 empty_ext_flag
= '0'
4186 if (len(self
.elt_list
)==0) and hasattr(self
, 'ext_list') and (len(self
.ext_list
)==0) and (not hasattr(self
, 'elt_list2') or (len(self
.elt_list2
)==0)):
4187 empty_ext_flag
= ext
4188 for e
in (self
.elt_list
):
4189 f
= fname
+ '/' + e
.val
.name
4190 table
+= self
.out_item(f
, e
.val
, e
.optional
, ext
, ectx
)
4191 if hasattr(self
, 'ext_list'):
4192 for e
in (self
.ext_list
):
4193 f
= fname
+ '/' + e
.val
.name
4194 table
+= self
.out_item(f
, e
.val
, e
.optional
, 'ASN1_NOT_EXTENSION_ROOT', ectx
)
4195 if hasattr(self
, 'elt_list2'):
4196 for e
in (self
.elt_list2
):
4197 f
= fname
+ '/' + e
.val
.name
4198 table
+= self
.out_item(f
, e
.val
, e
.optional
, ext
, ectx
)
4200 table
+= " { NULL, 0, 0, 0, NULL }\n};\n"
4202 table
+= " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag
)
4205 #--- SeqOfType -----------------------------------------------------------
4206 class SeqOfType (SqType
):
4207 def eth_type_default_table(self
, ectx
, tname
):
4208 #print "eth_type_default_table(tname='%s')" % (tname)
4209 fname
= ectx
.eth_type
[tname
]['ref'][0]
4210 if self
.val
.IsNamed ():
4211 f
= fname
+ '/' + self
.val
.name
4213 f
= fname
+ '/' + ITEM_FIELD_NAME
4214 table
= "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
4215 table
+= self
.out_item(f
, self
.val
, False, 'ASN1_NO_EXTENSIONS', ectx
)
4219 #--- SequenceOfType -----------------------------------------------------------
4220 class SequenceOfType (SeqOfType
):
4221 def to_python (self
, ctx
):
4222 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4223 # or '' + (1,) for optional
4225 if self
.size_constr
is not None:
4226 print("#Ignoring size constraint:", self
.size_constr
.subtype
)
4227 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx
.spaces (),
4228 self
.val
.to_python (ctx
),
4231 def eth_reg_sub(self
, ident
, ectx
):
4233 if not self
.val
.IsNamed ():
4234 itmnm
+= '/' + ITEM_FIELD_NAME
4235 self
.val
.eth_reg(itmnm
, ectx
, tstrip
=1, idx
='[##]', parent
=ident
)
4237 def eth_tname(self
):
4238 if self
.val
.type != 'Type_Ref':
4239 return '#' + self
.type + '_' + str(id(self
))
4240 if not self
.HasConstraint():
4241 return "SEQUENCE_OF_" + self
.val
.eth_tname()
4242 elif self
.constr
.IsSize():
4243 return 'SEQUENCE_' + self
.constr
.eth_constrname() + '_OF_' + self
.val
.eth_tname()
4245 return '#' + self
.type + '_' + str(id(self
))
4247 def eth_ftype(self
, ectx
):
4248 return ('FT_UINT32', 'BASE_DEC')
4250 def eth_need_tree(self
):
4253 def GetTTag(self
, ectx
):
4254 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4256 def eth_type_default_pars(self
, ectx
, tname
):
4257 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4258 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
4259 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
4262 def eth_type_default_body(self
, ectx
, tname
):
4264 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
4265 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret
='offset',
4266 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4267 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4269 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence_of', ret
='offset',
4270 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4271 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4272 elif ((ectx
.Per() or ectx
.Oer()) and not self
.HasConstraint()):
4273 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence_of', ret
='offset',
4274 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4275 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4276 elif ((ectx
.Per() or ectx
.Oer()) and self
.constr
.type == 'Size'):
4277 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret
='offset',
4278 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4279 ('%(ETT_INDEX)s', '%(TABLE)s',),
4280 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
4282 body
= '#error Can not decode SequenceOfType %s' % (tname
)
4286 #--- SetOfType ----------------------------------------------------------------
4287 class SetOfType (SeqOfType
):
4288 def eth_reg_sub(self
, ident
, ectx
):
4290 if not self
.val
.IsNamed ():
4291 itmnm
+= '/' + ITEM_FIELD_NAME
4292 self
.val
.eth_reg(itmnm
, ectx
, tstrip
=1, idx
='(##)', parent
=ident
)
4294 def eth_tname(self
):
4295 if self
.val
.type != 'Type_Ref':
4296 return '#' + self
.type + '_' + str(id(self
))
4297 if not self
.HasConstraint():
4298 return "SET_OF_" + self
.val
.eth_tname()
4299 elif self
.constr
.IsSize():
4300 return 'SET_' + self
.constr
.eth_constrname() + '_OF_' + self
.val
.eth_tname()
4302 return '#' + self
.type + '_' + str(id(self
))
4304 def eth_ftype(self
, ectx
):
4305 return ('FT_UINT32', 'BASE_DEC')
4307 def eth_need_tree(self
):
4310 def GetTTag(self
, ectx
):
4311 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4313 def eth_type_default_pars(self
, ectx
, tname
):
4314 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4315 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
4316 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
4319 def eth_type_default_body(self
, ectx
, tname
):
4321 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
4322 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret
='offset',
4323 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4324 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4326 body
= ectx
.eth_fn_call('dissect_%(ER)s_set_of', ret
='offset',
4327 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4328 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4329 elif (ectx
.Per() and not self
.HasConstraint()):
4330 body
= ectx
.eth_fn_call('dissect_%(ER)s_set_of', ret
='offset',
4331 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4332 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4333 elif (ectx
.Per() and self
.constr
.type == 'Size'):
4334 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret
='offset',
4335 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4336 ('%(ETT_INDEX)s', '%(TABLE)s',),
4337 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),))
4339 body
= '#error Can not decode SetOfType %s' % (tname
)
4342 def mk_tag_str (ctx
, cls
, typ
, num
):
4344 # XXX should do conversion to int earlier!
4347 if typ
== 'DEFAULT':
4349 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ
, val
, cls
) # XXX still ned
4351 #--- SequenceType -------------------------------------------------------------
4352 class SequenceType (SeqType
):
4353 def to_python (self
, ctx
):
4354 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4355 # or '' + (1,) for optional
4356 # XXX should also collect names for SEQUENCE inside SEQUENCE or
4357 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
4358 # from? for others, element or arm name would be fine)
4359 seq_name
= getattr (self
, 'sequence_name', None)
4360 if seq_name
is None:
4363 seq_name
= "'" + seq_name
+ "'"
4364 if 'ext_list' in self
.__dict
__:
4365 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx
.spaces (),
4366 self
.elts_to_py (self
.elt_list
, ctx
),
4367 self
.elts_to_py (self
.ext_list
, ctx
), seq_name
)
4369 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx
.spaces (),
4370 self
.elts_to_py (self
.elt_list
, ctx
), seq_name
)
4371 def elts_to_py (self
, list, ctx
):
4372 # we have elt_type, val= named_type, maybe default=, optional=
4373 # named_type node: either ident = or typ =
4374 # need to dismember these in order to generate Python output syntax.
4377 assert (e
.type == 'elt_type')
4379 optflag
= e
.optional
4380 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
4381 assert (nt
.type == 'named_type')
4384 if hasattr (nt
.typ
, 'type') and nt
.typ
.type == 'tag': # ugh
4385 tagstr
= mk_tag_str (ctx
,nt
.typ
.tag
.cls
,
4386 nt
.typ
.tag
.tag_typ
,nt
.typ
.tag
.num
)
4390 return "('%s',%s,%s,%d)" % (identstr
, tagstr
,
4391 nt
.typ
.to_python (ctx
), optflag
)
4392 indentstr
= ",\n" + ctx
.spaces ()
4393 rv
= indentstr
.join ([elt_to_py (e
) for e
in list])
4397 def eth_need_tree(self
):
4400 def GetTTag(self
, ectx
):
4401 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4403 def eth_type_default_pars(self
, ectx
, tname
):
4404 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4405 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4408 def eth_type_default_body(self
, ectx
, tname
):
4410 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence', ret
='offset',
4411 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4412 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4413 elif (ectx
.Per() or ectx
.Oer()):
4414 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence', ret
='offset',
4415 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4416 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4418 body
= '#error Can not decode SequenceType %s' % (tname
)
4421 #--- ExtensionAdditionGroup ---------------------------------------------------
4422 class ExtensionAdditionGroup (SeqType
):
4423 def __init__(self
,*args
, **kw
) :
4424 self
.parent_ident
= None
4425 self
.parent_tname
= None
4426 SeqType
.__init
__ (self
,*args
, **kw
)
4428 def eth_omit_field(self
):
4431 def eth_tname(self
):
4432 if (self
.parent_tname
and self
.IsNamed()):
4433 return self
.parent_tname
+ "_" + self
.name
4435 return SeqType
.eth_tname(self
)
4437 def eth_reg_sub(self
, ident
, ectx
):
4438 ectx
.eth_dummy_eag_field_required()
4439 ectx
.eth_dep_add(self
.parent_ident
, ident
)
4440 SeqType
.eth_reg_sub(self
, ident
, ectx
)
4442 def eth_type_default_pars(self
, ectx
, tname
):
4443 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4444 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4447 def eth_type_default_body(self
, ectx
, tname
):
4449 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence_eag', ret
='offset',
4450 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),))
4452 body
= '#error Can not decode ExtensionAdditionGroup %s' % (tname
)
4456 #--- SetType ------------------------------------------------------------------
4457 class SetType (SeqType
):
4459 def eth_need_tree(self
):
4462 def GetTTag(self
, ectx
):
4463 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4465 def eth_type_default_pars(self
, ectx
, tname
):
4466 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4467 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4470 def eth_type_default_body(self
, ectx
, tname
):
4472 body
= ectx
.eth_fn_call('dissect_%(ER)s_set', ret
='offset',
4473 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4474 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4476 body
= ectx
.eth_fn_call('dissect_%(ER)s_set', ret
='offset',
4477 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4478 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4480 body
= '#error Can not decode SetType %s' % (tname
)
4483 #--- ChoiceType ---------------------------------------------------------------
4484 class ChoiceType (Type
):
4485 def to_python (self
, ctx
):
4486 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4487 # or '' + (1,) for optional
4488 if 'ext_list' in self
.__dict
__:
4489 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx
.spaces (),
4490 self
.elts_to_py (self
.elt_list
, ctx
),
4491 self
.elts_to_py (self
.ext_list
, ctx
))
4493 return "%sasn1.CHOICE ([%s])" % (ctx
.spaces (), self
.elts_to_py (self
.elt_list
, ctx
))
4494 def elts_to_py (self
, list, ctx
):
4497 assert (nt
.type == 'named_type')
4499 if hasattr (nt
, 'ident'):
4502 if hasattr (nt
.typ
, 'val'):
4503 identstr
= nt
.typ
.val
# XXX, making up name
4504 elif hasattr (nt
.typ
, 'name'):
4505 identstr
= nt
.typ
.name
4507 identstr
= ctx
.make_new_name ()
4509 if hasattr (nt
.typ
, 'type') and nt
.typ
.type == 'tag': # ugh
4510 tagstr
= mk_tag_str (ctx
,nt
.typ
.tag
.cls
,
4511 nt
.typ
.tag
.tag_typ
,nt
.typ
.tag
.num
)
4515 return "('%s',%s,%s)" % (identstr
, tagstr
,
4516 nt
.typ
.to_python (ctx
))
4517 indentstr
= ",\n" + ctx
.spaces ()
4518 rv
= indentstr
.join ([elt_to_py (e
) for e
in list])
4522 def eth_reg_sub(self
, ident
, ectx
):
4523 #print "eth_reg_sub(ident='%s')" % (ident)
4524 # check if autotag is required
4526 if (ectx
.NeedTags() and (ectx
.tag_def
== 'AUTOMATIC')):
4528 for e
in (self
.elt_list
):
4529 if e
.HasOwnTag(): autotag
= False; break
4530 if autotag
and hasattr(self
, 'ext_list'):
4531 for e
in (self
.ext_list
):
4532 if e
.HasOwnTag(): autotag
= False; break
4536 for e
in (self
.elt_list
):
4537 e
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4539 if autotag
and hasattr(self
, 'ext_list'):
4540 for e
in (self
.ext_list
):
4541 e
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4543 for e
in (self
.elt_list
):
4544 e
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4545 if ectx
.conform
.check_item('EXPORTS', ident
+ '.' + e
.name
):
4546 ectx
.eth_sel_req(ident
, e
.name
)
4547 if hasattr(self
, 'ext_list'):
4548 for e
in (self
.ext_list
):
4549 e
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4550 if ectx
.conform
.check_item('EXPORTS', ident
+ '.' + e
.name
):
4551 ectx
.eth_sel_req(ident
, e
.name
)
4553 def sel_item(self
, ident
, sel
, ectx
):
4554 lst
= self
.elt_list
[:]
4555 if hasattr(self
, 'ext_list'):
4556 lst
.extend(self
.ext_list
)
4558 for e
in (self
.elt_list
):
4559 if e
.IsNamed() and (e
.name
== sel
):
4563 print("#CHOICE %s does not contain item %s" % (ident
, sel
))
4566 def sel_req(self
, ident
, sel
, ectx
):
4567 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4568 ee
= self
.sel_item(ident
, sel
, ectx
)
4570 ee
.eth_reg(ident
, ectx
, tstrip
=0, selflag
=True)
4572 def eth_ftype(self
, ectx
):
4573 return ('FT_UINT32', 'BASE_DEC')
4575 def eth_ftype_sel(self
, sel
, ectx
):
4576 ee
= self
.sel_item('', sel
, ectx
)
4578 return ee
.eth_ftype(ectx
)
4580 return ('FT_NONE', 'BASE_NONE')
4582 def eth_strings(self
):
4585 def eth_need_tree(self
):
4588 def eth_has_vals(self
):
4591 def GetTTag(self
, ectx
):
4593 cls
= 'BER_CLASS_ANY/*choice*/'
4594 #if hasattr(self, 'ext_list'):
4595 # lst.extend(self.ext_list)
4597 # cls = lst[0].GetTag(ectx)[0]
4599 # if (e.GetTag(ectx)[0] != cls):
4600 # cls = '-1/*choice*/'
4601 return (cls
, '-1/*choice*/')
4603 def GetTTagSel(self
, sel
, ectx
):
4604 ee
= self
.sel_item('', sel
, ectx
)
4606 return ee
.GetTag(ectx
)
4608 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4610 def IndetermTag(self
, ectx
):
4611 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4612 return not self
.HasOwnTag()
4614 def detect_tagval(self
, ectx
):
4616 lst
= self
.elt_list
[:]
4617 if hasattr(self
, 'ext_list'):
4618 lst
.extend(self
.ext_list
)
4619 if (len(lst
) > 0) and (not (ectx
.Per() or ectx
.Oer()) or lst
[0].HasOwnTag()):
4620 t
= lst
[0].GetTag(ectx
)[0]
4625 if (t
== 'BER_CLASS_UNI'):
4628 if not (ectx
.Per() or ectx
.Oer()) or e
.HasOwnTag():
4629 tt
= e
.GetTag(ectx
)[0]
4637 def get_vals(self
, ectx
):
4638 tagval
= self
.detect_tagval(ectx
)
4641 for e
in (self
.elt_list
):
4642 if (tagval
): val
= e
.GetTag(ectx
)[1]
4643 else: val
= str(cnt
)
4644 vals
.append((val
, e
.name
))
4646 if hasattr(self
, 'ext_list'):
4647 for e
in (self
.ext_list
):
4648 if (tagval
): val
= e
.GetTag(ectx
)[1]
4649 else: val
= str(cnt
)
4650 vals
.append((val
, e
.name
))
4654 def eth_type_vals(self
, tname
, ectx
):
4656 vals
= self
.get_vals(ectx
)
4657 out
+= ectx
.eth_vals(tname
, vals
)
4660 def reg_enum_vals(self
, tname
, ectx
):
4661 vals
= self
.get_vals(ectx
)
4662 for (val
, id) in vals
:
4663 ectx
.eth_reg_value(id, self
, val
, ethname
=ectx
.eth_enum_item(tname
, id))
4665 def eth_type_enum(self
, tname
, ectx
):
4667 vals
= self
.get_vals(ectx
)
4668 out
+= ectx
.eth_enum(tname
, vals
)
4671 def eth_type_default_pars(self
, ectx
, tname
):
4672 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4673 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4676 def eth_type_default_table(self
, ectx
, tname
):
4677 def out_item(val
, e
, ext
, ectx
):
4678 has_enum
= ectx
.eth_type
[tname
]['enum'] & EF_ENUM
4680 vval
= ectx
.eth_enum_item(tname
, e
.name
)
4683 f
= fname
+ '/' + e
.name
4684 ef
= ectx
.field
[f
]['ethname']
4685 t
= ectx
.eth_hf
[ef
]['ethtype']
4688 if (not e
.HasOwnTag()):
4689 opt
= 'BER_FLAGS_NOOWNTAG'
4690 elif (e
.HasImplicitTag(ectx
)):
4691 if (opt
): opt
+= '|'
4692 opt
+= 'BER_FLAGS_IMPLTAG'
4693 if (not opt
): opt
= '0'
4695 (tc
, tn
) = e
.GetTag(ectx
)
4696 out
= ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4697 % (vval
, '&'+ectx
.eth_hf
[ef
]['fullname'], tc
, tn
, opt
, ectx
.eth_type
[t
]['proto'], t
)
4698 elif (ectx
.Per() or ectx
.Oer()):
4699 out
= ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4700 % (vval
, '&'+ectx
.eth_hf
[ef
]['fullname'], ext
, ectx
.eth_type
[t
]['proto'], t
)
4705 #print "eth_type_default_table(tname='%s')" % (tname)
4706 fname
= ectx
.eth_type
[tname
]['ref'][0]
4707 tagval
= self
.detect_tagval(ectx
)
4708 table
= "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4710 if hasattr(self
, 'ext_list'):
4711 ext
= 'ASN1_EXTENSION_ROOT'
4713 ext
= 'ASN1_NO_EXTENSIONS'
4714 empty_ext_flag
= '0'
4715 if (len(self
.elt_list
)==0) and hasattr(self
, 'ext_list') and (len(self
.ext_list
)==0):
4716 empty_ext_flag
= ext
4717 for e
in (self
.elt_list
):
4718 if (tagval
): val
= e
.GetTag(ectx
)[1]
4719 else: val
= str(cnt
)
4720 table
+= out_item(val
, e
, ext
, ectx
)
4722 if hasattr(self
, 'ext_list'):
4723 for e
in (self
.ext_list
):
4724 if (tagval
): val
= e
.GetTag(ectx
)[1]
4725 else: val
= str(cnt
)
4726 table
+= out_item(val
, e
, 'ASN1_NOT_EXTENSION_ROOT', ectx
)
4729 table
+= " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4731 table
+= " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag
)
4734 def eth_type_default_body(self
, ectx
, tname
):
4736 body
= ectx
.eth_fn_call('dissect_%(ER)s_choice', ret
='offset',
4737 par
=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4738 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4740 elif (ectx
.Per() or ectx
.Oer()):
4741 body
= ectx
.eth_fn_call('dissect_%(ER)s_choice', ret
='offset',
4742 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4743 ('%(ETT_INDEX)s', '%(TABLE)s',),
4746 body
= '#error Can not decode ChoiceType %s' % (tname
)
4749 #--- ChoiceValue ----------------------------------------------------
4750 class ChoiceValue (Value
):
4751 def to_str(self
, ectx
):
4752 return self
.val
.to_str(ectx
)
4754 def fld_obj_eq(self
, other
):
4755 return isinstance(other
, ChoiceValue
) and (self
.choice
== other
.choice
) and (str(self
.val
.val
) == str(other
.val
.val
))
4757 #--- EnumeratedType -----------------------------------------------------------
4758 class EnumeratedType (Type
):
4759 def to_python (self
, ctx
):
4760 def strify_one (named_num
):
4761 return "%s=%s" % (named_num
.ident
, named_num
.val
)
4762 return "asn1.ENUM(%s)" % ",".join (map (strify_one
, self
.val
))
4764 def eth_ftype(self
, ectx
):
4765 return ('FT_UINT32', 'BASE_DEC')
4767 def eth_strings(self
):
4770 def eth_has_vals(self
):
4773 def GetTTag(self
, ectx
):
4774 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4776 def get_vals_etc(self
, ectx
):
4784 for e
in (self
.val
):
4785 if e
.type == 'NamedNumber':
4786 used
[int(e
.val
)] = True
4787 for e
in (self
.val
):
4788 if e
.type == 'NamedNumber':
4791 while lastv
in used
:
4795 vals
.append((val
, e
.ident
))
4796 map_table
.append(val
)
4800 if self
.ext
is not None:
4801 for e
in (self
.ext
):
4802 if e
.type == 'NamedNumber':
4803 used
[int(e
.val
)] = True
4804 for e
in (self
.ext
):
4805 if e
.type == 'NamedNumber':
4808 while lastv
in used
:
4812 vals
.append((val
, e
.ident
))
4813 map_table
.append(val
)
4818 for i
in range(len(map_table
)):
4819 need_map
= need_map
or (map_table
[i
] != i
)
4822 return (vals
, root_num
, ext_num
, map_table
)
4824 def eth_type_vals(self
, tname
, ectx
):
4826 vals
= self
.get_vals_etc(ectx
)[0]
4827 out
+= ectx
.eth_vals(tname
, vals
)
4830 def reg_enum_vals(self
, tname
, ectx
):
4831 vals
= self
.get_vals_etc(ectx
)[0]
4832 for (val
, id) in vals
:
4833 ectx
.eth_reg_value(id, self
, val
, ethname
=ectx
.eth_enum_item(tname
, id))
4835 def eth_type_enum(self
, tname
, ectx
):
4837 vals
= self
.get_vals_etc(ectx
)[0]
4838 out
+= ectx
.eth_enum(tname
, vals
)
4841 def eth_type_default_pars(self
, ectx
, tname
):
4842 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4843 (root_num
, ext_num
, map_table
) = self
.get_vals_etc(ectx
)[1:]
4844 if self
.ext
is not None:
4848 pars
['ROOT_NUM'] = str(root_num
)
4850 pars
['EXT_NUM'] = str(ext_num
)
4852 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4854 pars
['TABLE'] = 'NULL'
4857 def eth_type_default_table(self
, ectx
, tname
):
4858 if (not ectx
.Per() and not ectx
.Oer()): return ''
4859 map_table
= self
.get_vals_etc(ectx
)[3]
4860 if map_table
is None: return ''
4861 table
= "static uint32_t %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4862 table
+= ", ".join([str(v
) for v
in map_table
])
4866 def eth_type_default_body(self
, ectx
, tname
):
4868 if (ectx
.constraints_check
and self
.HasValueConstraint()):
4869 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer', ret
='offset',
4870 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4871 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4873 body
= ectx
.eth_fn_call('dissect_%(ER)s_integer', ret
='offset',
4874 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4876 elif (ectx
.Per() or ectx
.Oer()):
4877 body
= ectx
.eth_fn_call('dissect_%(ER)s_enumerated', ret
='offset',
4878 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4879 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4881 body
= '#error Can not decode EnumeratedType %s' % (tname
)
4884 #--- EmbeddedPDVType -----------------------------------------------------------
4885 class EmbeddedPDVType (Type
):
4886 def eth_tname(self
):
4887 return 'EMBEDDED_PDV'
4889 def eth_ftype(self
, ectx
):
4890 return ('FT_NONE', 'BASE_NONE')
4892 def GetTTag(self
, ectx
):
4893 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4895 def eth_type_default_pars(self
, ectx
, tname
):
4896 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4897 if ectx
.default_embedded_pdv_cb
:
4898 pars
['TYPE_REF_FN'] = ectx
.default_embedded_pdv_cb
4900 pars
['TYPE_REF_FN'] = 'NULL'
4903 def eth_type_default_body(self
, ectx
, tname
):
4905 body
= ectx
.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret
='offset',
4906 par
=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4908 body
= ectx
.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret
='offset',
4909 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4911 body
= '#error Can not decode EmbeddedPDVType %s' % (tname
)
4914 #--- ExternalType -----------------------------------------------------------
4915 class ExternalType (Type
):
4916 def eth_tname(self
):
4919 def eth_ftype(self
, ectx
):
4920 return ('FT_NONE', 'BASE_NONE')
4922 def GetTTag(self
, ectx
):
4923 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4925 def eth_type_default_pars(self
, ectx
, tname
):
4926 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4927 if ectx
.default_external_type_cb
:
4928 pars
['TYPE_REF_FN'] = ectx
.default_external_type_cb
4930 pars
['TYPE_REF_FN'] = 'NULL'
4933 def eth_type_default_body(self
, ectx
, tname
):
4935 body
= ectx
.eth_fn_call('dissect_%(ER)s_external_type', ret
='offset',
4936 par
=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4938 body
= ectx
.eth_fn_call('dissect_%(ER)s_external_type', ret
='offset',
4939 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4941 body
= '#error Can not decode ExternalType %s' % (tname
)
4944 #--- OpenType -----------------------------------------------------------
4945 class OpenType (Type
):
4946 def to_python (self
, ctx
):
4949 def single_type(self
):
4950 if (self
.HasConstraint() and
4951 self
.constr
.type == 'Type' and
4952 self
.constr
.subtype
.type == 'Type_Ref'):
4953 return self
.constr
.subtype
.val
4956 def eth_reg_sub(self
, ident
, ectx
):
4957 t
= self
.single_type()
4959 ectx
.eth_dep_add(ident
, t
)
4961 def eth_tname(self
):
4962 t
= self
.single_type()
4964 return 'OpenType_' + t
4966 return Type
.eth_tname(self
)
4968 def eth_ftype(self
, ectx
):
4969 return ('FT_NONE', 'BASE_NONE')
4971 def GetTTag(self
, ectx
):
4972 return ('BER_CLASS_ANY', '0')
4974 def eth_type_default_pars(self
, ectx
, tname
):
4975 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4976 pars
['FN_VARIANT'] = ectx
.default_opentype_variant
4977 t
= self
.single_type()
4979 t
= ectx
.type[t
]['ethname']
4980 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
4981 pars
['TYPE_REF_TNAME'] = t
4982 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4984 pars
['TYPE_REF_FN'] = 'NULL'
4987 def eth_type_default_body(self
, ectx
, tname
):
4988 if (ectx
.Per() or ectx
.Oer()):
4989 body
= ectx
.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret
='offset',
4990 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4992 body
= '#error Can not decode OpenType %s' % (tname
)
4995 #--- InstanceOfType -----------------------------------------------------------
4996 class InstanceOfType (Type
):
4997 def eth_tname(self
):
4998 return 'INSTANCE_OF'
5000 def eth_ftype(self
, ectx
):
5001 return ('FT_NONE', 'BASE_NONE')
5003 def GetTTag(self
, ectx
):
5004 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
5006 def eth_type_default_pars(self
, ectx
, tname
):
5007 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5008 if ectx
.default_external_type_cb
:
5009 pars
['TYPE_REF_FN'] = ectx
.default_external_type_cb
5011 pars
['TYPE_REF_FN'] = 'NULL'
5014 def eth_type_default_body(self
, ectx
, tname
):
5016 body
= ectx
.eth_fn_call('dissect_%(ER)s_external_type', ret
='offset',
5017 par
=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
5019 body
= '#error Can not decode %s' % (tname
)
5022 #--- AnyType -----------------------------------------------------------
5023 class AnyType (Type
):
5024 def to_python (self
, ctx
):
5027 def eth_ftype(self
, ectx
):
5028 return ('FT_NONE', 'BASE_NONE')
5030 def GetTTag(self
, ectx
):
5031 return ('BER_CLASS_ANY', '0')
5033 def eth_type_default_body(self
, ectx
, tname
):
5034 body
= '#error Can not decode %s' % (tname
)
5037 class Literal (Node
):
5038 def to_python (self
, ctx
):
5041 #--- NullType -----------------------------------------------------------------
5042 class NullType (Type
):
5043 def to_python (self
, ctx
):
5046 def eth_tname(self
):
5049 def GetTTag(self
, ectx
):
5050 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
5052 def eth_type_default_body(self
, ectx
, tname
):
5054 body
= ectx
.eth_fn_call('dissect_%(ER)s_null', ret
='offset',
5055 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5056 elif (ectx
.Per() or ectx
.Oer()):
5057 body
= ectx
.eth_fn_call('dissect_%(ER)s_null', ret
='offset',
5058 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5060 body
= '#error Can not decode %s' % (tname
)
5063 #--- NullValue ----------------------------------------------------
5064 class NullValue (Value
):
5065 def to_str(self
, ectx
):
5068 #--- RealType -----------------------------------------------------------------
5069 class RealType (Type
):
5070 def to_python (self
, ctx
):
5073 def eth_tname(self
):
5076 def GetTTag(self
, ectx
):
5077 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
5079 def eth_ftype(self
, ectx
):
5080 return ('FT_DOUBLE', 'BASE_NONE')
5082 def eth_type_default_body(self
, ectx
, tname
):
5084 body
= ectx
.eth_fn_call('dissect_%(ER)s_real', ret
='offset',
5085 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5088 body
= ectx
.eth_fn_call('dissect_%(ER)s_real', ret
='offset',
5089 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5091 body
= '#error Can not decode %s' % (tname
)
5094 #--- BooleanType --------------------------------------------------------------
5095 class BooleanType (Type
):
5096 def to_python (self
, ctx
):
5097 return 'asn1.BOOLEAN'
5099 def eth_tname(self
):
5102 def GetTTag(self
, ectx
):
5103 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
5105 def eth_ftype(self
, ectx
):
5106 return ('FT_BOOLEAN', 'BASE_NONE')
5108 def eth_type_default_body(self
, ectx
, tname
):
5110 body
= ectx
.eth_fn_call('dissect_%(ER)s_boolean', ret
='offset',
5111 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5113 body
= ectx
.eth_fn_call('dissect_%(ER)s_boolean', ret
='offset',
5114 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5116 body
= ectx
.eth_fn_call('dissect_%(ER)s_boolean', ret
='offset',
5117 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5119 body
= '#error Can not decode %s' % (tname
)
5122 #--- OctetStringType ----------------------------------------------------------
5123 class OctetStringType (Type
):
5124 def to_python (self
, ctx
):
5125 return 'asn1.OCTSTRING'
5127 def eth_tname(self
):
5128 if not self
.HasConstraint():
5129 return 'OCTET_STRING'
5130 elif self
.constr
.type == 'Size':
5131 return 'OCTET_STRING' + '_' + self
.constr
.eth_constrname()
5133 return '#' + self
.type + '_' + str(id(self
))
5135 def eth_ftype(self
, ectx
):
5136 return ('FT_BYTES', 'BASE_NONE')
5138 def GetTTag(self
, ectx
):
5139 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
5141 def eth_need_pdu(self
, ectx
):
5143 if self
.HasContentsConstraint():
5144 t
= self
.constr
.GetContents(ectx
)
5145 if t
and (ectx
.default_containing_variant
in ('_pdu', '_pdu_new')):
5147 'new' : ectx
.default_containing_variant
== '_pdu_new' }
5150 def eth_type_default_pars(self
, ectx
, tname
):
5151 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5152 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
5153 if self
.HasContentsConstraint():
5154 pars
['FN_VARIANT'] = ectx
.default_containing_variant
5155 t
= self
.constr
.GetContents(ectx
)
5157 if pars
['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5158 t
= ectx
.field
[t
]['ethname']
5159 pars
['TYPE_REF_PROTO'] = ''
5160 pars
['TYPE_REF_TNAME'] = t
5161 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5163 t
= ectx
.type[t
]['ethname']
5164 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
5165 pars
['TYPE_REF_TNAME'] = t
5166 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5168 pars
['TYPE_REF_FN'] = 'NULL'
5171 def eth_type_default_body(self
, ectx
, tname
):
5173 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
5174 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret
='offset',
5175 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5176 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5178 body
= ectx
.eth_fn_call('dissect_%(ER)s_octet_string', ret
='offset',
5179 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5181 elif (ectx
.Per() or ectx
.Oer()):
5182 if self
.HasContentsConstraint():
5183 body
= ectx
.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret
='offset',
5184 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5185 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
5187 body
= ectx
.eth_fn_call('dissect_%(ER)s_octet_string', ret
='offset',
5188 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5189 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
5191 body
= '#error Can not decode %s' % (tname
)
5194 #--- CharacterStringType ------------------------------------------------------
5195 class CharacterStringType (Type
):
5196 def eth_tname(self
):
5197 if not self
.HasConstraint():
5198 return self
.eth_tsname()
5199 elif self
.constr
.type == 'Size':
5200 return self
.eth_tsname() + '_' + self
.constr
.eth_constrname()
5202 return '#' + self
.type + '_' + str(id(self
))
5204 def eth_ftype(self
, ectx
):
5205 return ('FT_STRING', 'BASE_NONE')
5207 class RestrictedCharacterStringType (CharacterStringType
):
5208 def to_python (self
, ctx
):
5209 return 'asn1.' + self
.eth_tsname()
5211 def GetTTag(self
, ectx
):
5212 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self
.eth_tsname())
5214 def eth_type_default_pars(self
, ectx
, tname
):
5215 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5216 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
5217 (pars
['STRING_TYPE'], pars
['STRING_TAG']) = (self
.eth_tsname(), self
.GetTTag(ectx
)[1])
5218 (pars
['ALPHABET'], pars
['ALPHABET_LEN']) = self
.eth_get_alphabet_constr(ectx
)
5221 def eth_type_default_body(self
, ectx
, tname
):
5223 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
5224 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret
='offset',
5225 par
=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5226 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5227 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5229 body
= ectx
.eth_fn_call('dissect_%(ER)s_restricted_string', ret
='offset',
5230 par
=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5231 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5233 elif (ectx
.Per() and self
.HasPermAlph() and self
.eth_tsname() in KnownMultiplierStringTypes
):
5234 # XXX: If there is a permitted alphabet but it is extensible,
5235 # then the permitted-alphabet is not PER-visible and should be
5236 # ignored. (X.691 9.3.10, 9.3.18) We don't handle extensible
5237 # permitted-alphabets.
5238 body
= ectx
.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret
='offset',
5239 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5240 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
5243 if (self
.eth_tsname() == 'GeneralString'):
5244 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5245 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5246 elif (self
.eth_tsname() == 'GeneralizedTime' or self
.eth_tsname() == 'UTCTime'):
5247 body
= ectx
.eth_fn_call('dissect_%(ER)s_VisibleString', ret
='offset',
5248 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5249 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s'),
5251 elif (self
.eth_tsname() in KnownMultiplierStringTypes
):
5252 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5253 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5254 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s'),
5257 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5258 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5259 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5261 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5262 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5263 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5265 body
= '#error Can not decode %s' % (tname
)
5268 class BMPStringType (RestrictedCharacterStringType
):
5269 def eth_tsname(self
):
5272 class GeneralStringType (RestrictedCharacterStringType
):
5273 def eth_tsname(self
):
5274 return 'GeneralString'
5276 class GraphicStringType (RestrictedCharacterStringType
):
5277 def eth_tsname(self
):
5278 return 'GraphicString'
5280 class IA5StringType (RestrictedCharacterStringType
):
5281 def eth_tsname(self
):
5284 class NumericStringType (RestrictedCharacterStringType
):
5285 def eth_tsname(self
):
5286 return 'NumericString'
5288 class PrintableStringType (RestrictedCharacterStringType
):
5289 def eth_tsname(self
):
5290 return 'PrintableString'
5292 class TeletexStringType (RestrictedCharacterStringType
):
5293 def eth_tsname(self
):
5294 return 'TeletexString'
5296 class T61StringType (RestrictedCharacterStringType
):
5297 def eth_tsname(self
):
5299 def GetTTag(self
, ectx
):
5300 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
5302 class UniversalStringType (RestrictedCharacterStringType
):
5303 def eth_tsname(self
):
5304 return 'UniversalString'
5306 class UTF8StringType (RestrictedCharacterStringType
):
5307 def eth_tsname(self
):
5310 class VideotexStringType (RestrictedCharacterStringType
):
5311 def eth_tsname(self
):
5312 return 'VideotexString'
5314 class VisibleStringType (RestrictedCharacterStringType
):
5315 def eth_tsname(self
):
5316 return 'VisibleString'
5318 class ISO646StringType (RestrictedCharacterStringType
):
5319 def eth_tsname(self
):
5320 return 'ISO646String'
5321 def GetTTag(self
, ectx
):
5322 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
5324 class UnrestrictedCharacterStringType (CharacterStringType
):
5325 def to_python (self
, ctx
):
5326 return 'asn1.UnrestrictedCharacterString'
5327 def eth_tsname(self
):
5328 return 'CHARACTER_STRING'
5330 #--- UsefulType ---------------------------------------------------------------
5331 class GeneralizedTime (RestrictedCharacterStringType
):
5332 def eth_tsname(self
):
5333 return 'GeneralizedTime'
5335 def eth_ftype(self
, ectx
):
5337 return ('FT_ABSOLUTE_TIME', 'ABSOLUTE_TIME_LOCAL')
5339 return ('FT_STRING', 'BASE_NONE')
5341 def eth_type_default_body(self
, ectx
, tname
):
5343 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5344 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5347 return RestrictedCharacterStringType
.eth_type_default_body(self
, ectx
, tname
)
5349 class UTCTime (RestrictedCharacterStringType
):
5350 def eth_tsname(self
):
5353 def eth_type_default_body(self
, ectx
, tname
):
5355 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5356 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', 'NULL', 'NULL'),))
5359 return RestrictedCharacterStringType
.eth_type_default_body(self
, ectx
, tname
)
5361 class ObjectDescriptor (RestrictedCharacterStringType
):
5362 def eth_tsname(self
):
5363 return 'ObjectDescriptor'
5365 def eth_type_default_body(self
, ectx
, tname
):
5367 body
= RestrictedCharacterStringType
.eth_type_default_body(self
, ectx
, tname
)
5369 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_descriptor', ret
='offset',
5370 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5372 body
= '#error Can not decode %s' % (tname
)
5375 #--- ObjectIdentifierType -----------------------------------------------------
5376 class ObjectIdentifierType (Type
):
5377 def to_python (self
, ctx
):
5378 return 'asn1.OBJECT_IDENTIFIER'
5380 def eth_tname(self
):
5381 return 'OBJECT_IDENTIFIER'
5383 def eth_ftype(self
, ectx
):
5384 return ('FT_OID', 'BASE_NONE')
5386 def GetTTag(self
, ectx
):
5387 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
5389 def eth_type_default_pars(self
, ectx
, tname
):
5390 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5391 pars
['FN_VARIANT'] = ectx
.default_oid_variant
5394 def eth_type_default_body(self
, ectx
, tname
):
5396 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret
='offset',
5397 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5399 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret
='offset',
5400 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5402 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret
='offset',
5403 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5405 body
= '#error Can not decode %s' % (tname
)
5408 #--- ObjectIdentifierValue ----------------------------------------------------
5409 class ObjectIdentifierValue (Value
):
5410 def get_num(self
, path
, val
):
5411 return str(oid_names
.get(path
+ '/' + val
, val
))
5413 def to_str(self
, ectx
):
5418 for v
in self
.comp_list
:
5419 if isinstance(v
, Node
) and (v
.type == 'name_and_number'):
5424 vstr
= self
.get_num(path
, v
)
5425 if not first
and not vstr
.isdigit():
5426 vstr
= ectx
.value_get_val(vstr
)
5431 out
+= ectx
.value_get_eth(vstr
) + '"'
5441 v
= self
.comp_list
[0]
5442 if isinstance(v
, Node
) and (v
.type == 'name_and_number'):
5447 vstr
= self
.get_num('', v
)
5453 class NamedNumber(Node
):
5454 def to_python (self
, ctx
):
5455 return "('%s',%s)" % (self
.ident
, self
.val
)
5456 def __lt__(self
, other
):
5457 return int(self
.val
) < int(other
.val
)
5459 class NamedNumListBase(Node
):
5460 def to_python (self
, ctx
):
5461 return "asn1.%s_class ([%s])" % (self
.asn1_typ
,",".join (
5462 [x
.to_python (ctx
) for x
in self
.named_list
]))
5464 #--- RelativeOIDType ----------------------------------------------------------
5465 class RelativeOIDType (Type
):
5467 def eth_tname(self
):
5468 return 'RELATIVE_OID'
5470 def eth_ftype(self
, ectx
):
5471 return ('FT_REL_OID', 'BASE_NONE')
5473 def GetTTag(self
, ectx
):
5474 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5476 def eth_type_default_pars(self
, ectx
, tname
):
5477 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5478 pars
['FN_VARIANT'] = ectx
.default_oid_variant
5481 def eth_type_default_body(self
, ectx
, tname
):
5483 body
= ectx
.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret
='offset',
5484 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5486 body
= ectx
.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret
='offset',
5487 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5489 body
= '#error Can not decode relative_oid %s' % (tname
)
5493 #--- IntegerType --------------------------------------------------------------
5494 class IntegerType (Type
):
5495 def to_python (self
, ctx
):
5496 return "asn1.INTEGER_class ([%s])" % (",".join (
5497 [x
.to_python (ctx
) for x
in self
.named_list
]))
5499 def add_named_value(self
, ident
, val
):
5500 e
= NamedNumber(ident
= ident
, val
= val
)
5501 if not self
.named_list
:
5502 self
.named_list
= []
5503 self
.named_list
.append(e
)
5505 def eth_tname(self
):
5507 return Type
.eth_tname(self
)
5508 if not self
.HasConstraint():
5510 elif self
.constr
.type == 'SingleValue' or self
.constr
.type == 'ValueRange':
5511 return 'INTEGER' + '_' + self
.constr
.eth_constrname()
5513 return 'INTEGER' + '_' + self
.constr
.eth_tname()
5515 def GetTTag(self
, ectx
):
5516 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5519 def eth_ftype(self
, ectx
):
5520 if self
.HasConstraint():
5521 if not self
.constr
.IsNegativ():
5522 if self
.constr
.Needs64b(ectx
):
5523 return ('FT_UINT64', 'BASE_DEC')
5525 return ('FT_UINT32', 'BASE_DEC')
5526 if self
.constr
.Needs64b(ectx
):
5527 return ('FT_INT64', 'BASE_DEC')
5528 return ('FT_INT32', 'BASE_DEC')
5530 def eth_strings(self
):
5531 if (self
.named_list
):
5536 def eth_has_vals(self
):
5537 if (self
.named_list
):
5542 def get_vals(self
, ectx
):
5544 for e
in (self
.named_list
):
5545 vals
.append((int(e
.val
), e
.ident
))
5548 def eth_type_vals(self
, tname
, ectx
):
5549 if not self
.eth_has_vals(): return ''
5551 vals
= self
.get_vals(ectx
)
5552 out
+= ectx
.eth_vals(tname
, vals
)
5555 def reg_enum_vals(self
, tname
, ectx
):
5556 vals
= self
.get_vals(ectx
)
5557 for (val
, id) in vals
:
5558 ectx
.eth_reg_value(id, self
, val
, ethname
=ectx
.eth_enum_item(tname
, id))
5560 def eth_type_enum(self
, tname
, ectx
):
5561 if not self
.eth_has_enum(tname
, ectx
): return ''
5563 vals
= self
.get_vals(ectx
)
5564 out
+= ectx
.eth_enum(tname
, vals
)
5567 def eth_type_default_pars(self
, ectx
, tname
):
5568 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5569 if self
.HasValueConstraint():
5570 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_value_constr(ectx
)
5571 if (pars
['FN_VARIANT'] == '') and self
.constr
.Needs64b(ectx
):
5572 if ectx
.Ber(): pars
['FN_VARIANT'] = '64'
5574 if (ectx
.Oer() and pars
['MAX_VAL'] == 'NO_BOUND'):
5575 pars
['FN_VARIANT'] = '_64b_no_ub'
5577 pars
['FN_VARIANT'] = '_64b'
5580 def eth_type_default_body(self
, ectx
, tname
):
5582 if (ectx
.constraints_check
and self
.HasValueConstraint()):
5583 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret
='offset',
5584 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5585 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5587 body
= ectx
.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret
='offset',
5588 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5590 elif (ectx
.Per() or ectx
.Oer()):
5591 if (self
.HasValueConstraint()):
5592 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret
='offset',
5593 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5594 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5596 body
= ectx
.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret
='offset',
5597 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5599 body
= '#error Can not decode %s' % (tname
)
5602 #--- BitStringType ------------------------------------------------------------
5603 class BitStringType (Type
):
5604 def to_python (self
, ctx
):
5605 return "asn1.BITSTRING_class ([%s])" % (",".join (
5606 [x
.to_python (ctx
) for x
in self
.named_list
]))
5608 def eth_tname(self
):
5610 return Type
.eth_tname(self
)
5611 elif not self
.HasConstraint():
5613 elif self
.constr
.IsSize():
5614 return 'BIT_STRING' + '_' + self
.constr
.eth_constrname()
5616 return '#' + self
.type + '_' + str(id(self
))
5618 def GetTTag(self
, ectx
):
5619 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5621 def eth_ftype(self
, ectx
):
5622 return ('FT_BYTES', 'BASE_NONE')
5624 def eth_need_tree(self
):
5625 return self
.named_list
5627 def eth_need_pdu(self
, ectx
):
5629 if self
.HasContentsConstraint():
5630 t
= self
.constr
.GetContents(ectx
)
5631 if t
and (ectx
.default_containing_variant
in ('_pdu', '_pdu_new')):
5633 'new' : ectx
.default_containing_variant
== '_pdu_new' }
5636 def sortNamedBits(self
):
5637 return self
.named_list
.val
5639 def eth_named_bits(self
):
5641 if (self
.named_list
):
5642 sorted_list
= self
.named_list
5645 for e
in (sorted_list
):
5646 # Fill the table with "spare_bit" for "un named bits"
5647 if (int(e
.val
) != 0) and (expected_bit_no
!= int(e
.val
)):
5648 while ( expected_bit_no
< int(e
.val
)):
5649 bits
.append((expected_bit_no
, ("spare_bit%u" % (expected_bit_no
))))
5650 expected_bit_no
= expected_bit_no
+ 1
5651 #print ("Adding named bits to list %s bit no %d" % (e.ident, int (e.val)))
5652 bits
.append((int(e
.val
), e
.ident
))
5653 expected_bit_no
= int(e
.val
) + 1
5656 def eth_type_default_pars(self
, ectx
, tname
):
5657 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5658 pars
['LEN_PTR'] = 'NULL'
5659 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
5660 if 'ETT_INDEX' not in pars
:
5661 pars
['ETT_INDEX'] = '-1'
5662 pars
['TABLE'] = 'NULL'
5663 if self
.eth_named_bits():
5664 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5665 if self
.HasContentsConstraint():
5666 pars
['FN_VARIANT'] = ectx
.default_containing_variant
5667 t
= self
.constr
.GetContents(ectx
)
5669 if pars
['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5670 t
= ectx
.field
[t
]['ethname']
5671 pars
['TYPE_REF_PROTO'] = ''
5672 pars
['TYPE_REF_TNAME'] = t
5673 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5675 t
= ectx
.type[t
]['ethname']
5676 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
5677 pars
['TYPE_REF_TNAME'] = t
5678 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5680 pars
['TYPE_REF_FN'] = 'NULL'
5683 def eth_type_default_table(self
, ectx
, tname
):
5684 #print ("eth_type_default_table(tname='%s')" % (tname))
5686 bits
= self
.eth_named_bits()
5688 table
= ectx
.eth_bits(tname
, bits
)
5691 def eth_type_default_body(self
, ectx
, tname
):
5692 bits
= self
.eth_named_bits()
5694 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
5695 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret
='offset',
5696 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5697 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%s' % len(bits
),'%(HF_INDEX)s', '%(ETT_INDEX)s',),
5700 body
= ectx
.eth_fn_call('dissect_%(ER)s_bitstring', ret
='offset',
5701 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5702 ('%(TABLE)s', '%s' % len(bits
), '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5704 elif (ectx
.Per() or ectx
.Oer()):
5705 if self
.HasContentsConstraint():
5706 body
= ectx
.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret
='offset',
5707 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5708 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5710 body
= ectx
.eth_fn_call('dissect_%(ER)s_bit_string', ret
='offset',
5711 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5712 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s','%(TABLE)s', '%s' % len(bits
), '%(VAL_PTR)s', '%(LEN_PTR)s'),))
5714 body
= '#error Can not decode %s' % (tname
)
5717 #--- BStringValue ------------------------------------------------------------
5736 class BStringValue (Value
):
5737 def to_str(self
, ectx
):
5740 v
+= '0' * (8 - len(v
) % 8)
5742 for i
in (list(range(0, len(v
), 4))):
5743 vv
+= bstring_tab
[v
[i
:i
+4]]
5746 #--- HStringValue ------------------------------------------------------------
5747 class HStringValue (Value
):
5748 def to_str(self
, ectx
):
5750 vv
+= self
.val
[1:-2]
5753 return int(self
.val
[1:-2], 16)
5755 #--- FieldSpec ----------------------------------------------------------------
5756 class FieldSpec (Node
):
5757 def __init__(self
,*args
, **kw
) :
5759 Node
.__init
__ (self
,*args
, **kw
)
5761 def SetName(self
, name
):
5765 return ['#UNSUPPORTED_' + self
.type]
5769 repr.extend(self
.get_repr())
5772 class TypeFieldSpec (FieldSpec
):
5776 class FixedTypeValueFieldSpec (FieldSpec
):
5778 if isinstance(self
.typ
, Type_Ref
):
5779 repr = ['TypeReference', self
.typ
.val
]
5781 repr = [self
.typ
.type]
5784 class VariableTypeValueFieldSpec (FieldSpec
):
5786 return ['_' + self
.type]
5788 class FixedTypeValueSetFieldSpec (FieldSpec
):
5790 return ['_' + self
.type]
5792 class ObjectFieldSpec (FieldSpec
):
5794 return ['ClassReference', self
.cls
.val
]
5796 class ObjectSetFieldSpec (FieldSpec
):
5798 return ['ClassReference', self
.cls
.val
]
5800 #==============================================================================
5802 def p_module_list_1 (t
):
5803 'module_list : module_list ModuleDefinition'
5804 t
[0] = t
[1] + [t
[2]]
5806 def p_module_list_2 (t
):
5807 'module_list : ModuleDefinition'
5811 #--- ITU-T Recommendation X.680 -----------------------------------------------
5814 # 11 ASN.1 lexical items --------------------------------------------------------
5816 # 11.2 Type references
5818 'type_ref : UCASE_IDENT'
5819 t
[0] = Type_Ref(val
=t
[1])
5822 def p_identifier (t
):
5823 'identifier : LCASE_IDENT'
5826 # 11.4 Value references
5827 # cause reduce/reduce conflict
5828 #def p_valuereference (t):
5829 # 'valuereference : LCASE_IDENT'
5830 # t[0] = Value_Ref(val=t[1])
5832 # 11.5 Module references
5833 def p_modulereference (t
):
5834 'modulereference : UCASE_IDENT'
5838 # 12 Module definition --------------------------------------------------------
5841 def p_ModuleDefinition (t
):
5842 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5843 t
[0] = Module (ident
= t
[1], tag_def
= t
[3], body
= t
[7])
5845 def p_ModuleBegin (t
):
5847 if t
[-4].val
== 'Remote-Operations-Information-Objects':
5850 def p_TagDefault_1 (t
):
5851 '''TagDefault : EXPLICIT TAGS
5853 | AUTOMATIC TAGS '''
5854 t
[0] = Default_Tags (dfl_tag
= t
[1])
5856 def p_TagDefault_2 (t
):
5858 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5859 t
[0] = Default_Tags (dfl_tag
= 'EXPLICIT')
5861 def p_ModuleIdentifier_1 (t
):
5862 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5863 t
[0] = Node('module_ident', val
= t
[1], ident
= t
[2])
5865 def p_ModuleIdentifier_2 (t
):
5866 'ModuleIdentifier : modulereference' # name, oid
5867 t
[0] = Node('module_ident', val
= t
[1], ident
= None)
5869 def p_DefinitiveIdentifier (t
):
5870 'DefinitiveIdentifier : ObjectIdentifierValue'
5873 #def p_module_ref (t):
5874 # 'module_ref : UCASE_IDENT'
5877 def p_ModuleBody_1 (t
):
5878 'ModuleBody : Exports Imports AssignmentList'
5879 t
[0] = Module_Body (exports
= t
[1], imports
= t
[2], assign_list
= t
[3])
5881 def p_ModuleBody_2 (t
):
5883 t
[0] = Node ('module_body', exports
= [], imports
= [], assign_list
= [])
5885 def p_Exports_1 (t
):
5886 'Exports : EXPORTS syms_exported SEMICOLON'
5889 def p_Exports_2 (t
):
5890 'Exports : EXPORTS ALL SEMICOLON'
5893 def p_Exports_3 (t
):
5897 def p_syms_exported_1 (t
):
5898 'syms_exported : exp_sym_list'
5901 def p_syms_exported_2 (t
):
5905 def p_exp_sym_list_1 (t
):
5906 'exp_sym_list : Symbol'
5909 def p_exp_sym_list_2 (t
):
5910 'exp_sym_list : exp_sym_list COMMA Symbol'
5911 t
[0] = t
[1] + [t
[3]]
5914 def p_Imports_1 (t
):
5915 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5917 global lcase_ident_assigned
5918 lcase_ident_assigned
= {}
5920 def p_importsbegin (t
):
5922 global lcase_ident_assigned
5924 lcase_ident_assigned
= {}
5925 lcase_ident_assigned
.update(g_conform
.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5927 def p_Imports_2 (t
):
5931 def p_SymbolsImported_1(t
):
5932 'SymbolsImported : '
5935 def p_SymbolsImported_2 (t
):
5936 'SymbolsImported : SymbolsFromModuleList'
5939 def p_SymbolsFromModuleList_1 (t
):
5940 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5941 t
[0] = t
[1] + [t
[2]]
5943 def p_SymbolsFromModuleList_2 (t
):
5944 'SymbolsFromModuleList : SymbolsFromModule'
5947 def p_SymbolsFromModule (t
):
5948 '''SymbolsFromModule : SymbolList FROM GlobalModuleReference
5949 | SymbolList FROM GlobalModuleReference WITH SUCCESSORS'''
5950 t
[0] = Node ('SymbolList', symbol_list
= t
[1], module
= t
[3])
5951 for s
in (t
[0].symbol_list
):
5952 if (isinstance(s
, Value_Ref
)): lcase_ident_assigned
[s
.val
] = t
[3]
5953 import_symbols_from_module(t
[0].module
, t
[0].symbol_list
)
5955 def import_symbols_from_module(module
, symbol_list
):
5956 if module
.val
== 'Remote-Operations-Information-Objects':
5957 for i
in range(len(symbol_list
)):
5959 if isinstance(s
, Type_Ref
) or isinstance(s
, Class_Ref
):
5961 if isinstance(s
, Type_Ref
) and is_class_ident(s
.val
):
5962 symbol_list
[i
] = Class_Ref (val
= s
.val
)
5964 for i
in range(len(symbol_list
)):
5966 if isinstance(s
, Type_Ref
) and is_class_ident("$%s$%s" % (module
.val
, s
.val
)):
5967 import_class_from_module(module
.val
, s
.val
)
5968 if isinstance(s
, Type_Ref
) and is_class_ident(s
.val
):
5969 symbol_list
[i
] = Class_Ref (val
= s
.val
)
5971 def p_GlobalModuleReference (t
):
5972 'GlobalModuleReference : modulereference AssignedIdentifier'
5973 t
[0] = Node('module_ident', val
= t
[1], ident
= t
[2])
5975 def p_AssignedIdentifier_1 (t
):
5976 'AssignedIdentifier : ObjectIdentifierValue'
5979 def p_AssignedIdentifier_2 (t
):
5980 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5983 def p_AssignedIdentifier_3 (t
):
5984 'AssignedIdentifier : '
5987 def p_SymbolList_1 (t
):
5988 'SymbolList : Symbol'
5991 def p_SymbolList_2 (t
):
5992 'SymbolList : SymbolList COMMA Symbol'
5993 t
[0] = t
[1] + [t
[3]]
5996 '''Symbol : Reference
5997 | ParameterizedReference'''
6000 def p_Reference_1 (t
):
6001 '''Reference : type_ref
6002 | objectclassreference '''
6005 def p_Reference_2 (t
):
6006 '''Reference : LCASE_IDENT_ASSIGNED
6007 | identifier ''' # instead of valuereference which causes reduce/reduce conflict
6008 t
[0] = Value_Ref(val
=t
[1])
6010 def p_AssignmentList_1 (t
):
6011 'AssignmentList : AssignmentList Assignment'
6012 t
[0] = t
[1] + [t
[2]]
6014 def p_AssignmentList_2 (t
):
6015 'AssignmentList : Assignment SEMICOLON'
6018 def p_AssignmentList_3 (t
):
6019 'AssignmentList : Assignment'
6022 def p_Assignment (t
):
6023 '''Assignment : TypeAssignment
6025 | ValueSetTypeAssignment
6026 | ObjectClassAssignment
6028 | ObjectSetAssignment
6029 | ParameterizedAssignment
6034 # 13 Referencing type and value definitions -----------------------------------
6037 def p_DefinedType (t
):
6038 '''DefinedType : ExternalTypeReference
6040 | ParameterizedType'''
6043 def p_DefinedValue_1(t
):
6044 '''DefinedValue : ExternalValueReference'''
6047 def p_DefinedValue_2(t
):
6048 '''DefinedValue : identifier ''' # instead of valuereference which causes reduce/reduce conflict
6049 t
[0] = Value_Ref(val
=t
[1])
6052 def p_ExternalTypeReference (t
):
6053 'ExternalTypeReference : modulereference DOT type_ref'
6054 t
[0] = Node ('ExternalTypeReference', module
= t
[1], typ
= t
[3])
6056 def p_ExternalValueReference (t
):
6057 'ExternalValueReference : modulereference DOT identifier'
6058 t
[0] = Node ('ExternalValueReference', module
= t
[1], ident
= t
[3])
6061 # 15 Assigning types and values -----------------------------------------------
6064 def p_TypeAssignment (t
):
6065 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
6070 def p_ValueAssignment (t
):
6071 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
6072 t
[0] = ValueAssignment(ident
= t
[1], typ
= t
[2], val
= t
[4])
6074 # only "simple" types are supported to simplify grammar
6075 def p_ValueType (t
):
6076 '''ValueType : type_ref
6079 | ObjectIdentifierType
6086 def p_ValueSetTypeAssignment (t
):
6087 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
6088 t
[0] = Node('ValueSetTypeAssignment', name
=t
[1], typ
=t
[2], val
=t
[4])
6092 'ValueSet : lbraceignore rbraceignore'
6096 # 16 Definition of types and values -------------------------------------------
6100 '''Type : BuiltinType
6102 | ConstrainedType'''
6106 def p_BuiltinType (t
):
6107 '''BuiltinType : AnyType
6110 | CharacterStringType
6118 | ObjectClassFieldType
6119 | ObjectIdentifierType
6131 def p_ReferencedType (t
):
6132 '''ReferencedType : DefinedType
6138 def p_NamedType (t
):
6139 'NamedType : identifier Type'
6145 '''Value : BuiltinValue
6147 | ObjectClassFieldValue'''
6151 def p_BuiltinValue (t
):
6152 '''BuiltinValue : BooleanValue
6155 | ObjectIdentifierValue
6160 | char_string''' # XXX we don't support {data} here
6164 def p_ReferencedValue (t
):
6165 '''ReferencedValue : DefinedValue
6166 | ValueFromObject'''
6170 #def p_NamedValue (t):
6171 # 'NamedValue : identifier Value'
6172 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
6175 # 17 Notation for the boolean type --------------------------------------------
6178 def p_BooleanType (t
):
6179 'BooleanType : BOOLEAN'
6180 t
[0] = BooleanType ()
6183 def p_BooleanValue (t
):
6184 '''BooleanValue : TRUE
6189 # 18 Notation for the integer type --------------------------------------------
6192 def p_IntegerType_1 (t
):
6193 'IntegerType : INTEGER'
6194 t
[0] = IntegerType (named_list
= None)
6196 def p_IntegerType_2 (t
):
6197 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
6198 t
[0] = IntegerType(named_list
= t
[3])
6200 def p_NamedNumberList_1 (t
):
6201 'NamedNumberList : NamedNumber'
6204 def p_NamedNumberList_2 (t
):
6205 'NamedNumberList : NamedNumberList COMMA NamedNumber'
6206 t
[0] = t
[1] + [t
[3]]
6208 def p_NamedNumber (t
):
6209 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
6210 | identifier LPAREN DefinedValue RPAREN'''
6211 t
[0] = NamedNumber(ident
= t
[1], val
= t
[3])
6213 def p_SignedNumber_1 (t
):
6214 'SignedNumber : NUMBER'
6217 def p_SignedNumber_2 (t
):
6218 'SignedNumber : MINUS NUMBER'
6222 def p_IntegerValue (t
):
6223 'IntegerValue : SignedNumber'
6226 # 19 Notation for the enumerated type -----------------------------------------
6229 def p_EnumeratedType (t
):
6230 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
6231 t
[0] = EnumeratedType (val
= t
[3]['val'], ext
= t
[3]['ext'])
6233 def p_Enumerations_1 (t
):
6234 'Enumerations : Enumeration'
6235 t
[0] = { 'val' : t
[1], 'ext' : None }
6237 def p_Enumerations_2 (t
):
6238 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
6239 t
[0] = { 'val' : t
[1], 'ext' : [] }
6241 def p_Enumerations_3 (t
):
6242 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
6243 t
[0] = { 'val' : t
[1], 'ext' : t
[6] }
6245 def p_Enumeration_1 (t
):
6246 'Enumeration : EnumerationItem'
6249 def p_Enumeration_2 (t
):
6250 'Enumeration : Enumeration COMMA EnumerationItem'
6251 t
[0] = t
[1] + [t
[3]]
6253 def p_EnumerationItem (t
):
6254 '''EnumerationItem : Identifier
6258 def p_Identifier (t
):
6259 'Identifier : identifier'
6260 t
[0] = Node ('Identifier', ident
= t
[1])
6263 # 20 Notation for the real type -----------------------------------------------
6271 def p_RealValue (t
):
6272 '''RealValue : REAL_NUMBER
6273 | SpecialRealValue'''
6276 def p_SpecialRealValue (t
):
6277 '''SpecialRealValue : PLUS_INFINITY
6282 # 21 Notation for the bitstring type ------------------------------------------
6285 def p_BitStringType_1 (t
):
6286 'BitStringType : BIT STRING'
6287 t
[0] = BitStringType (named_list
= None)
6289 def p_BitStringType_2 (t
):
6290 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
6291 t
[0] = BitStringType (named_list
= t
[4])
6293 def p_NamedBitList_1 (t
):
6294 'NamedBitList : NamedBit'
6297 def p_NamedBitList_2 (t
):
6298 'NamedBitList : NamedBitList COMMA NamedBit'
6299 t
[0] = t
[1] + [t
[3]]
6302 '''NamedBit : identifier LPAREN NUMBER RPAREN
6303 | identifier LPAREN DefinedValue RPAREN'''
6304 t
[0] = NamedNumber (ident
= t
[1], val
= t
[3])
6307 # 22 Notation for the octetstring type ----------------------------------------
6310 def p_OctetStringType (t
):
6311 'OctetStringType : OCTET STRING'
6312 t
[0] = OctetStringType ()
6315 # 23 Notation for the null type -----------------------------------------------
6323 def p_NullValue (t
):
6328 # 24 Notation for sequence types ----------------------------------------------
6331 def p_SequenceType_1 (t
):
6332 'SequenceType : SEQUENCE LBRACE RBRACE'
6333 t
[0] = SequenceType (elt_list
= [])
6335 def p_SequenceType_2 (t
):
6336 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
6337 t
[0] = SequenceType (elt_list
= t
[3]['elt_list'])
6338 if 'ext_list' in t
[3]:
6339 t
[0].ext_list
= t
[3]['ext_list']
6340 if 'elt_list2' in t
[3]:
6341 t
[0].elt_list2
= t
[3]['elt_list2']
6343 def p_ExtensionAndException_1 (t
):
6344 'ExtensionAndException : ELLIPSIS'
6347 def p_OptionalExtensionMarker_1 (t
):
6348 'OptionalExtensionMarker : COMMA ELLIPSIS'
6351 def p_OptionalExtensionMarker_2 (t
):
6352 'OptionalExtensionMarker : '
6355 def p_ComponentTypeLists_1 (t
):
6356 'ComponentTypeLists : ComponentTypeList'
6357 t
[0] = {'elt_list' : t
[1]}
6359 def p_ComponentTypeLists_2 (t
):
6360 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
6361 t
[0] = {'elt_list' : t
[1], 'ext_list' : []}
6363 def p_ComponentTypeLists_3 (t
):
6364 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6365 t
[0] = {'elt_list' : t
[1], 'ext_list' : t
[4]}
6367 def p_ComponentTypeLists_4 (t
):
6368 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
6369 t
[0] = {'elt_list' : t
[1], 'ext_list' : [], 'elt_list2' : t
[6]}
6371 def p_ComponentTypeLists_5 (t
):
6372 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
6373 t
[0] = {'elt_list' : t
[1], 'ext_list' : t
[4], 'elt_list2' : t
[7]}
6375 def p_ComponentTypeLists_6 (t
):
6376 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
6377 t
[0] = {'elt_list' : [], 'ext_list' : []}
6379 def p_ComponentTypeLists_7 (t
):
6380 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6381 t
[0] = {'elt_list' : [], 'ext_list' : t
[2]}
6383 def p_ExtensionEndMarker (t
):
6384 'ExtensionEndMarker : COMMA ELLIPSIS'
6387 def p_ExtensionAdditionList_1 (t
):
6388 'ExtensionAdditionList : COMMA ExtensionAddition'
6391 def p_ExtensionAdditionList_2 (t
):
6392 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition'
6393 t
[0] = t
[1] + [t
[3]]
6395 def p_ExtensionAddition_1 (t
):
6396 'ExtensionAddition : ExtensionAdditionGroup'
6397 t
[0] = Node ('elt_type', val
= t
[1], optional
= 0)
6399 def p_ExtensionAddition_2 (t
):
6400 'ExtensionAddition : ComponentType'
6403 def p_ExtensionAdditionGroup (t
):
6404 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK'
6405 t
[0] = ExtensionAdditionGroup (ver
= t
[2], elt_list
= t
[3])
6407 def p_VersionNumber_1 (t
):
6410 def p_VersionNumber_2 (t
):
6411 'VersionNumber : NUMBER COLON'
6414 def p_ComponentTypeList_1 (t
):
6415 'ComponentTypeList : ComponentType'
6418 def p_ComponentTypeList_2 (t
):
6419 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
6420 t
[0] = t
[1] + [t
[3]]
6422 def p_ComponentType_1 (t
):
6423 'ComponentType : NamedType'
6424 t
[0] = Node ('elt_type', val
= t
[1], optional
= 0)
6426 def p_ComponentType_2 (t
):
6427 'ComponentType : NamedType OPTIONAL'
6428 t
[0] = Node ('elt_type', val
= t
[1], optional
= 1)
6430 def p_ComponentType_3 (t
):
6431 'ComponentType : NamedType DEFAULT DefaultValue'
6432 t
[0] = Node ('elt_type', val
= t
[1], optional
= 1, default
= t
[3])
6434 def p_ComponentType_4 (t
):
6435 'ComponentType : COMPONENTS OF Type'
6436 t
[0] = Node ('components_of', typ
= t
[3])
6438 def p_DefaultValue_1 (t
):
6439 '''DefaultValue : ReferencedValue
6447 | ObjectClassFieldValue'''
6450 def p_DefaultValue_2 (t
):
6451 'DefaultValue : lbraceignore rbraceignore'
6455 def p_SequenceValue_1 (t
):
6456 'SequenceValue : LBRACE RBRACE'
6460 #def p_SequenceValue_2 (t):
6461 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
6464 #def p_ComponentValueList_1 (t):
6465 # 'ComponentValueList : NamedValue'
6468 #def p_ComponentValueList_2 (t):
6469 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
6470 # t[0] = t[1] + [t[3]]
6473 # 25 Notation for sequence-of types -------------------------------------------
6476 def p_SequenceOfType (t
):
6477 '''SequenceOfType : SEQUENCE OF Type
6478 | SEQUENCE OF NamedType'''
6479 t
[0] = SequenceOfType (val
= t
[3], size_constr
= None)
6482 # 26 Notation for set types ---------------------------------------------------
6485 def p_SetType_1 (t
):
6486 'SetType : SET LBRACE RBRACE'
6487 t
[0] = SetType (elt_list
= [])
6489 def p_SetType_2 (t
):
6490 'SetType : SET LBRACE ComponentTypeLists RBRACE'
6491 t
[0] = SetType (elt_list
= t
[3]['elt_list'])
6492 if 'ext_list' in t
[3]:
6493 t
[0].ext_list
= t
[3]['ext_list']
6494 if 'elt_list2' in t
[3]:
6495 t
[0].elt_list2
= t
[3]['elt_list2']
6498 # 27 Notation for set-of types ------------------------------------------------
6501 def p_SetOfType (t
):
6502 '''SetOfType : SET OF Type
6503 | SET OF NamedType'''
6504 t
[0] = SetOfType (val
= t
[3])
6506 # 28 Notation for choice types ------------------------------------------------
6509 def p_ChoiceType (t
):
6510 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE'
6511 if 'ext_list' in t
[3]:
6512 t
[0] = ChoiceType (elt_list
= t
[3]['elt_list'], ext_list
= t
[3]['ext_list'])
6514 t
[0] = ChoiceType (elt_list
= t
[3]['elt_list'])
6516 def p_AlternativeTypeLists_1 (t
):
6517 'AlternativeTypeLists : AlternativeTypeList'
6518 t
[0] = {'elt_list' : t
[1]}
6520 def p_AlternativeTypeLists_2 (t
):
6521 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker'
6522 t
[0] = {'elt_list' : t
[1], 'ext_list' : t
[4]}
6524 def p_ExtensionAdditionAlternatives_1 (t
):
6525 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList'
6528 def p_ExtensionAdditionAlternatives_2 (t
):
6529 'ExtensionAdditionAlternatives : '
6532 def p_ExtensionAdditionAlternativesList_1 (t
):
6533 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative'
6536 def p_ExtensionAdditionAlternativesList_2 (t
):
6537 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative'
6540 def p_ExtensionAdditionAlternative_1 (t
):
6541 'ExtensionAdditionAlternative : NamedType'
6544 def p_ExtensionAdditionAlternative_2 (t
):
6545 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup'
6548 def p_ExtensionAdditionAlternativesGroup (t
):
6549 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK'
6552 def p_AlternativeTypeList_1 (t
):
6553 'AlternativeTypeList : NamedType'
6556 def p_AlternativeTypeList_2 (t
):
6557 'AlternativeTypeList : AlternativeTypeList COMMA NamedType'
6558 t
[0] = t
[1] + [t
[3]]
6561 def p_ChoiceValue_1 (t
):
6562 '''ChoiceValue : identifier COLON Value
6563 | identifier COLON NullValue '''
6565 if not isinstance(val
, Value
):
6566 val
= Value(val
=val
)
6567 t
[0] = ChoiceValue (choice
= t
[1], val
= val
)
6569 # 29 Notation for selection types
6572 def p_SelectionType (t
): #
6573 'SelectionType : identifier LT Type'
6574 t
[0] = SelectionType (typ
= t
[3], sel
= t
[1])
6576 # 30 Notation for tagged types ------------------------------------------------
6579 def p_TaggedType_1 (t
):
6580 'TaggedType : Tag Type'
6581 t
[1].mode
= 'default'
6585 def p_TaggedType_2 (t
):
6586 '''TaggedType : Tag IMPLICIT Type
6587 | Tag EXPLICIT Type'''
6593 'Tag : LBRACK Class ClassNumber RBRACK'
6594 t
[0] = Tag(cls
= t
[2], num
= t
[3])
6596 def p_ClassNumber_1 (t
):
6597 'ClassNumber : number'
6600 def p_ClassNumber_2 (t
):
6601 'ClassNumber : DefinedValue'
6605 '''Class : UNIVERSAL
6615 # 31 Notation for the object identifier type ----------------------------------
6618 def p_ObjectIdentifierType (t
):
6619 'ObjectIdentifierType : OBJECT IDENTIFIER'
6620 t
[0] = ObjectIdentifierType()
6623 def p_ObjectIdentifierValue (t
):
6624 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6625 t
[0] = ObjectIdentifierValue (comp_list
=t
[2])
6627 def p_oid_comp_list_1 (t
):
6628 'oid_comp_list : oid_comp_list ObjIdComponents'
6629 t
[0] = t
[1] + [t
[2]]
6631 def p_oid_comp_list_2 (t
):
6632 'oid_comp_list : ObjIdComponents'
6635 def p_ObjIdComponents (t
):
6636 '''ObjIdComponents : NameForm
6638 | NameAndNumberForm'''
6642 '''NameForm : LCASE_IDENT
6643 | LCASE_IDENT_ASSIGNED'''
6646 def p_NumberForm (t
):
6647 '''NumberForm : NUMBER'''
6651 def p_NameAndNumberForm (t
):
6652 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6653 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6654 t
[0] = Node('name_and_number', ident
= t
[1], number
= t
[3])
6656 # 32 Notation for the relative object identifier type -------------------------
6659 def p_RelativeOIDType (t
):
6660 'RelativeOIDType : RELATIVE_OID'
6661 t
[0] = RelativeOIDType()
6663 # 33 Notation for the embedded-pdv type ---------------------------------------
6666 def p_EmbeddedPDVType (t
):
6667 'EmbeddedPDVType : EMBEDDED PDV'
6668 t
[0] = EmbeddedPDVType()
6670 # 34 Notation for the external type -------------------------------------------
6673 def p_ExternalType (t
):
6674 'ExternalType : EXTERNAL'
6675 t
[0] = ExternalType()
6677 # 36 Notation for character string types --------------------------------------
6680 def p_CharacterStringType (t
):
6681 '''CharacterStringType : RestrictedCharacterStringType
6682 | UnrestrictedCharacterStringType'''
6686 # 37 Definition of restricted character string types --------------------------
6688 def p_RestrictedCharacterStringType_1 (t
):
6689 'RestrictedCharacterStringType : BMPString'
6690 t
[0] = BMPStringType ()
6691 def p_RestrictedCharacterStringType_2 (t
):
6692 'RestrictedCharacterStringType : GeneralString'
6693 t
[0] = GeneralStringType ()
6694 def p_RestrictedCharacterStringType_3 (t
):
6695 'RestrictedCharacterStringType : GraphicString'
6696 t
[0] = GraphicStringType ()
6697 def p_RestrictedCharacterStringType_4 (t
):
6698 'RestrictedCharacterStringType : IA5String'
6699 t
[0] = IA5StringType ()
6700 def p_RestrictedCharacterStringType_5 (t
):
6701 'RestrictedCharacterStringType : ISO646String'
6702 t
[0] = ISO646StringType ()
6703 def p_RestrictedCharacterStringType_6 (t
):
6704 'RestrictedCharacterStringType : NumericString'
6705 t
[0] = NumericStringType ()
6706 def p_RestrictedCharacterStringType_7 (t
):
6707 'RestrictedCharacterStringType : PrintableString'
6708 t
[0] = PrintableStringType ()
6709 def p_RestrictedCharacterStringType_8 (t
):
6710 'RestrictedCharacterStringType : TeletexString'
6711 t
[0] = TeletexStringType ()
6712 def p_RestrictedCharacterStringType_9 (t
):
6713 'RestrictedCharacterStringType : T61String'
6714 t
[0] = T61StringType ()
6715 def p_RestrictedCharacterStringType_10 (t
):
6716 'RestrictedCharacterStringType : UniversalString'
6717 t
[0] = UniversalStringType ()
6718 def p_RestrictedCharacterStringType_11 (t
):
6719 'RestrictedCharacterStringType : UTF8String'
6720 t
[0] = UTF8StringType ()
6721 def p_RestrictedCharacterStringType_12 (t
):
6722 'RestrictedCharacterStringType : VideotexString'
6723 t
[0] = VideotexStringType ()
6724 def p_RestrictedCharacterStringType_13 (t
):
6725 'RestrictedCharacterStringType : VisibleString'
6726 t
[0] = VisibleStringType ()
6729 # 40 Definition of unrestricted character string types ------------------------
6732 def p_UnrestrictedCharacterStringType (t
):
6733 'UnrestrictedCharacterStringType : CHARACTER STRING'
6734 t
[0] = UnrestrictedCharacterStringType ()
6737 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6739 # 42 Generalized time ---------------------------------------------------------
6741 def p_UsefulType_1 (t
):
6742 'UsefulType : GeneralizedTime'
6743 t
[0] = GeneralizedTime()
6745 # 43 Universal time -----------------------------------------------------------
6747 def p_UsefulType_2 (t
):
6748 'UsefulType : UTCTime'
6751 # 44 The object descriptor type -----------------------------------------------
6753 def p_UsefulType_3 (t
):
6754 'UsefulType : ObjectDescriptor'
6755 t
[0] = ObjectDescriptor()
6758 # 45 Constrained types --------------------------------------------------------
6761 def p_ConstrainedType_1 (t
):
6762 'ConstrainedType : Type Constraint'
6764 t
[0].AddConstraint(t
[2])
6766 def p_ConstrainedType_2 (t
):
6767 'ConstrainedType : TypeWithConstraint'
6771 def p_TypeWithConstraint_1 (t
):
6772 '''TypeWithConstraint : SET Constraint OF Type
6773 | SET SizeConstraint OF Type'''
6774 t
[0] = SetOfType (val
= t
[4], constr
= t
[2])
6776 def p_TypeWithConstraint_2 (t
):
6777 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6778 | SEQUENCE SizeConstraint OF Type'''
6779 t
[0] = SequenceOfType (val
= t
[4], constr
= t
[2])
6781 def p_TypeWithConstraint_3 (t
):
6782 '''TypeWithConstraint : SET Constraint OF NamedType
6783 | SET SizeConstraint OF NamedType'''
6784 t
[0] = SetOfType (val
= t
[4], constr
= t
[2])
6786 def p_TypeWithConstraint_4 (t
):
6787 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6788 | SEQUENCE SizeConstraint OF NamedType'''
6789 t
[0] = SequenceOfType (val
= t
[4], constr
= t
[2])
6793 def p_Constraint (t
):
6794 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6797 def p_ConstraintSpec (t
):
6798 '''ConstraintSpec : ElementSetSpecs
6799 | GeneralConstraint'''
6802 # 46 Element set specification ------------------------------------------------
6805 def p_ElementSetSpecs_1 (t
):
6806 'ElementSetSpecs : RootElementSetSpec'
6809 def p_ElementSetSpecs_2 (t
):
6810 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6814 def p_ElementSetSpecs_3 (t
):
6815 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6819 def p_RootElementSetSpec (t
):
6820 'RootElementSetSpec : ElementSetSpec'
6823 def p_AdditionalElementSetSpec (t
):
6824 'AdditionalElementSetSpec : ElementSetSpec'
6827 def p_ElementSetSpec (t
):
6828 'ElementSetSpec : Unions'
6832 'Unions : Intersections'
6836 'Unions : UElems UnionMark Intersections'
6837 # Constraints currently ignored become None, e.g. InnerTypeConstraints
6838 # (WITH COMPONENT[S]). Don't add them to a Union.
6844 t
[0] = Constraint(type = 'Union', subtype
= [t
[1], t
[3]])
6850 def p_Intersections_1 (t
):
6851 'Intersections : IntersectionElements'
6854 def p_Intersections_2 (t
):
6855 'Intersections : IElems IntersectionMark IntersectionElements'
6856 t
[0] = Constraint(type = 'Intersection', subtype
= [t
[1], t
[3]])
6859 'IElems : Intersections'
6862 def p_IntersectionElements (t
):
6863 'IntersectionElements : Elements'
6866 def p_UnionMark (t
):
6870 def p_IntersectionMark (t
):
6871 '''IntersectionMark : CIRCUMFLEX
6875 def p_Elements_1 (t
):
6876 'Elements : SubtypeElements'
6879 def p_Elements_2 (t
):
6880 'Elements : LPAREN ElementSetSpec RPAREN'
6883 # 47 Subtype elements ---------------------------------------------------------
6886 def p_SubtypeElements (t
):
6887 '''SubtypeElements : SingleValue
6893 | InnerTypeConstraints
6894 | PatternConstraint'''
6899 def p_SingleValue (t
):
6900 'SingleValue : Value'
6901 t
[0] = Constraint(type = 'SingleValue', subtype
= t
[1])
6903 # 47.3 Contained subtype
6905 def p_ContainedSubtype (t
):
6906 'ContainedSubtype : Includes Type'
6907 t
[0] = Constraint(type = 'ContainedSubtype', subtype
= t
[2])
6910 '''Includes : INCLUDES
6915 def p_ValueRange (t
):
6916 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6917 t
[0] = Constraint(type = 'ValueRange', subtype
= [t
[1], t
[3]])
6920 def p_LowerEndpoint_1 (t
):
6921 'LowerEndpoint : LowerEndValue'
6924 def p_LowerEndpoint_2 (t
):
6925 'LowerEndpoint : LowerEndValue LT'
6926 t
[0] = t
[1] # but not inclusive range
6928 def p_UpperEndpoint_1 (t
):
6929 'UpperEndpoint : UpperEndValue'
6932 def p_UpperEndpoint_2 (t
):
6933 'UpperEndpoint : LT UpperEndValue'
6934 t
[0] = t
[1] # but not inclusive range
6937 def p_LowerEndValue (t
):
6938 '''LowerEndValue : Value
6942 def p_UpperEndValue (t
):
6943 '''UpperEndValue : Value
6947 # 47.5 Size constraint
6949 def p_SizeConstraint (t
):
6950 'SizeConstraint : SIZE Constraint'
6951 t
[0] = Constraint (type = 'Size', subtype
= t
[2])
6953 # 47.6 Type constraint
6955 def p_TypeConstraint (t
):
6956 'TypeConstraint : Type'
6957 t
[0] = Constraint (type = 'Type', subtype
= t
[1])
6959 # 47.7 Permitted alphabet
6961 def p_PermittedAlphabet (t
):
6962 'PermittedAlphabet : FROM Constraint'
6963 t
[0] = Constraint (type = 'From', subtype
= t
[2])
6965 # 47.8 Inner subtyping
6967 def p_InnerTypeConstraints (t
):
6968 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6969 | WITH COMPONENTS MultipleTypeConstraints'''
6970 pass # ignore PER invisible constraint
6973 def p_SingleTypeConstraint (t
):
6974 'SingleTypeConstraint : Constraint'
6978 def p_MultipleTypeConstraints (t
):
6979 '''MultipleTypeConstraints : FullSpecification
6980 | PartialSpecification'''
6983 def p_FullSpecification (t
):
6984 'FullSpecification : LBRACE TypeConstraints RBRACE'
6987 def p_PartialSpecification (t
):
6988 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6991 def p_TypeConstraints_1 (t
):
6992 'TypeConstraints : named_constraint'
6995 def p_TypeConstraints_2 (t
):
6996 'TypeConstraints : TypeConstraints COMMA named_constraint'
6997 t
[0] = t
[1] + [t
[3]]
6999 def p_named_constraint_1 (t
):
7000 'named_constraint : identifier constraint'
7001 return Node ('named_constraint', ident
= t
[1], constr
= t
[2])
7003 def p_named_constraint_2 (t
):
7004 'named_constraint : constraint'
7005 return Node ('named_constraint', constr
= t
[1])
7007 def p_constraint (t
):
7008 'constraint : value_constraint presence_constraint'
7009 t
[0] = Node ('constraint', value
= t
[1], presence
= t
[2])
7011 def p_value_constraint_1 (t
):
7012 'value_constraint : Constraint'
7015 def p_value_constraint_2 (t
):
7016 'value_constraint : '
7019 def p_presence_constraint_1 (t
):
7020 '''presence_constraint : PRESENT
7025 def p_presence_constraint_2 (t
):
7026 '''presence_constraint : '''
7029 # 47.9 Pattern constraint
7031 def p_PatternConstraint (t
):
7032 'PatternConstraint : PATTERN Value'
7033 t
[0] = Constraint (type = 'Pattern', subtype
= t
[2])
7035 # 49 The exception identifier
7038 def p_ExceptionSpec_1 (t
):
7039 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
7042 def p_ExceptionSpec_2 (t
):
7046 def p_ExceptionIdentification (t
):
7047 '''ExceptionIdentification : SignedNumber
7049 | Type COLON Value '''
7052 # /*-----------------------------------------------------------------------*/
7053 # /* Value Notation Productions */
7054 # /*-----------------------------------------------------------------------*/
7058 def p_binary_string (t
):
7059 'binary_string : BSTRING'
7060 t
[0] = BStringValue(val
= t
[1])
7062 def p_hex_string (t
):
7063 'hex_string : HSTRING'
7064 t
[0] = HStringValue(val
= t
[1])
7066 def p_char_string (t
):
7067 'char_string : QSTRING'
7075 #--- ITU-T Recommendation X.208 -----------------------------------------------
7077 # 27 Notation for the any type ------------------------------------------------
7082 | ANY DEFINED BY identifier'''
7085 #--- ITU-T Recommendation X.681 -----------------------------------------------
7087 # 7 ASN.1 lexical items -------------------------------------------------------
7089 # 7.1 Information object class references
7091 def p_objectclassreference (t
):
7092 'objectclassreference : CLASS_IDENT'
7093 t
[0] = Class_Ref(val
=t
[1])
7095 # 7.2 Information object references
7097 def p_objectreference (t
):
7098 'objectreference : LCASE_IDENT'
7101 # 7.3 Information object set references
7103 #def p_objectsetreference (t):
7104 # 'objectsetreference : UCASE_IDENT'
7107 # 7.4 Type field references
7108 # ucasefieldreference
7109 # 7.5 Value field references
7110 # lcasefieldreference
7111 # 7.6 Value set field references
7112 # ucasefieldreference
7113 # 7.7 Object field references
7114 # lcasefieldreference
7115 # 7.8 Object set field references
7116 # ucasefieldreference
7118 def p_ucasefieldreference (t
):
7119 'ucasefieldreference : AMPERSAND UCASE_IDENT'
7122 def p_lcasefieldreference (t
):
7123 'lcasefieldreference : AMPERSAND LCASE_IDENT'
7126 # 8 Referencing definitions
7129 def p_DefinedObjectClass (t
):
7130 '''DefinedObjectClass : objectclassreference
7131 | UsefulObjectClassReference'''
7134 obj_class
= t
[0].val
7136 def p_DefinedObject (t
):
7137 '''DefinedObject : objectreference'''
7141 def p_UsefulObjectClassReference (t
):
7142 '''UsefulObjectClassReference : TYPE_IDENTIFIER
7143 | ABSTRACT_SYNTAX'''
7144 t
[0] = Class_Ref(val
=t
[1])
7146 # 9 Information object class definition and assignment
7149 def p_ObjectClassAssignment (t
):
7150 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
7151 | UCASE_IDENT ASSIGNMENT ObjectClass'''
7154 if isinstance(t
[0], ObjectClassDefn
):
7158 def p_ObjectClass (t
):
7159 '''ObjectClass : DefinedObjectClass
7161 | ParameterizedObjectClass '''
7165 def p_ObjectClassDefn (t
):
7166 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
7167 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
7168 t
[0] = ObjectClassDefn(fields
= t
[3])
7170 def p_FieldSpecs_1 (t
):
7171 'FieldSpecs : FieldSpec'
7174 def p_FieldSpecs_2 (t
):
7175 'FieldSpecs : FieldSpecs COMMA FieldSpec'
7176 t
[0] = t
[1] + [t
[3]]
7178 def p_WithSyntaxSpec (t
):
7179 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
7183 def p_FieldSpec (t
):
7184 '''FieldSpec : TypeFieldSpec
7185 | FixedTypeValueFieldSpec
7186 | VariableTypeValueFieldSpec
7187 | FixedTypeValueSetFieldSpec
7189 | ObjectSetFieldSpec '''
7193 def p_TypeFieldSpec (t
):
7194 '''TypeFieldSpec : ucasefieldreference
7195 | ucasefieldreference TypeOptionalitySpec '''
7196 t
[0] = TypeFieldSpec()
7199 def p_TypeOptionalitySpec_1 (t
):
7200 'TypeOptionalitySpec ::= OPTIONAL'
7203 def p_TypeOptionalitySpec_2 (t
):
7204 'TypeOptionalitySpec ::= DEFAULT Type'
7208 def p_FixedTypeValueFieldSpec (t
):
7209 '''FixedTypeValueFieldSpec : lcasefieldreference Type
7210 | lcasefieldreference Type UNIQUE
7211 | lcasefieldreference Type ValueOptionalitySpec
7212 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
7213 t
[0] = FixedTypeValueFieldSpec(typ
= t
[2])
7216 def p_ValueOptionalitySpec_1 (t
):
7217 'ValueOptionalitySpec ::= OPTIONAL'
7220 def p_ValueOptionalitySpec_2 (t
):
7221 'ValueOptionalitySpec ::= DEFAULT Value'
7226 def p_VariableTypeValueFieldSpec (t
):
7227 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
7228 | lcasefieldreference FieldName ValueOptionalitySpec '''
7229 t
[0] = VariableTypeValueFieldSpec()
7233 def p_FixedTypeValueSetFieldSpec (t
):
7234 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
7235 | ucasefieldreference Type ValueSetOptionalitySpec '''
7236 t
[0] = FixedTypeValueSetFieldSpec()
7239 def p_ValueSetOptionalitySpec_1 (t
):
7240 'ValueSetOptionalitySpec ::= OPTIONAL'
7243 def p_ValueSetOptionalitySpec_2 (t
):
7244 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
7248 def p_ObjectFieldSpec (t
):
7249 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
7250 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
7251 t
[0] = ObjectFieldSpec(cls
=t
[2])
7256 def p_ObjectOptionalitySpec_1 (t
):
7257 'ObjectOptionalitySpec ::= OPTIONAL'
7260 def p_ObjectOptionalitySpec_2 (t
):
7261 'ObjectOptionalitySpec ::= DEFAULT Object'
7265 def p_ObjectSetFieldSpec (t
):
7266 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
7267 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
7268 t
[0] = ObjectSetFieldSpec(cls
=t
[2])
7271 def p_ObjectSetOptionalitySpec_1 (t
):
7272 'ObjectSetOptionalitySpec ::= OPTIONAL'
7275 def p_ObjectSetOptionalitySpec_2 (t
):
7276 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
7280 def p_PrimitiveFieldName (t
):
7281 '''PrimitiveFieldName : ucasefieldreference
7282 | lcasefieldreference '''
7286 def p_FieldName_1 (t
):
7287 'FieldName : PrimitiveFieldName'
7290 def p_FieldName_2 (t
):
7291 'FieldName : FieldName DOT PrimitiveFieldName'
7292 t
[0] = t
[1] + '.' + t
[3]
7294 # 11 Information object definition and assignment
7297 def p_ObjectAssignment (t
):
7298 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
7299 t
[0] = ObjectAssignment (ident
= t
[1], cls
=t
[2].val
, val
=t
[4])
7305 '''Object : DefinedObject
7307 | ParameterizedObject'''
7311 def p_ObjectDefn (t
):
7312 'ObjectDefn : lbraceobject bodyobject rbraceobject'
7315 # {...} block of object definition
7316 def p_lbraceobject(t
):
7317 'lbraceobject : braceobjectbegin LBRACE'
7320 def p_braceobjectbegin(t
):
7321 'braceobjectbegin : '
7324 if set_class_syntax(obj_class
):
7328 state
= 'braceignore'
7329 lexer
.push_state(state
)
7331 def p_rbraceobject(t
):
7332 'rbraceobject : braceobjectend RBRACE'
7335 def p_braceobjectend(t
):
7339 set_class_syntax(None)
7341 def p_bodyobject_1 (t
):
7345 def p_bodyobject_2 (t
):
7346 'bodyobject : cls_syntax_list'
7349 def p_cls_syntax_list_1 (t
):
7350 'cls_syntax_list : cls_syntax_list cls_syntax'
7354 def p_cls_syntax_list_2 (t
):
7355 'cls_syntax_list : cls_syntax'
7359 def p_cls_syntax_1 (t
):
7360 'cls_syntax : Type IDENTIFIED BY Value'
7361 t
[0] = { get_class_field(' ') : t
[1], get_class_field(' '.join((t
[2], t
[3]))) : t
[4] }
7363 def p_cls_syntax_2 (t
):
7364 'cls_syntax : HAS PROPERTY Value'
7365 t
[0] = { get_class_field(' '.join(t
[1:-1])) : t
[-1:][0] }
7368 def p_cls_syntax_3 (t
):
7369 '''cls_syntax : ERRORS ObjectSet
7371 | RETURN RESULT BooleanValue
7372 | SYNCHRONOUS BooleanValue
7373 | INVOKE PRIORITY Value
7374 | RESULT_PRIORITY Value
7376 | ALWAYS RESPONDS BooleanValue
7377 | IDEMPOTENT BooleanValue '''
7378 t
[0] = { get_class_field(' '.join(t
[1:-1])) : t
[-1:][0] }
7380 def p_cls_syntax_4 (t
):
7381 '''cls_syntax : ARGUMENT Type
7383 | PARAMETER Type '''
7384 t
[0] = { get_class_field(t
[1]) : t
[2] }
7386 def p_cls_syntax_5 (t
):
7387 'cls_syntax : CODE Value'
7388 fld
= get_class_field(t
[1])
7389 t
[0] = { fld
: t
[2] }
7390 if isinstance(t
[2], ChoiceValue
):
7391 fldt
= fld
+ '.' + t
[2].choice
7394 def p_cls_syntax_6 (t
):
7395 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
7396 | RESULT Type OPTIONAL BooleanValue
7397 | PARAMETER Type OPTIONAL BooleanValue '''
7398 t
[0] = { get_class_field(t
[1]) : t
[2], get_class_field(' '.join((t
[1], t
[3]))) : t
[4] }
7400 # 12 Information object set definition and assignment
7403 def p_ObjectSetAssignment (t
):
7404 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
7405 t
[0] = Node('ObjectSetAssignment', name
=t
[1], cls
=t
[2], val
=t
[4])
7408 def p_ObjectSet (t
):
7409 'ObjectSet : lbraceignore rbraceignore'
7412 # 14 Notation for the object class field type ---------------------------------
7415 def p_ObjectClassFieldType (t
):
7416 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
7417 t
[0] = get_type_from_class(t
[1], t
[3])
7420 def p_ObjectClassFieldValue (t
):
7421 '''ObjectClassFieldValue : OpenTypeFieldVal'''
7424 def p_OpenTypeFieldVal (t
):
7425 '''OpenTypeFieldVal : Type COLON Value
7426 | NullType COLON NullValue'''
7430 # 15 Information from objects -------------------------------------------------
7434 def p_ValueFromObject (t
):
7435 'ValueFromObject : LCASE_IDENT DOT FieldName'
7436 t
[0] = t
[1] + '.' + t
[3]
7439 # Annex C - The instance-of type ----------------------------------------------
7442 def p_InstanceOfType (t
):
7443 'InstanceOfType : INSTANCE OF DefinedObjectClass'
7444 t
[0] = InstanceOfType()
7449 useful_object_class_types
= {
7451 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
7452 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
7454 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
7455 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
7456 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
7459 object_class_types
= { }
7461 object_class_typerefs
= { }
7463 object_class_classrefs
= { }
7466 class _VariableTypeValueFieldSpec (AnyType
):
7469 class _FixedTypeValueSetFieldSpec (AnyType
):
7472 class_types_creator
= {
7473 'BooleanType' : lambda : BooleanType(),
7474 'IntegerType' : lambda : IntegerType(),
7475 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
7476 'OpenType' : lambda : OpenType(),
7478 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
7479 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
7485 'TYPE-IDENTIFIER' : {
7487 'IDENTIFIED' : 'IDENTIFIED',
7489 'IDENTIFIED BY' : '&id',
7491 'ABSTRACT-SYNTAX' : {
7493 'IDENTIFIED' : 'IDENTIFIED',
7495 'IDENTIFIED BY' : '&id',
7497 'PROPERTY' : 'PROPERTY',
7498 'HAS PROPERTY' : '&property',
7502 class_syntaxes_enabled
= {
7503 'TYPE-IDENTIFIER' : True,
7504 'ABSTRACT-SYNTAX' : True,
7508 'TYPE-IDENTIFIER' : x681_syntaxes
['TYPE-IDENTIFIER'],
7509 'ABSTRACT-SYNTAX' : x681_syntaxes
['ABSTRACT-SYNTAX'],
7512 class_current_syntax
= None
7514 def get_syntax_tokens(syntaxes
):
7516 for s
in (syntaxes
):
7517 for k
in (list(syntaxes
[s
].keys())):
7520 tokens
[k
] = tokens
[k
].replace('-', '_')
7521 return list(tokens
.values())
7523 tokens
= tokens
+ get_syntax_tokens(x681_syntaxes
)
7525 def set_class_syntax(syntax
):
7526 global class_syntaxes_enabled
7527 global class_current_syntax
7528 #print "set_class_syntax", syntax, class_current_syntax
7529 if class_syntaxes_enabled
.get(syntax
, False):
7530 class_current_syntax
= syntax
7533 class_current_syntax
= None
7536 def is_class_syntax(name
):
7537 global class_syntaxes
7538 global class_current_syntax
7539 #print "is_class_syntax", name, class_current_syntax
7540 if not class_current_syntax
:
7542 return name
in class_syntaxes
[class_current_syntax
]
7544 def get_class_field(name
):
7545 if not class_current_syntax
:
7547 return class_syntaxes
[class_current_syntax
][name
]
7549 def is_class_ident(name
):
7550 return name
in class_names
7552 def add_class_ident(name
):
7553 #print "add_class_ident", name
7554 class_names
[name
] = name
7556 def get_type_from_class(cls
, fld
):
7557 flds
= fld
.split('.')
7558 if (isinstance(cls
, Class_Ref
)):
7559 key
= cls
.val
+ '.' + flds
[0]
7561 key
= cls
+ '.' + flds
[0]
7563 if key
in object_class_classrefs
:
7564 return get_type_from_class(object_class_classrefs
[key
], '.'.join(flds
[1:]))
7566 if key
in object_class_typerefs
:
7567 return Type_Ref(val
=object_class_typerefs
[key
])
7569 creator
= lambda : AnyType()
7570 creator
= useful_object_class_types
.get(key
, creator
)
7571 creator
= object_class_types
.get(key
, creator
)
7574 def set_type_to_class(cls
, fld
, pars
):
7575 #print "set_type_to_class", cls, fld, pars
7576 key
= cls
+ '.' + fld
7577 typename
= 'OpenType'
7581 pars
.append(typename
)
7584 if (isinstance(pars
[1], Class_Ref
)):
7585 pars
[1] = pars
[1].val
7589 if key
in object_class_types
:
7590 msg
= object_class_types
[key
]().type
7591 if key
in object_class_typerefs
:
7592 msg
= "TypeReference " + object_class_typerefs
[key
]
7593 if key
in object_class_classrefs
:
7594 msg
= "ClassReference " + object_class_classrefs
[key
]
7596 if msg
== ' '.join(pars
):
7600 msg0
= "Can not define CLASS field %s as '%s'\n" % (key
, ' '.join(pars
))
7601 msg1
= "Already defined as '%s'" % (msg
)
7602 raise CompError(msg0
+ msg1
)
7604 if (typename
== 'ClassReference'):
7605 if not typeref
: return False
7606 object_class_classrefs
[key
] = typeref
7609 if (typename
== 'TypeReference'):
7610 if not typeref
: return False
7611 object_class_typerefs
[key
] = typeref
7614 creator
= class_types_creator
.get(typename
)
7616 object_class_types
[key
] = creator
7621 def import_class_from_module(mod
, cls
):
7622 add_class_ident(cls
)
7623 mcls
= "$%s$%s" % (mod
, cls
)
7624 for k
in list(object_class_classrefs
.keys()):
7625 kk
= k
.split('.', 1)
7627 object_class_classrefs
[cls
+ '.' + kk
[0]] = object_class_classrefs
[k
]
7628 for k
in list(object_class_typerefs
.keys()):
7629 kk
= k
.split('.', 1)
7631 object_class_typerefs
[cls
+ '.' + kk
[0]] = object_class_typerefs
[k
]
7632 for k
in list(object_class_types
.keys()):
7633 kk
= k
.split('.', 1)
7635 object_class_types
[cls
+ '.' + kk
[0]] = object_class_types
[k
]
7637 #--- ITU-T Recommendation X.682 -----------------------------------------------
7639 # 8 General constraint specification ------------------------------------------
7642 def p_GeneralConstraint (t
):
7643 '''GeneralConstraint : UserDefinedConstraint
7645 | ContentsConstraint'''
7648 # 9 User-defined constraints --------------------------------------------------
7651 def p_UserDefinedConstraint (t
):
7652 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7653 t
[0] = Constraint(type = 'UserDefined', subtype
= t
[4])
7655 def p_UserDefinedConstraintParameterList_1 (t
):
7656 'UserDefinedConstraintParameterList : '
7659 def p_UserDefinedConstraintParameterList_2 (t
):
7660 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7663 def p_UserDefinedConstraintParameterList_3 (t
):
7664 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7665 t
[0] = t
[1] + [t
[3]]
7668 def p_UserDefinedConstraintParameter (t
):
7669 'UserDefinedConstraintParameter : Type'
7672 # 10 Table constraints, including component relation constraints --------------
7675 def p_TableConstraint (t
):
7676 '''TableConstraint : SimpleTableConstraint
7677 | ComponentRelationConstraint'''
7678 t
[0] = Constraint(type = 'Table', subtype
= t
[1])
7680 def p_SimpleTableConstraint (t
):
7681 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7685 def p_ComponentRelationConstraint (t
):
7686 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7687 t
[0] = t
[2] + str(t
[5])
7689 def p_AtNotations_1 (t
):
7690 'AtNotations : AtNotation'
7693 def p_AtNotations_2 (t
):
7694 'AtNotations : AtNotations COMMA AtNotation'
7695 t
[0] = t
[1] + [t
[3]]
7697 def p_AtNotation_1 (t
):
7698 'AtNotation : AT ComponentIdList'
7701 def p_AtNotation_2 (t
):
7702 'AtNotation : AT DOT Level ComponentIdList'
7703 t
[0] = '@.' + t
[3] + t
[4]
7713 def p_ComponentIdList_1 (t
):
7714 'ComponentIdList : LCASE_IDENT'
7717 def p_ComponentIdList_2 (t
):
7718 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7719 t
[0] = t
[1] + '.' + t
[3]
7721 # 11 Contents constraints -----------------------------------------------------
7724 def p_ContentsConstraint (t
):
7725 'ContentsConstraint : CONTAINING type_ref'
7726 t
[0] = Constraint(type = 'Contents', subtype
= t
[2])
7729 #--- ITU-T Recommendation X.683 -----------------------------------------------
7731 # 8 Parameterized assignments -------------------------------------------------
7734 def p_ParameterizedAssignment (t
):
7735 '''ParameterizedAssignment : ParameterizedTypeAssignment
7736 | ParameterizedObjectClassAssignment
7737 | ParameterizedObjectAssignment
7738 | ParameterizedObjectSetAssignment'''
7742 def p_ParameterizedTypeAssignment (t
):
7743 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7745 t
[0].SetName(t
[1]) # t[0].SetName(t[1] + 'xxx')
7747 def p_ParameterizedObjectClassAssignment (t
):
7748 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7749 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7752 if isinstance(t
[0], ObjectClassDefn
):
7755 def p_ParameterizedObjectAssignment (t
):
7756 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7757 t
[0] = ObjectAssignment (ident
= t
[1], cls
=t
[3].val
, val
=t
[5])
7761 def p_ParameterizedObjectSetAssignment (t
):
7762 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7763 t
[0] = Node('ObjectSetAssignment', name
=t
[1], cls
=t
[3].val
, val
=t
[5])
7766 def p_ParameterList (t
):
7767 'ParameterList : lbraceignore rbraceignore'
7769 #def p_ParameterList (t):
7770 # 'ParameterList : LBRACE Parameters RBRACE'
7773 #def p_Parameters_1 (t):
7774 # 'Parameters : Parameter'
7777 #def p_Parameters_2 (t):
7778 # 'Parameters : Parameters COMMA Parameter'
7779 # t[0] = t[1] + [t[3]]
7781 #def p_Parameter_1 (t):
7782 # 'Parameter : Type COLON Reference'
7783 # t[0] = [t[1], t[3]]
7785 #def p_Parameter_2 (t):
7786 # 'Parameter : Reference'
7790 # 9 Referencing parameterized definitions -------------------------------------
7793 def p_ParameterizedReference (t
):
7794 'ParameterizedReference : Reference LBRACE RBRACE'
7799 def p_ParameterizedType (t
):
7800 'ParameterizedType : type_ref ActualParameterList'
7805 def p_ParameterizedObjectClass (t
):
7806 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7810 def p_ParameterizedObject (t
):
7811 'ParameterizedObject : DefinedObject ActualParameterList'
7816 def p_ActualParameterList (t
):
7817 'ActualParameterList : lbraceignore rbraceignore'
7819 #def p_ActualParameterList (t):
7820 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7823 #def p_ActualParameters_1 (t):
7824 # 'ActualParameters : ActualParameter'
7827 #def p_ActualParameters_2 (t):
7828 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7829 # t[0] = t[1] + [t[3]]
7831 #def p_ActualParameter (t):
7832 # '''ActualParameter : Type
7837 #--- ITU-T Recommendation X.880 -----------------------------------------------
7841 '&ArgumentType' : [],
7842 '&argumentTypeOptional' : [ 'BooleanType' ],
7843 '&returnResult' : [ 'BooleanType' ],
7845 '&resultTypeOptional' : [ 'BooleanType' ],
7846 '&Errors' : [ 'ClassReference', 'ERROR' ],
7847 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7848 '&synchronous' : [ 'BooleanType' ],
7849 '&idempotent' : [ 'BooleanType' ],
7850 '&alwaysReturns' : [ 'BooleanType' ],
7851 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7852 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7853 '&operationCode' : [ 'TypeReference', 'Code' ],
7856 '&ParameterType' : [],
7857 '¶meterTypeOptional' : [ 'BooleanType' ],
7858 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7859 '&errorCode' : [ 'TypeReference', 'Code' ],
7861 'OPERATION-PACKAGE' : {
7862 '&Both' : [ 'ClassReference', 'OPERATION' ],
7863 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7864 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7865 '&id' : [ 'ObjectIdentifierType' ],
7867 'CONNECTION-PACKAGE' : {
7868 '&bind' : [ 'ClassReference', 'OPERATION' ],
7869 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7870 '&responderCanUnbind' : [ 'BooleanType' ],
7871 '&unbindCanFail' : [ 'BooleanType' ],
7872 '&id' : [ 'ObjectIdentifierType' ],
7875 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7876 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7877 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7878 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7879 '&id' : [ 'ObjectIdentifierType' ],
7881 'ROS-OBJECT-CLASS' : {
7882 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7883 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7884 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7885 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7886 '&id' : [ 'ObjectIdentifierType' ],
7892 'ARGUMENT' : '&ArgumentType',
7893 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7894 'RESULT' : '&ResultType',
7895 'RESULT OPTIONAL' : '&resultTypeOptional',
7896 'RETURN' : 'RETURN',
7897 'RETURN RESULT' : '&returnResult',
7898 'ERRORS' : '&Errors',
7899 'LINKED' : '&Linked',
7900 'SYNCHRONOUS' : '&synchronous',
7901 'IDEMPOTENT' : '&idempotent',
7902 'ALWAYS' : 'ALWAYS',
7903 'RESPONDS' : 'RESPONDS',
7904 'ALWAYS RESPONDS' : '&alwaysReturns',
7905 'INVOKE' : 'INVOKE',
7906 'PRIORITY' : 'PRIORITY',
7907 'INVOKE PRIORITY' : '&InvokePriority',
7908 'RESULT-PRIORITY': '&ResultPriority',
7909 'CODE' : '&operationCode',
7912 'PARAMETER' : '&ParameterType',
7913 'PARAMETER OPTIONAL' : '¶meterTypeOptional',
7914 'PRIORITY' : '&ErrorPriority',
7915 'CODE' : '&errorCode',
7917 # 'OPERATION-PACKAGE' : {
7919 # 'CONNECTION-PACKAGE' : {
7923 # 'ROS-OBJECT-CLASS' : {
7927 def x880_module_begin():
7928 #print "x880_module_begin()"
7929 for name
in list(x880_classes
.keys()):
7930 add_class_ident(name
)
7932 def x880_import(name
):
7933 if name
in x880_syntaxes
:
7934 class_syntaxes_enabled
[name
] = True
7935 class_syntaxes
[name
] = x880_syntaxes
[name
]
7936 if name
in x880_classes
:
7937 add_class_ident(name
)
7938 for f
in (list(x880_classes
[name
].keys())):
7939 set_type_to_class(name
, f
, x880_classes
[name
][f
])
7941 tokens
= tokens
+ get_syntax_tokens(x880_syntaxes
)
7944 #def p_lbrace_oid(t):
7945 # 'lbrace_oid : brace_oid_begin LBRACE'
7948 #def p_brace_oid_begin(t):
7949 # 'brace_oid_begin : '
7953 #def p_rbrace_oid(t):
7954 # 'rbrace_oid : brace_oid_end RBRACE'
7957 #def p_brace_oid_end(t):
7958 # 'brace_oid_end : '
7962 # {...} block to be ignored
7963 def p_lbraceignore(t
):
7964 'lbraceignore : braceignorebegin LBRACE'
7967 def p_braceignorebegin(t
):
7968 'braceignorebegin : '
7971 lexer
.push_state('braceignore')
7973 def p_rbraceignore(t
):
7974 'rbraceignore : braceignoreend RBRACE'
7977 def p_braceignoreend(t
):
7984 raise ParseError(t
, input_file
)
7987 '''pyquote : PYQUOTE'''
7988 t
[0] = PyQuote (val
= t
[1])
7994 token
= lexer
.token ()
8000 def do_module (ast
, defined_dict
):
8001 assert (ast
.type == 'Module')
8002 ctx
= Ctx (defined_dict
)
8003 print(ast
.to_python (ctx
))
8004 print(ctx
.output_assignments ())
8005 print(ctx
.output_pyquotes ())
8007 def eth_do_module (ast
, ectx
):
8008 assert (ast
.type == 'Module')
8009 if ectx
.dbg('s'): print(ast
.str_depth(0))
8012 def testyacc(s
, fn
, defined_dict
):
8013 ast
= yacc
.parse(s
, debug
=0)
8014 time_str
= time
.strftime("%a, %d %b %Y %H:%M:%S +0000", time
.gmtime())
8015 print("""#!/usr/bin/env python
8016 # Auto-generated from %s at %s
8017 from PyZ3950 import asn1""" % (fn
, time_str
))
8019 eth_do_module (module
, defined_dict
)
8022 # Wireshark compiler
8025 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
8027 -b : BER (default is PER)
8028 -u : Unaligned (default is aligned)
8029 -p proto : Protocol name (implies -S). Default is module-name
8030 from input_file (renamed by #.MODULE if present)
8031 -o name : Output files name core (default is <proto>)
8032 -O dir : Output directory for dissector
8033 -c cnf_file : Conformance file
8034 -I path : Path for conformance file includes
8035 -e : Create conformance file for exported types
8036 -E : Just create conformance file for exported types
8037 -S : Single output for multiple modules
8038 -s template : Single file output (template is input file
8039 without .c/.h extension)
8040 -k : Keep intermediate files though single file output is used
8041 -L : Suppress #line directive from .cnf file
8042 -D dir : Directory for input_file(s) (default: '.')
8043 -C : Add check for SIZE constraints
8044 -r prefix : Remove the prefix from type names
8046 input_file(s) : Input ASN.1 file(s)
8048 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
8052 s - internal ASN.1 structure
8053 a - list of assignments
8055 c - conformance values
8056 m - list of compiled modules with dependency
8057 o - list of output files
8061 ## Used to preparse C style comments
8062 ## https://github.com/eerimoq/asn1tools/blob/master/asn1tools/parser.py#L231
8064 def ignore_comments(string
):
8065 """Ignore comments in given string by replacing them with spaces. This
8066 reduces the parsing time by roughly a factor of two.
8071 (mo
.start(), mo
.group(0))
8072 for mo
in re
.finditer(r
'(/\*|\*/|\n)', string
)
8077 multi_line_comment_depth
= 0
8079 non_comment_offset
= 0
8082 for offset
, kind
in comments
:
8083 if multi_line_comment_depth
> 0:
8085 multi_line_comment_depth
+= 1
8087 multi_line_comment_depth
-= 1
8089 if multi_line_comment_depth
== 0:
8091 chunks
.append(' ' * (offset
- start_offset
))
8092 non_comment_offset
= offset
8095 non_comment_offset
= offset
8097 multi_line_comment_depth
= 1
8098 start_offset
= offset
8099 chunks
.append(string
[non_comment_offset
:start_offset
])
8101 chunks
.append(string
[non_comment_offset
:])
8103 return ''.join(chunks
)
8112 opts
, args
= getopt
.getopt(sys
.argv
[1:], "h?d:D:buXp:qFTo:O:c:I:eESs:kLCr:")
8113 except getopt
.GetoptError
:
8114 eth_usage(); sys
.exit(2)
8116 eth_usage(); sys
.exit(2)
8121 ectx
= EthCtx(conform
, output
)
8122 ectx
.encoding
= 'per'
8123 ectx
.proto_opt
= None
8125 ectx
.tag_opt
= False
8126 ectx
.outnm_opt
= None
8131 ectx
.justexpcnf
= False
8132 ectx
.merge_modules
= False
8133 ectx
.group_by_prot
= False
8134 ectx
.conform
.last_group
= 0
8135 ectx
.conform
.suppress_line
= False
8136 ectx
.output
.outnm
= None
8137 ectx
.output
.single_file
= None
8138 ectx
.constraints_check
= False
8140 if o
in ("-h", "-?"):
8141 eth_usage(); sys
.exit(2)
8143 conf_to_read
= relpath(a
)
8145 ectx
.conform
.include_path
.append(relpath(a
))
8148 ectx
.justexpcnf
= True
8150 ectx
.srcdir
= relpath(a
)
8152 ectx
.constraints_check
= True
8154 ectx
.conform
.suppress_line
= True
8158 warnings
.warn("Command line option -X is obsolete and can be removed")
8160 warnings
.warn("Command line option -T is obsolete and can be removed")
8163 print("ASN.1 to Wireshark dissector compiler")
8166 ectx
.conform
.read(conf_to_read
)
8169 if o
in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-q", "-X", "-T"):
8170 pass # already processed
8174 ectx
.conform
.set_opt(o
, par
, "commandline", 0)
8176 (ld
, yd
, pd
) = (0, 0, 0)
8177 if ectx
.dbg('l'): ld
= 1
8178 if ectx
.dbg('y'): yd
= 1
8179 if ectx
.dbg('p'): pd
= 2
8180 lexer
= lex
.lex(debug
=ld
)
8181 parser
= yacc
.yacc(method
='LALR', debug
=yd
, outputdir
='.')
8182 parser
.defaulted_states
= {}
8183 g_conform
= ectx
.conform
8188 if (ectx
.srcdir
): fn
= ectx
.srcdir
+ '/' + fn
8189 # Read ASN.1 definition, trying one of the common encodings.
8190 data
= open(fn
, "rb").read()
8192 data
= data
.decode('utf-8')
8193 except UnicodeDecodeError:
8194 warnings
.warn_explicit(f
"Decoding {fn} as UTF-8 failed.", UnicodeWarning
, '', 0)
8196 # Py2 compat, name.translate in eth_output_hf_arr fails with unicode
8197 if not isinstance(data
, str):
8198 data
= data
.encode('utf-8')
8199 data
= ignore_comments(data
)
8200 ast
.extend(yacc
.parse(data
, lexer
=lexer
, debug
=pd
))
8202 if (ectx
.merge_modules
): # common output for all module
8205 eth_do_module(module
, ectx
)
8207 ectx
.eth_do_output()
8208 elif (ectx
.groups()): # group by protocols/group
8211 if (ectx
.group_by_prot
): # group by protocols
8213 prot
= module
.get_proto(ectx
)
8214 if prot
not in pr2gr
:
8215 pr2gr
[prot
] = len(groups
)
8217 groups
[pr2gr
[prot
]].append(module
)
8218 else: # group by groups
8223 eth_do_module(module
, ectx
)
8225 ectx
.eth_do_output()
8226 else: # output for each module
8229 eth_do_module(module
, ectx
)
8231 ectx
.eth_do_output()
8237 ectx
.conform
.dbg_print()
8238 if not ectx
.justexpcnf
:
8239 ectx
.conform
.unused_report()
8242 ectx
.output
.dbg_print()
8243 ectx
.output
.make_single_file(ectx
.conform
.suppress_line
)
8248 if sys
.version_info
[0] < 3:
8249 print("This requires Python 3")
8253 if len (sys
.argv
) == 1:
8255 s
= eval(input ('Query: '))
8258 testfn (s
, 'console', {})
8261 for fn
in sys
.argv
[1:]:
8263 testfn (f
.read (), fn
, defined_dict
)
8268 #--- BODY ---------------------------------------------------------------------
8270 if __name__
== '__main__':
8271 if (os
.path
.splitext(os
.path
.basename(sys
.argv
[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
8276 #------------------------------------------------------------------------------
8278 # Editor modelines - https://www.wireshark.org/tools/modelines.html
8280 # c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil
8281 # vi: set shiftwidth=4 tabstop=8 expandtab:
8282 # :indentSize=4:tabSize=8:noTabs=true: