#!/usr/bin/env python
#
-# competh.py
+# asn2wrs.py
# ASN.1 to Wireshark dissector compiler
# 2004 Tomas Kukosa
#
# http://www.pobox.com/~asl2/software/PyZ3950/
# (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
#
-# It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 1.6)
+# It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
# http://www.dabeaz.com/ply/
#
#
# ITU-T Recommendation X.680 (07/2002),
# Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
#
+# ITU-T Recommendation X.681 (07/2002),
+# Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
+#
# ITU-T Recommendation X.682 (07/2002),
# Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
#
# ITU-T Recommendation X.683 (07/2002),
# Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
#
+# ITU-T Recommendation X.880 (07/1994),
+# Information technology - Remote Operations: Concepts, model and notation
+#
from __future__ import nested_scopes
import os.path
import time
import getopt
+import traceback
-import __main__ # XXX blech!
import lex
import yacc
}
def asn2c(id):
- return id.replace('-', '_').replace('.', '_')
-
-class LexError(Exception): pass
-class ParseError(Exception): pass
-
+ return id.replace('-', '_').replace('.', '_').replace('&', '_')
+
+input_file = None
+g_conform = None
+lexer = None
+in_oid = False
+
+class LexError(Exception):
+ def __init__(self, tok, filename=None):
+ self.tok = tok
+ self.filename = filename
+ self.msg = "Unexpected character %r" % (self.tok.value[0])
+ Exception.__init__(self, self.msg)
+ def __repr__(self):
+ return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
+ __str__ = __repr__
+
+
+class ParseError(Exception):
+ def __init__(self, tok, filename=None):
+ self.tok = tok
+ self.filename = filename
+ self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
+ Exception.__init__(self, self.msg)
+ def __repr__(self):
+ return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
+ __str__ = __repr__
+
+
+states = (
+ ('braceignore','exclusive'),
+)
+
+precedence = (
+ ('left', 'UNION', 'BAR'),
+ ('left', 'INTERSECTION', 'CIRCUMFLEX'),
+)
# 11 ASN.1 lexical items
static_tokens = {
#r'"' : 'QUOTATION',
#r"'" : 'APOSTROPHE',
r';' : 'SEMICOLON',
- #r'@' : 'AT',
- #r'\!' : 'EXCLAMATION',
- r'\^' : 'CIRCUMFLEX'
+ r'@' : 'AT',
+ r'\!' : 'EXCLAMATION',
+ r'\^' : 'CIRCUMFLEX',
+ r'\&' : 'AMPERSAND',
+ r'\|' : 'BAR'
}
# 11.27 Reserved words
# all keys in reserved_words must start w/ upper case
reserved_words = {
- 'TAGS' : 'TAGS',
- 'BOOLEAN' : 'BOOLEAN',
- 'INTEGER' : 'INTEGER',
- 'BIT' : 'BIT',
- 'CHARACTER' : 'CHARACTER',
- 'STRING' : 'STRING',
- 'OCTET' : 'OCTET',
- 'NULL' : 'NULL',
- 'SEQUENCE': 'SEQUENCE',
- 'OF' : 'OF',
- 'SET' : 'SET',
- 'IMPLICIT': 'IMPLICIT',
- 'CHOICE' : 'CHOICE',
- 'ANY' : 'ANY',
-# 'EXTERNAL' : 'EXTERNAL', # XXX added over base
- 'OPTIONAL':'OPTIONAL',
- 'DEFAULT' : 'DEFAULT',
- 'COMPONENTS': 'COMPONENTS',
- 'UNIVERSAL' : 'UNIVERSAL',
- 'APPLICATION' : 'APPLICATION',
- 'PRIVATE' : 'PRIVATE',
- 'TRUE' : 'TRUE',
- 'FALSE' : 'FALSE',
- 'BEGIN' : 'BEGIN',
- 'END' : 'END',
- 'DEFINITIONS' : 'DEFINITIONS',
- 'EXPLICIT' : 'EXPLICIT',
- 'ENUMERATED' : 'ENUMERATED',
- 'EXPORTS' : 'EXPORTS',
- 'IMPORTS' : 'IMPORTS',
- 'REAL' : 'REAL',
- 'INCLUDES': 'INCLUDES',
- 'MIN' : 'MIN',
- 'MAX' : 'MAX',
- 'SIZE' : 'SIZE',
- 'FROM' : 'FROM',
- 'INTERSECTION' : 'INTERSECTION',
-# 'UNION' : 'UNION',
- 'PATTERN' : 'PATTERN',
- 'WITH' : 'WITH',
- 'COMPONENT': 'COMPONENT',
- 'PRESENT' : 'PRESENT',
- 'ABSENT' : 'ABSENT',
-# 'DEFINED' : 'DEFINED',
- 'CONSTRAINED' : 'CONSTRAINED',
- 'BY' : 'BY',
- 'PLUS-INFINITY' : 'PLUS_INFINITY',
- 'MINUS-INFINITY' : 'MINUS_INFINITY',
- 'GeneralizedTime' : 'GeneralizedTime',
- 'UTCTime' : 'UTCTime',
- 'ObjectDescriptor': 'ObjectDescriptor',
- 'AUTOMATIC': 'AUTOMATIC',
- 'OBJECT': 'OBJECT',
- 'IDENTIFIER': 'IDENTIFIER',
-# 'OPERATION' : 'OPERATION',
-# 'ARGUMENT' : 'ARGUMENT',
-# 'RESULT' : 'RESULT',
-# 'ERRORS' : 'ERRORS',
-# 'LINKED' : 'LINKED',
-# 'ERROR' : 'ERROR',
-# 'PARAMETER' : 'PARAMETER',
-# 'BIND' : 'BIND',
-# 'BIND-ERROR' : 'BIND_ERROR',
-# 'UNBIND' : 'UNBIND',
-# 'APPLICATION-CONTEXT' : 'AC',
-# 'APPLICATON-SERVICE-ELEMENTS' : 'ASES',
-# 'REMOTE' : 'REMOTE',
-# 'INITIATOR' : 'INITIATOR',
-# 'RESPONDER' : 'RESPONDER',
-# 'APPLICATION-SERVICE-ELEMENT' : 'ASE',
-# 'OPERATIONS' : None,
-# 'EXTENSION-ATTRIBUTE' : 'EXTENSION_ATTRIBUTE',
-# 'EXTENSIONS' : None,
-# 'CHOSEN' : None,
-# 'EXTENSION' : None,
-# 'CRITICAL': None,
-# 'FOR' : None,
-# 'SUBMISSION' : None,
-# 'DELIVERY' : None,
-# 'TRANSFER' : None,
-# 'OBJECT' : None,
-# 'PORTS' : None,
-# 'PORT' : None,
-# r'ABSTRACT\s*OPERATIONS' : 'ABSTR_OPS',
-# 'REFINE' : None,
-# 'AS' : None,
-# 'RECURRING' : None
- }
+ 'ABSENT' : 'ABSENT',
+ 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
+ 'ALL' : 'ALL',
+ 'APPLICATION' : 'APPLICATION',
+ 'AUTOMATIC' : 'AUTOMATIC',
+ 'BEGIN' : 'BEGIN',
+ 'BIT' : 'BIT',
+ 'BOOLEAN' : 'BOOLEAN',
+ 'BY' : 'BY',
+ 'CHARACTER' : 'CHARACTER',
+ 'CHOICE' : 'CHOICE',
+ 'CLASS' : 'CLASS',
+ 'COMPONENT' : 'COMPONENT',
+ 'COMPONENTS' : 'COMPONENTS',
+ 'CONSTRAINED' : 'CONSTRAINED',
+ 'CONTAINING' : 'CONTAINING',
+ 'DEFAULT' : 'DEFAULT',
+ 'DEFINITIONS' : 'DEFINITIONS',
+ 'EMBEDDED' : 'EMBEDDED',
+# 'ENCODED' : 'ENCODED',
+ 'END' : 'END',
+ 'ENUMERATED' : 'ENUMERATED',
+# 'EXCEPT' : 'EXCEPT',
+ 'EXPLICIT' : 'EXPLICIT',
+ 'EXPORTS' : 'EXPORTS',
+# 'EXTENSIBILITY' : 'EXTENSIBILITY',
+ 'EXTERNAL' : 'EXTERNAL',
+ 'FALSE' : 'FALSE',
+ 'FROM' : 'FROM',
+ 'GeneralizedTime' : 'GeneralizedTime',
+ 'IDENTIFIER' : 'IDENTIFIER',
+ 'IMPLICIT' : 'IMPLICIT',
+# 'IMPLIED' : 'IMPLIED',
+ 'IMPORTS' : 'IMPORTS',
+ 'INCLUDES' : 'INCLUDES',
+ 'INSTANCE' : 'INSTANCE',
+ 'INTEGER' : 'INTEGER',
+ 'INTERSECTION' : 'INTERSECTION',
+ 'MAX' : 'MAX',
+ 'MIN' : 'MIN',
+ 'MINUS-INFINITY' : 'MINUS_INFINITY',
+ 'NULL' : 'NULL',
+ 'OBJECT' : 'OBJECT',
+ 'ObjectDescriptor' : 'ObjectDescriptor',
+ 'OCTET' : 'OCTET',
+ 'OF' : 'OF',
+ 'OPTIONAL' : 'OPTIONAL',
+ 'PATTERN' : 'PATTERN',
+ 'PDV' : 'PDV',
+ 'PLUS-INFINITY' : 'PLUS_INFINITY',
+ 'PRESENT' : 'PRESENT',
+ 'PRIVATE' : 'PRIVATE',
+ 'REAL' : 'REAL',
+# 'RELATIVE-OID' : 'RELATIVE-OID',
+ 'SEQUENCE' : 'SEQUENCE',
+ 'SET' : 'SET',
+ 'SIZE' : 'SIZE',
+ 'STRING' : 'STRING',
+ 'SYNTAX' : 'SYNTAX',
+ 'TAGS' : 'TAGS',
+ 'TRUE' : 'TRUE',
+ 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
+ 'UNION' : 'UNION',
+ 'UNIQUE' : 'UNIQUE',
+ 'UNIVERSAL' : 'UNIVERSAL',
+ 'UTCTime' : 'UTCTime',
+ 'WITH' : 'WITH',
+# obsolete but still used
+ 'ANY' : 'ANY',
+}
-for k in static_tokens.keys ():
- if static_tokens [k] == None:
- static_tokens [k] = k
+for k in static_tokens.keys():
+ if static_tokens [k] == None:
+ static_tokens [k] = k
StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
tokens = static_tokens.values() \
+ reserved_words.values() \
+ ['BSTRING', 'HSTRING', 'QSTRING',
- 'UCASE_IDENT', 'LCASE_IDENT',
- 'NUMBER', 'PYQUOTE']
+ 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
+ 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
+cur_mod = __import__ (__name__) # XXX blech!
+
for (k, v) in static_tokens.items ():
- __main__.__dict__['t_' + v] = k
+ cur_mod.__dict__['t_' + v] = k
# 11.10 Binary strings
def t_BSTRING (t):
def t_QSTRING (t):
r'"([^"]|"")*"'
- return t # XXX might want to un-""
+ return t
def t_UCASE_IDENT (t):
r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
- t.type = reserved_words.get(t.value, "UCASE_IDENT")
+ if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
+ if (is_class_syntax(t.value)): t.type = t.value
+ t.type = reserved_words.get(t.value, t.type)
return t
+lcase_ident_assigned = {}
def t_LCASE_IDENT (t):
r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
+ if (not in_oid and lcase_ident_assigned.has_key(t.value)): t.type = 'LCASE_IDENT_ASSIGNED'
+ return t
+
+# 11.9 Real numbers
+def t_REAL_NUMBER (t):
+ r"[0-9]+\.[0-9]*(?!\.)"
return t
# 11.8 Numbers
r"0|([1-9][0-9]*)"
return t
-# 11.9 Real numbers
-# not supported yet
-
# 11.6 Comments
pyquote_str = 'PYQUOTE'
def t_COMMENT(t):
r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
- if (t.value.find("\n") >= 0) : t.lineno += 1
+ if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
if t.value[2:2+len (pyquote_str)] == pyquote_str:
t.value = t.value[2+len(pyquote_str):]
t.value = t.value.lstrip ()
def t_NEWLINE(t):
r'\n+'
- t.lineno += t.value.count("\n")
+ t.lexer.lineno += t.value.count("\n")
def t_error(t):
- print "Error", t.value[:100], t.lineno
- raise LexError
+ global input_file
+ raise LexError(t, input_file)
-
+# state 'braceignore'
+
+def t_braceignore_lbrace(t):
+ r'\{'
+ t.lexer.level +=1
+
+def t_braceignore_rbrace(t):
+ r'\}'
+ t.lexer.level -=1
+ # If closing brace, return token
+ if t.lexer.level == 0:
+ t.type = 'RBRACE'
+ return t
+
+def t_braceignore_QSTRING (t):
+ r'"([^"]|"")*"'
+ t.lexer.lineno += t.value.count("\n")
+
+def t_braceignore_COMMENT(t):
+ r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
+ if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
+
+def t_braceignore_nonspace(t):
+ r'[^\s\{\}\"-]+|-(?!-)'
+
+t_braceignore_ignore = " \t\r"
+
+def t_braceignore_NEWLINE(t):
+ r'\n+'
+ t.lexer.lineno += t.value.count("\n")
+
+def t_braceignore_error(t):
+ t.lexer.skip(1)
class Ctx:
def __init__ (self, defined_dict, indent = 0):
self.name_ctr += 1
return "_compiler_generated_name_%d" % (self.name_ctr,)
+#--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
+EF_TYPE = 0x0001
+EF_VALS = 0x0002
+EF_ENUM = 0x0004
+EF_WS_VAR = 0x0010
+EF_EXTERN = 0x0020
+EF_NO_PROT = 0x0040
+EF_NO_TYPE = 0x0080
+EF_UCASE = 0x0100
+EF_TABLE = 0x0400
+EF_DEFINE = 0x0800
+
+#--- common dependency computation ---
+# Input : list of items
+# dictionary with lists of dependency
+#
+#
+# Output : list of two outputs:
+# [0] list of items in dependency
+# [1] list of cycle dependency cycles
+def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False):
+ item_ord = []
+ item_cyc = []
+ x = {} # already emitted
+ #print '# Dependency computation'
+ for t in items:
+ if x.has_key(map_fn(t)):
+ #print 'Continue: %s : %s' % (t, (map_fn(t))
+ continue
+ stack = [t]
+ stackx = {t : dependency.get(t, [])[:]}
+ #print 'Push: %s : %s' % (t, str(stackx[t]))
+ while stack:
+ if stackx[stack[-1]]: # has dependencies
+ d = stackx[stack[-1]].pop(0)
+ if x.has_key(map_fn(d)) or ignore_fn(d):
+ continue
+ if stackx.has_key(d): # cyclic dependency
+ c = stack[:]
+ c.reverse()
+ c = [d] + c[0:c.index(d)+1]
+ c.reverse()
+ item_cyc.append(c)
+ #print 'Cyclic: %s ' % (' -> '.join(c))
+ continue
+ stack.append(d)
+ stackx[d] = dependency.get(d, [])[:]
+ #print 'Push: %s : %s' % (d, str(stackx[d]))
+ else:
+ #print 'Pop: %s' % (stack[-1])
+ del stackx[stack[-1]]
+ e = map_fn(stack.pop())
+ if x.has_key(e):
+ continue
+ #print 'Add: %s' % (e)
+ item_ord.append(e)
+ x[e] = True
+ return (item_ord, item_cyc)
+
#--- EthCtx -------------------------------------------------------------------
class EthCtx:
def __init__(self, conform, output, indent = 0):
self.conform = conform
self.output = output
+ self.conform.ectx = self
+ self.output.ectx = self
+ self.encoding = 'per'
+ self.aligned = False
+ self.new_ber = False
+ self.default_oid_variant = ''
+ self.default_opentype_variant = ''
+ self.default_containing_variant = '_pdu_new'
+ self.default_embedded_pdv_cb = None
+ self.default_external_type_cb = None
+ self.emitted_pdu = {}
+ self.module = {}
+ self.module_ord = []
+ self.all_type_attr = {}
+ self.all_tags = {}
+ self.all_vals = {}
def encp(self): # encoding protocol
encp = self.encoding
# Encoding
def Per(self): return self.encoding == 'per'
def Ber(self): return self.encoding == 'ber'
+ def NewBer(self): return self.new_ber
def Aligned(self): return self.aligned
def Unaligned(self): return not self.aligned
+ def Fld(self, tnm='*'): return self.fld_opt.get('*', False) or self.fld_opt.get(tnm, False) or (self.Ber() and not self.NewBer())
+ def Tag(self): return self.tag_opt # or self.Ber() - temporary comment out (experimental feature)
def NAPI(self): return False # disable planned features
+ def Module(self): # current module name
+ return self.modules[-1][0]
+
+ def groups(self):
+ return self.group_by_prot or (self.conform.last_group > 0)
+
def dbg(self, d):
if (self.dbgopt.find(d) >= 0):
return True
else:
return False
+ def value_max(self, a, b):
+ if (a == 'MAX') or (b == 'MAX'): return 'MAX';
+ if a == 'MIN': return b;
+ if b == 'MIN': return a;
+ try:
+ if (int(a) > int(b)):
+ return a
+ else:
+ return b
+ except (ValueError, TypeError):
+ pass
+ return "MAX((%s),(%s))" % (a, b)
+
+ def value_min(self, a, b):
+ if (a == 'MIN') or (b == 'MIN'): return 'MIN';
+ if a == 'MAX': return b;
+ if b == 'MAX': return a;
+ try:
+ if (int(a) < int(b)):
+ return a
+ else:
+ return b
+ except (ValueError, TypeError):
+ pass
+ return "MIN((%s),(%s))" % (a, b)
+
+ def value_get_eth(self, val):
+ if isinstance(val, Value):
+ return val.to_str(self)
+ ethname = val
+ if self.value.has_key(val):
+ ethname = self.value[val]['ethname']
+ return ethname
+
+ def value_get_val(self, nm):
+ val = asn2c(nm)
+ if self.value.has_key(nm):
+ if self.value[nm]['import']:
+ v = self.get_val_from_all(nm, self.value[nm]['import'])
+ if v is None:
+ msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto'])
+ warnings.warn_explicit(msg, UserWarning, '', '')
+ else:
+ val = v
+ else:
+ val = self.value[nm]['value']
+ if isinstance (val, Value):
+ val = val.to_str(self)
+ else:
+ msg = 'Need value of unknown value identifier %s' % (nm)
+ warnings.warn_explicit(msg, UserWarning, '', '')
+ return val
+
def eth_get_type_attr(self, type):
types = [type]
while (not self.type[type]['import']
attr = {}
while len(types):
t = types.pop()
- attr.update(self.type[t]['attr'])
- attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
+ if (self.type[t]['import']):
+ attr.update(self.type[t]['attr'])
+ attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import']))
+ elif (self.type[t]['val'].type == 'SelectionType'):
+ val = self.type[t]['val']
+ (ftype, display) = val.eth_ftype(self)
+ attr.update({ 'TYPE' : ftype, 'DISPLAY' : display,
+ 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' });
+ else:
+ attr.update(self.type[t]['attr'])
+ attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
+ return attr
+
+ def eth_get_type_attr_from_all(self, type, module):
+ attr = {}
+ if self.all_type_attr.has_key(module) and self.all_type_attr[module].has_key(type):
+ attr = self.all_type_attr[module][type]
return attr
+ def get_ttag_from_all(self, type, module):
+ ttag = None
+ if self.all_tags.has_key(module) and self.all_tags[module].has_key(type):
+ ttag = self.all_tags[module][type]
+ return ttag
+
+ def get_val_from_all(self, nm, module):
+ val = None
+ if self.all_vals.has_key(module) and self.all_vals[module].has_key(nm):
+ val = self.all_vals[module][nm]
+ return val
+
+ def get_obj_repr(self, ident, restr):
+ def set_type_fn(cls, field, fnfield):
+ obj[fnfield + '_fn'] = 'NULL'
+ obj[fnfield + '_pdu'] = 'NULL'
+ if val.has_key(field) and isinstance(val[field], Type_Ref):
+ p = val[field].eth_type_default_pars(self, '')
+ obj[fnfield + '_fn'] = p['TYPE_REF_FN']
+ obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration
+ if (self.conform.check_item('PDU', cls + '.' + field)):
+ obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname']
+ return
+ # end of get_type_fn()
+ obj = { '_name' : ident, '_ident' : asn2c(ident)}
+ obj['_class'] = self.oassign[ident].cls
+ val = self.oassign[ident].val
+ fld = None
+ fld_neg = False
+ if len(restr) > 0:
+ fld = restr[0]
+ if fld[0] == '!':
+ fld_neg = True
+ fld = fld[1:]
+ if fld:
+ if fld_neg:
+ if val.has_key(fld):
+ return None
+ else:
+ if not val.has_key(fld):
+ return None
+ for f in val.keys():
+ if isinstance(val[f], Node):
+ obj[f] = val[f].fld_obj_repr(self)
+ else:
+ obj[f] = str(val[f])
+ if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'):
+ set_type_fn(obj['_class'], '&Type', '_type')
+ if (obj['_class'] == 'OPERATION'):
+ set_type_fn(obj['_class'], '&ArgumentType', '_argument')
+ set_type_fn(obj['_class'], '&ResultType', '_result')
+ if (obj['_class'] == 'ERROR'):
+ set_type_fn(obj['_class'], '&ParameterType', '_parameter')
+ return obj
+
+ #--- eth_reg_module -----------------------------------------------------------
+ def eth_reg_module(self, module):
+ #print "eth_reg_module(module='%s')" % (module)
+ name = module.get_name()
+ self.modules.append([name, module.get_proto(self)])
+ if self.module.has_key(name):
+ raise "Duplicate module for " + name
+ self.module[name] = []
+ self.module_ord.append(name)
+
+ #--- eth_module_dep_add ------------------------------------------------------------
+ def eth_module_dep_add(self, module, dep):
+ self.module[module].append(dep)
+
+ #--- eth_exports ------------------------------------------------------------
+ def eth_exports(self, exports):
+ self.exports_all = False
+ if ((len(exports) == 1) and (exports[0] == 'ALL')):
+ self.exports_all = True
+ return
+ for e in (exports):
+ if isinstance(e, Type_Ref):
+ self.exports.append(e.val)
+ elif isinstance(e, Class_Ref):
+ self.cexports.append(e.val)
+ else:
+ self.vexports.append(e)
+
#--- eth_reg_assign ---------------------------------------------------------
- def eth_reg_assign(self, ident, val):
+ def eth_reg_assign(self, ident, val, virt=False):
#print "eth_reg_assign(ident='%s')" % (ident)
if self.assign.has_key(ident):
raise "Duplicate assignment for " + ident
- self.assign[ident] = val
+ self.assign[ident] = { 'val' : val , 'virt' : virt }
self.assign_ord.append(ident)
+ if (self.exports_all):
+ self.exports.append(ident)
#--- eth_reg_vassign --------------------------------------------------------
def eth_reg_vassign(self, vassign):
raise "Duplicate value assignment for " + ident
self.vassign[ident] = vassign
self.vassign_ord.append(ident)
+ if (self.exports_all):
+ self.vexports.append(ident)
+
+ #--- eth_reg_oassign --------------------------------------------------------
+ def eth_reg_oassign(self, oassign):
+ ident = oassign.ident
+ #print "eth_reg_oassign(ident='%s')" % (ident)
+ if self.oassign.has_key(ident):
+ if self.oassign[ident] == oassign:
+ return # OK - already defined
+ else:
+ raise "Duplicate information object assignment for " + ident
+ self.oassign[ident] = oassign
+ self.oassign_ord.append(ident)
+ self.oassign_cls.setdefault(oassign.cls, []).append(ident)
#--- eth_import_type --------------------------------------------------------
def eth_import_type(self, ident, mod, proto):
- #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
+ #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
if self.type.has_key(ident):
- raise "Duplicate type for " + ident
+ #print "already defined import=%s, module=%s" % (str(self.type[ident]['import']), self.type[ident]['module'])
+ if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
+ return # OK - already defined
+ elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
+ return # OK - already imported
+ else:
+ raise "Duplicate type for " + ident
self.type[ident] = {'import' : mod, 'proto' : proto,
'ethname' : '' }
self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
self.type_imp.append(ident)
+ #--- dummy_import_type --------------------------------------------------------
+ def dummy_import_type(self, ident):
+ # dummy imported
+ if self.type.has_key(ident):
+ raise "Try to dummy import for existing type :" + ident
+ ethtype = asn2c(ident)
+ self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
+ 'ethname' : ethtype }
+ self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
+ 'STRINGS' : 'NULL', 'BITMASK' : '0' }
+ self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'create_field' : False, 'ref' : []}
+ print "Dummy imported: %s (%s)" % (ident, ethtype)
+ return ethtype
+
+ #--- eth_import_class --------------------------------------------------------
+ def eth_import_class(self, ident, mod, proto):
+ #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
+ if self.objectclass.has_key(ident):
+ #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
+ if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
+ return # OK - already defined
+ elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
+ return # OK - already imported
+ else:
+ raise "Duplicate object class for " + ident
+ self.objectclass[ident] = {'import' : mod, 'proto' : proto,
+ 'ethname' : '' }
+ self.objectclass_imp.append(ident)
+
#--- eth_import_value -------------------------------------------------------
def eth_import_value(self, ident, mod, proto):
#print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
- if self.type.has_key(ident):
- raise "Duplicate value for " + ident
+ if self.value.has_key(ident):
+ #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
+ if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) :
+ return # OK - already defined
+ elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) :
+ return # OK - already imported
+ else:
+ raise "Duplicate value for " + ident
self.value[ident] = {'import' : mod, 'proto' : proto,
'ethname' : ''}
self.value_imp.append(ident)
+ #--- eth_sel_req ------------------------------------------------------------
+ def eth_sel_req(self, typ, sel):
+ key = typ + '.' + sel
+ if not self.sel_req.has_key(key):
+ self.sel_req[key] = { 'typ' : typ , 'sel' : sel}
+ self.sel_req_ord.append(key)
+ return key
+
+ #--- eth_comp_req ------------------------------------------------------------
+ def eth_comp_req(self, type):
+ self.comp_req_ord.append(type)
+
#--- eth_dep_add ------------------------------------------------------------
def eth_dep_add(self, type, dep):
- if self.type_dep.has_key(type):
- self.type_dep[type].append(dep)
- else:
- self.type_dep[type] = [dep]
+ if not self.type_dep.has_key(type):
+ self.type_dep[type] = []
+ self.type_dep[type].append(dep)
#--- eth_reg_type -----------------------------------------------------------
def eth_reg_type(self, ident, val):
- #print "eth_reg_type(ident='%s')" % (ident)
+ #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
if self.type.has_key(ident):
- raise "Duplicate type for " + ident
+ if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) :
+ # replace imported type
+ del self.type[ident]
+ self.type_imp.remove(ident)
+ else:
+ raise "Duplicate type for " + ident
self.type[ident] = { 'val' : val, 'import' : None }
+ self.type[ident]['module'] = self.Module()
+ self.type[ident]['proto'] = self.proto
if len(ident.split('/')) > 1:
self.type[ident]['tname'] = val.eth_tname()
else:
self.type[ident]['tname'] = asn2c(ident)
self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
+ self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
self.type[ident]['ethname'] = ''
- if val.type == 'Type_Ref':
+ if (val.type == 'Type_Ref') or (val.type == 'SelectionType') :
self.type[ident]['attr'] = {}
else:
(ftype, display) = val.eth_ftype(self)
'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
self.type_ord.append(ident)
+ # PDU
+ if (self.conform.check_item('PDU', ident)):
+ self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident))
+
+ #--- eth_reg_objectclass ----------------------------------------------------------
+ def eth_reg_objectclass(self, ident, val):
+ #print "eth_reg_objectclass(ident='%s')" % (ident)
+ if self.objectclass.has_key(ident):
+ if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) :
+ # replace imported object class
+ del self.objectclass[ident]
+ self.objectclass_imp.remove(ident)
+ elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \
+ isinstance(val, Class_Ref) and \
+ (self.objectclass[ident]['val'].val == val.val):
+ pass # ignore duplicated CLASS1 ::= CLASS2
+ else:
+ raise "Duplicate object class for " + ident
+ self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto }
+ self.objectclass[ident]['val'] = val
+ self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident)
+ self.objectclass_ord.append(ident)
#--- eth_reg_value ----------------------------------------------------------
- def eth_reg_value(self, ident, type, value):
+ def eth_reg_value(self, ident, type, value, ethname=None):
#print "eth_reg_value(ident='%s')" % (ident)
if self.value.has_key(ident):
- raise "Duplicate value for " + ident
- self.value[ident] = { 'import' : None, 'proto' : self.proto,
- 'type' : type, 'value' : value }
+ if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) :
+ # replace imported value
+ del self.value[ident]
+ self.value_imp.remove(ident)
+ elif ethname:
+ self.value[ident]['ethname'] = ethname
+ return
+ else:
+ raise "Duplicate value for " + ident
+ self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto,
+ 'type' : type, 'value' : value,
+ 'no_emit' : False }
self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
self.value[ident]['ethname'] = ''
+ if (ethname): self.value[ident]['ethname'] = ethname
self.value_ord.append(ident)
#--- eth_reg_field ----------------------------------------------------------
def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
#print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
if self.field.has_key(ident):
- raise "Duplicate field for " + ident
+ if pdu and (type == self.field[ident]['type']):
+ pass # OK already created PDU
+ else:
+ raise "Duplicate field for " + ident
self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
- 'modified' : '', 'attr' : {} }
+ 'modified' : '', 'attr' : {} , 'create_field' : False }
name = ident.split('/')[-1]
if len(ident.split('/')) > 1 and name == '_item': # Sequnce/Set of type
self.field[ident]['attr']['NAME'] = '"Item"'
self.pdu_ord.append(ident)
else:
self.field_ord.append(ident)
- if parent: self.eth_dep_add(parent, type)
+ if parent:
+ self.field[ident]['create_field'] = self.Fld(parent)
+ self.eth_dep_add(parent, type)
#--- eth_clean --------------------------------------------------------------
def eth_clean(self):
self.type_ord = []
self.type_imp = []
self.type_dep = {}
+ self.sel_req = {}
+ self.sel_req_ord = []
+ self.comp_req_ord = []
self.vassign = {}
self.vassign_ord = []
self.value = {}
self.value_ord = []
self.value_imp = []
+ self.objectclass = {}
+ self.objectclass_ord = []
+ self.objectclass_imp = []
+ self.oassign = {}
+ self.oassign_ord = []
+ self.oassign_cls = {}
#--- Modules ------------
self.modules = []
+ self.exports_all = False
+ self.exports = []
+ self.cexports = []
+ self.vexports = []
#--- types -------------------
self.eth_type = {}
self.eth_type_ord = []
self.eth_reg_type('_dummy/'+nm, NullType())
self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
+ #--- required PDUs ----------------------------
+ for t in self.type_ord:
+ pdu = self.type[t]['val'].eth_need_pdu(self)
+ if not pdu: continue
+ f = pdu['type']
+ pdu['reg'] = None
+ pdu['hidden'] = False
+ pdu['need_decl'] = True
+ if not self.field.has_key(f):
+ self.eth_reg_field(f, f, pdu=pdu)
+
+ #--- values -> named values -------------------
+ t_for_update = {}
+ for v in self.value_ord:
+ if (self.value[v]['type'].type == 'Type_Ref'):
+ tnm = self.value[v]['type'].val
+ if self.type.has_key(tnm) \
+ and not self.type[tnm]['import'] \
+ and (self.type[tnm]['val'].type == 'IntegerType'):
+ self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
+ self.value[v]['no_emit'] = True
+ t_for_update[tnm] = True
+ for t in t_for_update.keys():
+ self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
+ self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
+
+ #--- required components of ---------------------------
+ #print "self.comp_req_ord = ", self.comp_req_ord
+ for t in self.comp_req_ord:
+ self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
+
+ #--- required selection types ---------------------------
+ #print "self.sel_req_ord = ", self.sel_req_ord
+ for t in self.sel_req_ord:
+ tt = self.sel_req[t]['typ']
+ if not self.type.has_key(tt):
+ self.dummy_import_type(t)
+ elif self.type[tt]['import']:
+ self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
+ else:
+ self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
+
#--- types -------------------
for t in self.type_imp:
nm = asn2c(t)
self.eth_type[nm] = { 'import' : self.type[t]['import'],
'proto' : asn2c(self.type[t]['proto']),
- 'attr' : {}, 'ref' : []}
+ 'attr' : {}, 'create_field' : False, 'ref' : []}
+ self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
self.type[t]['ethname'] = nm
for t in self.type_ord:
nm = self.type[t]['tname']
not self.conform.check_item('TYPE_RENAME', t))):
if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequnce of type at the 1st level
nm = t.split('/')[0] + t.split('/')[1]
- elif t.split('/')[-1] == '_item': # Sequnce of type at next levels
- nm = 'T_' + t.split('/')[-2] + t.split('/')[-1]
+ elif t.split('/')[-1] == '_item': # Sequnce/Set of type at next levels
+ nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
+ elif t.split('/')[-1] == '_untag': # Untagged type
+ nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
else:
- nm = 'T_' + t.split('/')[-1]
+ nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
nm = asn2c(nm)
if self.eth_type.has_key(nm):
if self.eth_type_dupl.has_key(nm):
self.eth_type_dupl[nm].append(t)
else:
self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
- nm += str(len(self.eth_type_dupl[nm])-1)
+ nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
if self.eth_type.has_key(nm):
self.eth_type[nm]['ref'].append(t)
else:
self.eth_type_ord.append(nm)
- self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0,
- 'user_def' : 0x03, 'no_emit' : 0x03,
+ self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
+ 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
'val' : self.type[t]['val'],
'attr' : {},
- 'ref' : [t]}
- self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
+ 'create_field' : False, 'ref' : [t]}
self.type[t]['ethname'] = nm
if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
self.eth_export_ord.append(nm)
self.eth_type[nm]['export'] |= self.type[t]['export']
+ self.eth_type[nm]['enum'] |= self.type[t]['enum']
self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
if self.type[t]['attr'].get('STRINGS') == '$$':
self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
+ self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
for t in self.eth_type_ord:
bits = self.eth_type[t]['val'].eth_named_bits()
if (bits):
else:
self.eth_type[t]['tree'] = None
+ #--- register values from enums ------------
+ for t in self.eth_type_ord:
+ if (self.eth_type[t]['val'].eth_has_enum(t, self)):
+ self.eth_type[t]['val'].reg_enum_vals(t, self)
+
#--- value dependencies -------------------
for v in self.value_ord:
if isinstance (self.value[v]['value'], Value):
d = deparr.pop()
if not self.value[d]['import']:
if not self.value[d]['export']:
- self.value[d]['export'] = 0x01
+ self.value[d]['export'] = EF_TYPE
deparr.extend(self.value_dep.get(d, []))
#--- values -------------------
'ref' : []}
self.value[v]['ethname'] = nm
for v in self.value_ord:
+ if (self.value[v]['ethname']):
+ continue
+ if (self.value[v]['no_emit']):
+ continue
nm = asn2c(v)
self.eth_value[nm] = { 'import' : None,
'proto' : asn2c(self.value[v]['proto']),
'export' : self.value[v]['export'], 'ref' : [v] }
- if isinstance (self.value[v]['value'], Value):
- self.eth_value[nm]['value'] = self.value[v]['value'].to_str()
- else:
- self.eth_value[nm]['value'] = self.value[v]['value']
+ self.eth_value[nm]['value'] = self.value[v]['value']
self.eth_value_ord.append(nm)
self.value[v]['ethname'] = nm
#--- fields -------------------------
for f in (self.pdu_ord + self.field_ord):
if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequnce/Set of type
- nm = f.split('/')[-2] + f.split('/')[-1]
+ nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
else:
nm = f.split('/')[-1]
nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
nm = asn2c(nm)
if (self.field[f]['pdu']):
nm += '_PDU'
+ if (not self.merge_modules):
+ nm = self.eproto + '_' + nm
t = self.field[f]['type']
if self.type.has_key(t):
ethtype = self.type[t]['ethname']
else: # undefined type
- # dummy imported
- print "Dummy imported: ", t
- self.type[t] = {'import' : 'xxx', 'proto' : 'xxx',
- 'ethname' : t }
- self.type[t]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
- 'STRINGS' : 'NULL', 'BITMASK' : '0' }
- self.eth_type[t] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
- ethtype = t
+ ethtype = self.dummy_import_type(t)
ethtypemod = ethtype + self.field[f]['modified']
if self.eth_hf.has_key(nm):
if self.eth_hf_dupl.has_key(nm):
if self.eth_hf_dupl[nm].has_key(ethtypemod):
nm = self.eth_hf_dupl[nm][ethtypemod]
+ self.eth_hf[nm]['create_field'] = self.eth_hf[nm]['create_field'] or self.field[f]['create_field']
self.eth_hf[nm]['ref'].append(f)
self.field[f]['ethname'] = nm
+ self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
continue
else:
- nmx = nm + str(len(self.eth_hf_dupl[nm]))
+ nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
self.eth_hf_dupl[nm][ethtype] = nmx
nm = nmx
else:
if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
+ self.eth_hf[nm]['create_field'] = self.eth_hf[nm]['create_field'] or self.field[f]['create_field']
self.eth_hf[nm]['ref'].append(f)
self.field[f]['ethname'] = nm
+ self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
continue
else:
+ nmx = nm + '_01'
self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
- ethtypemod : nm+'1'}
- nm += '1'
+ ethtypemod : nmx}
+ nm = nmx
if (self.field[f]['pdu']):
self.eth_hfpdu_ord.append(nm)
else:
self.eth_hf_ord.append(nm)
- fullname = "hf_%s_%s" % (self.eproto, nm)
+ fullname = 'hf_%s_%s' % (self.eproto, nm)
attr = self.eth_get_type_attr(self.field[f]['type']).copy()
attr.update(self.field[f]['attr'])
if (self.NAPI() and attr.has_key('NAME')):
attr.update(self.conform.use_item('EFIELD_ATTR', nm))
self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
- 'attr' : attr.copy(), 'ref' : [f]}
+ 'attr' : attr.copy(),
+ 'create_field' : self.field[f]['create_field'],
+ 'ref' : [f]}
self.field[f]['ethname'] = nm
+ self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
#--- type dependencies -------------------
- x = {} # already emitted
- #print '# Dependency computation'
- for t in self.type_ord:
- if x.has_key(self.type[t]['ethname']):
- #print 'Continue: %s : %s' % (t, self.type[t]['ethname'])
- continue
- stack = [t]
- stackx = {t : self.type_dep.get(t, [])[:]}
- #print 'Push: %s : %s' % (t, str(stackx[t]))
- while stack:
- if stackx[stack[-1]]: # has dependencies
- d = stackx[stack[-1]].pop(0)
- if x.has_key(self.type[d]['ethname']) or self.type[d]['import']:
- continue
- if stackx.has_key(d): # cyclic dependency
- c = stack[:]
- c.reverse()
- c = [d] + c[0:c.index(d)+1]
- c.reverse()
- self.eth_dep_cycle.append(c)
- #print 'Cyclic: %s ' % (' -> '.join(c))
- continue
- stack.append(d)
- stackx[d] = self.type_dep.get(d, [])[:]
- #print 'Push: %s : %s' % (d, str(stackx[d]))
- else:
- #print 'Pop: %s' % (stack[-1])
- del stackx[stack[-1]]
- e = self.type[stack.pop()]['ethname']
- if x.has_key(e):
- continue
- #print 'Add: %s' % (e)
- self.eth_type_ord1.append(e)
- x[e] = True
+ (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'])
i = 0
while i < len(self.eth_dep_cycle):
t = self.type[self.eth_dep_cycle[i][0]]['ethname']
else:
self.eth_value_ord1.append(v)
+ #--- export tags, values, ... ---
+ for t in self.exports:
+ if not self.type.has_key(t):
+ continue
+ if self.type[t]['import']:
+ continue
+ m = self.type[t]['module']
+ if not self.all_tags.has_key(m):
+ self.all_tags[m] = {}
+ self.all_tags[m][t] = self.type[t]['val'].GetTTag(self)
+ if not self.all_type_attr.has_key(m):
+ self.all_type_attr[m] = {}
+ self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy()
+ for v in self.vexports:
+ if not self.value.has_key(v):
+ continue
+ if self.value[v]['import']:
+ continue
+ m = self.value[v]['module']
+ if not self.all_vals.has_key(m):
+ self.all_vals[m] = {}
+ vv = self.value[v]['value']
+ if isinstance (vv, Value):
+ vv = vv.to_str(self)
+ self.all_vals[m][v] = vv
+
#--- eth_vals_nm ------------------------------------------------------------
def eth_vals_nm(self, tname):
out = ""
- if (not self.eth_type[tname]['export'] & 0x10):
+ if (not self.eth_type[tname]['export'] & EF_NO_PROT):
out += "%s_" % (self.eproto)
out += "%s_vals" % (tname)
return out
#--- eth_vals ---------------------------------------------------------------
def eth_vals(self, tname, vals):
out = ""
- if (not self.eth_type[tname]['export'] & 0x02):
+ has_enum = self.eth_type[tname]['enum'] & EF_ENUM
+ if (not self.eth_type[tname]['export'] & EF_VALS):
+ out += "static "
+ if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
out += "static "
out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
for (val, id) in vals:
- out += ' { %3s, "%s" },\n' % (val, id)
+ if (has_enum):
+ vval = self.eth_enum_item(tname, id)
+ else:
+ vval = val
+ out += ' { %3s, "%s" },\n' % (vval, id)
out += " { 0, NULL }\n};\n"
return out
+ #--- eth_enum_prefix ------------------------------------------------------------
+ def eth_enum_prefix(self, tname, type=False):
+ out = ""
+ if (self.eth_type[tname]['export'] & EF_ENUM):
+ no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
+ else:
+ no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
+ if (not no_prot):
+ out += self.eproto
+ if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type):
+ if (out): out += '_'
+ out += tname
+ if (self.eth_type[tname]['enum'] & EF_UCASE):
+ out = out.upper()
+ if (out): out += '_'
+ return out
+
+ #--- eth_enum_nm ------------------------------------------------------------
+ def eth_enum_nm(self, tname):
+ out = self.eth_enum_prefix(tname, type=True)
+ out += "enum"
+ return out
+
+ #--- eth_enum_item ---------------------------------------------------------------
+ def eth_enum_item(self, tname, ident):
+ out = self.eth_enum_prefix(tname)
+ out += asn2c(ident)
+ if (self.eth_type[tname]['enum'] & EF_UCASE):
+ out = out.upper()
+ return out
+
+ #--- eth_enum ---------------------------------------------------------------
+ def eth_enum(self, tname, vals):
+ out = ""
+ if (self.eth_type[tname]['enum'] & EF_DEFINE):
+ out += "/* enumerated values for %s */\n" % (tname)
+ for (val, id) in vals:
+ out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
+ else:
+ out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
+ first_line = 1
+ for (val, id) in vals:
+ if (first_line == 1):
+ first_line = 0
+ else:
+ out += ",\n"
+ out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val)
+ out += "\n} %s;\n" % (self.eth_enum_nm(tname))
+ return out
+
#--- eth_bits ---------------------------------------------------------------
def eth_bits(self, tname, bits):
out = ""
#--- eth_type_fn_h ----------------------------------------------------------
def eth_type_fn_h(self, tname):
out = ""
- if (not self.eth_type[tname]['export'] & 0x01):
+ if (not self.eth_type[tname]['export'] & EF_TYPE):
out += "static "
out += "int "
if (self.Ber()):
- out += "dissect_%s_%s(gboolean implicit_tag, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf_index)" % (self.eth_type[tname]['proto'], tname)
+ out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname)
elif (self.Per()):
- out += "dissect_%s_%s(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf_index)" % (self.eth_type[tname]['proto'], tname)
+ 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)
out += ";\n"
return out
#--- eth_type_fn_hdr --------------------------------------------------------
def eth_type_fn_hdr(self, tname):
out = '\n'
- if (not self.eth_type[tname]['export'] & 0x01):
+ if (not self.eth_type[tname]['export'] & EF_TYPE):
out += "static "
out += "int\n"
if (self.Ber()):
- out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname)
+ out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname)
elif (self.Per()):
- out += "dissect_%s_%s(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {\n" % (self.eth_type[tname]['proto'], tname)
- if self.conform.get_fn_presence(tname):
- out += self.conform.get_fn_text(tname, 'FN_HDR')
- elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
+ 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)
+ #if self.conform.get_fn_presence(tname):
+ # out += self.conform.get_fn_text(tname, 'FN_HDR')
+ #el
+ if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
return out
#--- eth_type_fn_ftr --------------------------------------------------------
def eth_type_fn_ftr(self, tname):
out = '\n'
- if self.conform.get_fn_presence(tname):
- out += self.conform.get_fn_text(tname, 'FN_FTR')
- elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
+ #if self.conform.get_fn_presence(tname):
+ # out += self.conform.get_fn_text(tname, 'FN_FTR')
+ #el
+ if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
out += " return offset;\n"
out += "}\n"
#--- eth_type_fn_body -------------------------------------------------------
def eth_type_fn_body(self, tname, body, pars=None):
out = body
- if self.conform.get_fn_body_presence(tname):
- out = self.conform.get_fn_text(tname, 'FN_BODY')
- elif self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
+ #if self.conform.get_fn_body_presence(tname):
+ # out = self.conform.get_fn_text(tname, 'FN_BODY')
+ #el
+ if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
if pars:
try:
if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
fx = self.output.file_open('hfarr')
for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
- if len(self.eth_hf[f]['ref']) == 1:
- blurb = '"' + self.eth_hf[f]['ref'][0] + '"'
- else:
- blurb = '""'
+ t = self.eth_hf[f]['ethtype']
+ blurb = '"%s.%s"' % (self.eth_type[t]['proto'], t)
attr = self.eth_hf[f]['attr'].copy()
attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
if not attr.has_key('BLURB'):
if (not len(self.eth_export_ord)): return
fx = self.output.file_open('exp', ext='h')
for t in self.eth_export_ord: # vals
- if (self.eth_type[t]['export'] & 0x02) and self.eth_type[t]['val'].eth_has_vals():
- if self.eth_type[t]['export'] & 0x08:
- fx.write("ETH_VAR_IMPORT ")
+ if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
+ fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
+ if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
+ if not self.eth_type[t]['export'] & EF_TABLE:
+ if self.eth_type[t]['export'] & EF_WS_VAR:
+ fx.write("WS_VAR_IMPORT ")
+ else:
+ fx.write("extern ")
+ fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
else:
- fx.write("extern ")
- fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
+ fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
for t in self.eth_export_ord: # functions
- if (self.eth_type[t]['export'] & 0x01):
+ if (self.eth_type[t]['export'] & EF_TYPE):
+ if self.eth_type[t]['export'] & EF_EXTERN:
+ fx.write("extern ")
fx.write(self.eth_type_fn_h(t))
self.output.file_close(fx)
for (m, p) in self.modules:
fx.write("%-*s %s\n" % (maxw, m, p))
fx.write('#.END\n\n')
+ for cls in self.objectclass_ord:
+ if self.objectclass[cls]['export']:
+ fx.write('#.CLASS %s\n' % (cls))
+ maxw = 2
+ for fld in self.objectclass[cls]['val'].fields:
+ w = len(fld.fld_repr()[0])
+ if (w > maxw): maxw = w
+ for fld in self.objectclass[cls]['val'].fields:
+ repr = fld.fld_repr()
+ fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:])))
+ fx.write('#.END\n\n')
if self.Ber():
fx.write('#.IMPORT_TAG\n')
for t in self.eth_export_ord: # tags
- if (self.eth_type[t]['export'] & 0x01):
+ if (self.eth_type[t]['export'] & EF_TYPE):
fx.write('%-24s ' % self.eth_type[t]['ref'][0])
fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
fx.write('#.END\n\n')
fx.write('#.TYPE_ATTR\n')
for t in self.eth_export_ord: # attributes
- if (self.eth_type[t]['export'] & 0x01):
+ if (self.eth_type[t]['export'] & EF_TYPE):
fx.write('%-24s ' % self.eth_type[t]['ref'][0])
attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
if (not len(self.eth_value_ord1)): return
fx = self.output.file_open('val', ext='h')
for v in self.eth_value_ord1:
- fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
+ vv = self.eth_value[v]['value']
+ if isinstance (vv, Value):
+ vv = vv.to_str(self)
+ fx.write("#define %-30s %s\n" % (v, vv))
+ for t in self.eth_type_ord1:
+ if self.eth_type[t]['import']:
+ continue
+ if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
+ fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
self.output.file_close(fx)
#--- eth_output_valexp ------------------------------------------------------
if (not len(self.eth_vexport_ord)): return
fx = self.output.file_open('valexp', ext='h')
for v in self.eth_vexport_ord:
- fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
+ vv = self.eth_value[v]['value']
+ if isinstance (vv, Value):
+ vv = vv.to_str(self)
+ fx.write("#define %-30s %s\n" % (v, vv))
self.output.file_close(fx)
#--- eth_output_types -------------------------------------------------------
if (self.Ber()):
if (i): postfix = '_impl'; impl = 'TRUE'
else: postfix = ''; impl = 'FALSE'
- out += 'static int dissect_'+f+postfix+'(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {\n'
- par=((impl, 'tvb', 'offset', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
+ out += 'static int dissect_'+f+postfix+'(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_) {\n'
+ par=((impl, 'tvb', 'offset', 'actx', 'tree', self.eth_hf[f]['fullname']),)
else:
- out += 'static int dissect_'+f+'(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {\n'
- par=(('tvb', 'offset', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
+ out += 'static int dissect_'+f+'(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_) {\n'
+ par=(('tvb', 'offset', 'actx', 'tree', self.eth_hf[f]['fullname']),)
out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret='return',
par=par)
out += '}\n'
return out
#end out_field()
- def out_pdu(f):
+ def out_pdu_decl(f):
t = self.eth_hf[f]['ethtype']
is_new = self.eth_hf[f]['pdu']['new']
- if self.field[self.eth_hf[f]['ref'][0]]['impl']:
- impl = 'TRUE'
+ out = 'static '
+ if (is_new):
+ out += 'int'
else:
- impl = 'FALSE'
+ out += 'void'
+ out += ' dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);\n'
+ return out
+ #end out_pdu_decl()
+ def out_pdu(f):
+ t = self.eth_hf[f]['ethtype']
+ is_new = self.eth_hf[f]['pdu']['new']
+ impl = 'FALSE'
out = 'static '
if (is_new):
out += 'int'
else:
out += 'void'
- out += ' dissect_'+f+'(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {\n'
+ out += ' dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
+ if (is_new):
+ out += ' int offset = 0;\n'
+ off_par = 'offset'
+ ret_par = 'offset'
+ else:
+ off_par = '0'
+ ret_par = None
if (self.Per()):
if (self.Aligned()):
aligned = 'TRUE'
else:
aligned = 'FALSE'
- out += self.eth_fn_call('per_aligment_type_callback', par=((aligned,),))
+ out += " asn1_ctx_t asn1_ctx;\n"
+ out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
if (self.Ber()):
- par=((impl, 'tvb', '0', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
+ out += " asn1_ctx_t asn1_ctx;\n"
+ out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
+ par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
elif (self.Per()):
- par=(('tvb', '0', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
+ par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
else:
par=((),)
- ret = None
- if (is_new): ret = 'return'
- out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret, par=par)
+ out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
+ if (self.Per() and is_new):
+ out += ' offset += 7; offset >>= 3;\n'
+ if (is_new):
+ out += ' return offset;\n'
out += '}\n'
return out
#end out_pdu()
fx = self.output.file_open('fn')
pos = fx.tell()
+ if (len(self.eth_hfpdu_ord)):
+ first_decl = True
+ for f in self.eth_hfpdu_ord:
+ if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
+ if first_decl:
+ fx.write('/*--- PDUs declarations ---*/\n')
+ first_decl = False
+ fx.write(out_pdu_decl(f))
+ if not first_decl:
+ fx.write('\n')
if self.eth_dep_cycle:
fx.write('/*--- Cyclic dependencies ---*/\n\n')
i = 0
if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
fx.write(''.join(map(lambda i: '/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]), self.dep_cycle_eth_type[t])))
fx.write(self.eth_type_fn_h(t))
- if (not self.NAPI()):
+ if (self.Fld() or self.eth_type[t]['create_field']):
fx.write('\n')
for f in self.eth_hf_ord:
- if (self.eth_hf[f]['ethtype'] == t):
+ if ((self.eth_hf[f]['ethtype'] == t) and (self.Fld() or self.eth_hf[f]['create_field'])):
fx.write(out_field(f))
fx.write('\n')
i += 1
fx.write('\n')
- if (not self.NAPI()): # fields for imported types
+ if (self.Fld()): # fields for imported types
fx.write('/*--- Fields for imported types ---*/\n\n')
for f in self.eth_hf_ord:
if (self.eth_type[self.eth_hf[f]['ethtype']]['import']):
if self.eth_type[t]['import']:
continue
if self.eth_type[t]['val'].eth_has_vals():
- if self.eth_type[t]['no_emit'] & 0x02:
+ if self.eth_type[t]['no_emit'] & EF_VALS:
pass
- elif self.eth_type[t]['user_def'] & 0x02:
+ elif self.eth_type[t]['user_def'] & EF_VALS:
fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
+ elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
+ pass
else:
fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
- if self.eth_type[t]['no_emit'] & 0x01:
+ if self.eth_type[t]['no_emit'] & EF_TYPE:
pass
- elif self.eth_type[t]['user_def'] & 0x01:
+ elif self.eth_type[t]['user_def'] & EF_TYPE:
fx.write(self.eth_type_fn_h(t))
else:
fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
- if (not self.NAPI() and not self.dep_cycle_eth_type.has_key(t)):
+ if ((self.Fld() or self.eth_type[t]['create_field']) and not self.dep_cycle_eth_type.has_key(t)):
for f in self.eth_hf_ord:
- if (self.eth_hf[f]['ethtype'] == t):
+ if ((self.eth_hf[f]['ethtype'] == t) and (self.Fld() or self.eth_hf[f]['create_field'])):
fx.write(out_field(f))
fx.write('\n')
if (len(self.eth_hfpdu_ord)):
fx.write('/*--- PDUs ---*/\n\n')
for f in self.eth_hfpdu_ord:
if (self.eth_hf[f]['pdu']):
- fx.write(out_pdu(f))
+ if (self.emitted_pdu.has_key(f)):
+ fx.write(" /* %s already emitted */\n" % (f))
+ else:
+ fx.write(out_pdu(f))
+ self.emitted_pdu[f] = True
fx.write('\n')
fempty = pos == fx.tell()
self.output.file_close(fx, discard=fempty)
hnd = 'find_dissector("%s")' % (dis)
else:
hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
- fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], reg['rport'], hnd))
+ rport = self.value_get_eth(reg['rport'])
+ fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
elif (reg['rtype'] in ('BER', 'PER')):
- fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), reg['roid'], f, self.eproto, reg['roidname']))
+ roid = self.value_get_eth(reg['roid'])
+ fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
fempty = False
fx.write('\n')
self.output.file_close(fx, discard=fempty)
+ #--- eth_output_table -----------------------------------------------------
+ def eth_output_table(self):
+ for num in self.conform.report.keys():
+ fx = self.output.file_open('table' + num)
+ for rep in self.conform.report[num]:
+ if rep['type'] == 'HDR':
+ fx.write('\n')
+ if rep['var']:
+ var = rep['var']
+ var_list = var.split('.')
+ cls = var_list[0]
+ del var_list[0]
+ if (self.oassign_cls.has_key(cls)):
+ for ident in self.oassign_cls[cls]:
+ obj = self.get_obj_repr(ident, var_list)
+ if not obj:
+ continue
+ obj['_LOOP'] = var
+ obj['_DICT'] = str(obj)
+ try:
+ text = rep['text'] % obj
+ except (KeyError):
+ raise sys.exc_type, "%s:%s invalid key %s for information object %s of %s" % (rep['fn'], rep['lineno'], sys.exc_value, ident, var)
+ fx.write(text)
+ else:
+ fx.write("/* Unknown or empty loop list %s */\n" % (var))
+ else:
+ fx.write(rep['text'])
+ if rep['type'] == 'FTR':
+ fx.write('\n')
+ self.output.file_close(fx)
+
#--- dupl_report -----------------------------------------------------
def dupl_report(self):
# types
for t in tmplist:
msg = "The same type names for different types. Explicit type renaming is recommended.\n"
msg += t + "\n"
- x = ''
for tt in self.eth_type_dupl[t]:
- msg += " %-20s %s\n" % (t+str(x), tt)
- if not x: x = 1
- else: x += 1
+ msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
warnings.warn_explicit(msg, UserWarning, '', '')
# fields
tmplist = self.eth_hf_dupl.keys()
def eth_do_output(self):
if self.dbg('a'):
print "\n# Assignments"
- print "\n".join(self.assign_ord)
+ for a in self.assign_ord:
+ v = ' '
+ if (self.assign[a]['virt']): v = '*'
+ print v, a
print "\n# Value assignments"
- print "\n".join(self.vassign_ord)
+ for a in self.vassign_ord:
+ print ' ', a
+ print "\n# Information object assignments"
+ for a in self.oassign_ord:
+ print " %-12s (%s)" % (a, self.oassign[a].cls)
if self.dbg('t'):
print "\n# Imported Types"
print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
print "-" * 100
for t in self.value_imp:
print "%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])
+ print "\n# Imported Object Classes"
+ print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
+ print "-" * 100
+ for t in self.objectclass_imp:
+ print "%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto'])
print "\n# Exported Types"
print "%-31s %s" % ("Wireshark type", "Export Flag")
print "-" * 100
print "%-40s %s" % ("Wireshark name", "Value")
print "-" * 100
for v in self.eth_vexport_ord:
- print "%-40s %s" % (v, self.eth_value[v]['value'])
+ vv = self.eth_value[v]['value']
+ if isinstance (vv, Value):
+ vv = vv.to_str(self)
+ print "%-40s %s" % (v, vv)
+ print "\n# ASN.1 Object Classes"
+ print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
+ print "-" * 100
+ for t in self.objectclass_ord:
+ print "%-40s " % (t)
print "\n# ASN.1 Types"
print "%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")
print "-" * 100
print "%-31s %d" % (t, len(self.eth_type[t]['ref'])),
print ', '.join(self.eth_type[t]['ref'])
print "\n# ASN.1 Values"
- print "%-40s %-18s %s" % ("ASN.1 unique name", "Type", "Value")
+ print "%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value")
print "-" * 100
for v in self.value_ord:
- if isinstance (self.value[v]['value'], Value):
- print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'].to_str())
- else:
- print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'])
- print "\n# Wireshark Values"
- print "%-40s %s" % ("Wireshark name", "Value")
- print "-" * 100
- for v in self.eth_value_ord:
- print "%-40s %s" % (v, self.eth_value[v]['value'])
+ vv = self.value[v]['value']
+ if isinstance (vv, Value):
+ vv = vv.to_str(self)
+ print "%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname'])
+ #print "\n# Wireshark Values"
+ #print "%-40s %s" % ("Wireshark name", "Value")
+ #print "-" * 100
+ #for v in self.eth_value_ord:
+ # vv = self.eth_value[v]['value']
+ # if isinstance (vv, Value):
+ # vv = vv.to_str(self)
+ # print "%-40s %s" % (v, vv)
print "\n# ASN.1 Fields"
print "ASN.1 unique name Wireshark name ASN.1 type"
print "-" * 100
self.output.outnm = self.outnm_opt
if (not self.output.outnm):
self.output.outnm = self.proto
+ self.output.outnm = self.output.outnm.replace('.', '-')
self.eth_output_hf()
self.eth_output_ett()
self.eth_output_types()
self.eth_output_dis_hnd()
self.eth_output_dis_reg()
self.eth_output_dis_tab()
+ self.eth_output_table()
+
+ def dbg_modules(self):
+ def print_mod(m):
+ print "%-30s " % (m),
+ dep = self.module[m][:]
+ for i in range(len(dep)):
+ if not self.module.has_key(dep[i]):
+ dep[i] = '*' + dep[i]
+ print ', '.join(dep)
+ # end of print_mod()
+ (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: not self.module.has_key(t))
+ print "\n# ASN.1 Moudules"
+ print "Module name Dependency"
+ print "-" * 100
+ new_ord = False
+ for m in (self.module_ord):
+ print_mod(m)
+ new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
+ if new_ord:
+ print "\n# ASN.1 Moudules - in dependency order"
+ print "Module name Dependency"
+ print "-" * 100
+ for m in (mod_ord):
+ print_mod(m)
+ if mod_cyc:
+ print "\nCyclic dependencies:"
+ for i in (range(len(mod_cyc))):
+ print "%02d: %s" % (i + 1, str(mod_cyc[i]))
+
#--- EthCnf -------------------------------------------------------------------
class EthCnf:
def __init__(self):
+ self.ectx = None
self.tblcfg = {}
self.table = {}
self.order = {}
self.fn = {}
+ self.report = {}
+ self.suppress_line = False
+ self.include_path = []
# Value name Default value Duplicity check Usage check
self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
+ self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
+ self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
+ self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
+ self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
+ self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
for k in self.tblcfg.keys() :
self.table[table][key].update(kw)
self.order[table].append(key)
+ def update_item(self, table, key, fn, lineno, **kw):
+ if not self.table[table].has_key(key):
+ self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
+ self.order[table].append(key)
+ self.table[table][key][self.tblcfg[table]['val_nm']] = {}
+ self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
+
def get_order(self, table):
return self.order[table]
self.table[table][key]['used'] = True
return self.table[table][key].get(vname, vdflt)
+ def omit_assignment(self, type, ident, module):
+ if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
+ return True
+ if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
+ self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
+ self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
+ self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
+ return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
+ return False
+
def add_fn_line(self, name, ctx, line, fn, lineno):
if not self.fn.has_key(name):
self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
return '';
if (not self.fn[name][ctx]):
return '';
- return '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'],self.fn[name][ctx]['fn'],self.fn[name][ctx]['text']);
+ self.fn[name][ctx]['used'] = True
+ out = self.fn[name][ctx]['text']
+ if (not self.suppress_line):
+ out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], self.fn[name][ctx]['fn'], out);
+ return out
def add_pdu(self, par, is_new, fn, lineno):
#print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
(reg, hidden) = (None, False)
if (len(par) > 1): reg = par[1]
if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
- attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden}
+ attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False}
self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
return
elif (rtype in ('BER', 'PER')):
attr['roid'] = par[1]
attr['roidname'] = '""'
- if (len(par)>=3): attr['roidname'] = par[2]
+ if (len(par)>=3):
+ attr['roidname'] = par[2]
+ elif attr['roid'][0] != '"':
+ attr['roidname'] = '"' + attr['roid'] + '"'
rkey = '/'.join([rtype, attr['roid']])
self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
+ def check_par(self, par, pmin, pmax, fn, lineno):
+ for i in range(len(par)):
+ if par[i] == '-':
+ par[i] = None
+ continue
+ if par[i][0] == '#':
+ par[i:] = []
+ break
+ if len(par) < pmin:
+ warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
+ return None
+ if (pmax >= 0) and (len(par) > pmax):
+ warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
+ return par[0:pmax]
+ return par
+
def read(self, fn):
def get_par(line, pmin, pmax, fn, lineno):
par = line.split(None, pmax)
- for i in range(len(par)):
- if par[i] == '-':
- par[i] = None
- continue
- if par[i][0] == '#':
- par[i:] = []
- break
- if len(par) < pmin:
- warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
- return None
- if len(par) > pmax:
- warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
- return par[0:pmax]
+ par = self.check_par(par, pmin, pmax, fn, lineno)
return par
def get_par_nm(line, pmin, pmax, fn, lineno):
return par
f = open(fn, "r")
- directive = re.compile(r'^\s*#\.(?P<name>[A-Z_]+)\s+')
+ directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)\s+')
+ report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
comment = re.compile(r'^\s*#[^.]')
empty = re.compile(r'^\s*$')
lineno = 0
ctx = None
name = ''
+ default_flags = 0x00
stack = []
while 1:
- line = f.readline()
- lineno += 1
+ if not f.closed:
+ line = f.readline()
+ lineno += 1
+ else:
+ line = None
if not line:
- f.close()
+ if not f.closed:
+ f.close()
if stack:
frec = stack.pop()
fn, f, lineno = frec['fn'], frec['f'], frec['lineno']
if comment.search(line): continue
result = directive.search(line)
if result: # directive
- if result.group('name') in ('EXPORTS', 'PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
- 'USER_DEFINED', 'NO_EMIT', 'MODULE', 'MODULE_IMPORT', 'OMIT_ASSIGNMENT',
- 'TYPE_RENAME', 'FIELD_RENAME', 'IMPORT_TAG',
+ rep_result = report.search(result.group('name'))
+ if result.group('name') == 'END_OF_CNF':
+ f.close()
+ elif result.group('name') == 'OPT':
+ ctx = result.group('name')
+ par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
+ if not par: continue
+ self.set_opt(par[0], par[1:], fn, lineno)
+ ctx = None
+ elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
+ 'MODULE', 'MODULE_IMPORT',
+ 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
+ 'VIRTUAL_ASSGN', 'SET_TYPE',
+ 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
ctx = result.group('name')
+ elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
+ 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
+ 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
+ ctx = result.group('name')
+ key = '*'
+ if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
+ key += 'T'
+ if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
+ key += 'V'
+ par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
+ if par:
+ key += '/' + par[0]
+ self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
+ if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
+ ctx = 'NO_OMIT_ASSGN'
+ else:
+ ctx = None
+ elif result.group('name') in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
+ ctx = result.group('name')
+ default_flags = EF_TYPE|EF_VALS
+ if ctx == 'EXPORTS':
+ par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
+ else:
+ par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
+ if not par: continue
+ p = 1
+ if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
+ elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
+ elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
+ elif (ctx == 'EXPORTS'): p = 0
+ else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
+ for i in range(p, len(par)):
+ if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
+ elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
+ elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
+ elif (par[i] == 'WS_VAR'): default_flags |= EF_WS_VAR
+ elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
+ elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
+ else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
+ elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
+ ctx = result.group('name')
+ default_flags = EF_ENUM
+ if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
+ if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
+ par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
+ for i in range(0, len(par)):
+ if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
+ elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
+ elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
+ elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
+ else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
elif result.group('name') in ('FN_HDR', 'FN_FTR'):
par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
if not par: continue
ctx = result.group('name')
if not par:
name = None
- else:
+ elif len(par) == 1:
name = par[0]
- if len(par) > 1:
- self.add_item(ctx, name, pars=par[1], fn=fn, lineno=lineno)
+ self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
+ elif len(par) > 1:
+ self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
ctx = None
- name = None
+ elif result.group('name') == 'CLASS':
+ par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
+ if not par: continue
+ ctx = result.group('name')
+ name = par[0]
+ add_class_ident(name)
+ if not name.isupper():
+ warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
+ UserWarning, fn, lineno)
+ elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
+ par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
+ if not par: continue
+ self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno)
+ elif rep_result: # Reports
+ num = rep_result.group('num')
+ type = rep_result.group('type')
+ if type == 'BODY':
+ par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
+ if not par: continue
+ else:
+ par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno)
+ rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno }
+ if len(par) > 0:
+ rep['var'] = par[0]
+ self.report.setdefault(num, []).append(rep)
+ ctx = 'TABLE'
+ name = num
elif result.group('name') == 'INCLUDE':
par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
if not par:
warnings.warn_explicit("INCLUDE requires parameter", UserWarning, fn, lineno)
continue
- fname = os.path.join(os.path.split(fn)[0], par[0])
+ fname = par[0]
+ #print "Try include: %s" % (fname)
+ if (not os.path.exists(fname)):
+ fname = os.path.join(os.path.split(fn)[0], par[0])
+ #print "Try include: %s" % (fname)
+ i = 0
+ while not os.path.exists(fname) and (i < len(self.include_path)):
+ fname = os.path.join(self.include_path[i], par[0])
+ #print "Try include: %s" % (fname)
+ i += 1
if (not os.path.exists(fname)):
fname = par[0]
fnew = open(fname, "r")
if not ctx:
if not empty.match(line):
warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
+ elif ctx == 'OPT':
+ if empty.match(line): continue
+ par = get_par(line, 1, -1, fn=fn, lineno=lineno)
+ if not par: continue
+ self.set_opt(par[0], par[1:], fn, lineno)
elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
if empty.match(line): continue
if ctx == 'EXPORTS':
- par = get_par(line, 1, 4, fn=fn, lineno=lineno)
+ par = get_par(line, 1, 6, fn=fn, lineno=lineno)
else:
par = get_par(line, 1, 2, fn=fn, lineno=lineno)
if not par: continue
- flag = 0x03
+ flags = default_flags
p = 2
if (len(par)>=2):
- if (par[1] == 'WITH_VALS'): flag = 0x03
- elif (par[1] == 'WITHOUT_VALS'): flag = 0x01
- elif (par[1] == 'ONLY_VALS'): flag = 0x02
+ if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
+ elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
+ elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
elif (ctx == 'EXPORTS'): p = 1
else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
for i in range(p, len(par)):
- if (par[i] == 'ETH_VAR'): flag |= 0x08
- elif (par[i] == 'NO_PROT_PREFIX'): flag |= 0x10
+ if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
+ elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
+ elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
+ elif (par[i] == 'WS_VAR'): flags |= EF_WS_VAR
+ elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
+ elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
- self.add_item(ctx, par[0], flag=flag, fn=fn, lineno=lineno)
+ self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
+ elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
+ if empty.match(line): continue
+ par = get_par(line, 1, 4, fn=fn, lineno=lineno)
+ if not par: continue
+ flags = default_flags
+ for i in range(1, len(par)):
+ if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
+ elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
+ elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
+ elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
+ else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
+ self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
elif ctx in ('PDU', 'PDU_NEW'):
if empty.match(line): continue
par = get_par(line, 1, 5, fn=fn, lineno=lineno)
if empty.match(line): continue
par = get_par(line, 3, 3, fn=fn, lineno=lineno)
if not par: continue
- self.add_item('IMPORT_TAG', par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
+ self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
elif ctx == 'OMIT_ASSIGNMENT':
if empty.match(line): continue
par = get_par(line, 1, 1, fn=fn, lineno=lineno)
if not par: continue
- self.add_item('OMIT_ASSIGNMENT', par[0], omit=True, fn=fn, lineno=lineno)
+ self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
+ elif ctx == 'NO_OMIT_ASSGN':
+ if empty.match(line): continue
+ par = get_par(line, 1, 1, fn=fn, lineno=lineno)
+ if not par: continue
+ self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
+ elif ctx == 'VIRTUAL_ASSGN':
+ if empty.match(line): continue
+ par = get_par(line, 2, -1, fn=fn, lineno=lineno)
+ if not par: continue
+ if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
+ self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
+ self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
+ for nm in par[2:]:
+ self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
+ if not par[0][0].isupper():
+ warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
+ UserWarning, fn, lineno)
+ elif ctx == 'SET_TYPE':
+ if empty.match(line): continue
+ par = get_par(line, 2, 2, fn=fn, lineno=lineno)
+ if not par: continue
+ if not self.check_item('VIRTUAL_ASSGN', par[0]):
+ self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
+ if not par[1][0].isupper():
+ warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
+ UserWarning, fn, lineno)
elif ctx == 'TYPE_RENAME':
if empty.match(line): continue
par = get_par(line, 2, 2, fn=fn, lineno=lineno)
if not par[1][0].islower():
warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
UserWarning, fn, lineno)
+ elif ctx == 'TF_RENAME':
+ if empty.match(line): continue
+ par = get_par(line, 2, 2, fn=fn, lineno=lineno)
+ if not par: continue
+ tmpu = par[1][0].upper() + par[1][1:]
+ tmpl = par[1][0].lower() + par[1][1:]
+ self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
+ if not tmpu[0].isupper():
+ warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
+ UserWarning, fn, lineno)
+ self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
+ if not tmpl[0].islower():
+ warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
+ UserWarning, fn, lineno)
elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
if empty.match(line): continue
par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
if not par: continue
if name:
- self.add_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
+ self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
else:
self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
+ elif ctx == 'CLASS':
+ if empty.match(line): continue
+ par = get_par(line, 1, 3, fn=fn, lineno=lineno)
+ if not par: continue
+ if not set_type_to_class(name, par[0], par[1:]):
+ warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
+ UserWarning, fn, lineno)
+ elif ctx == 'TABLE':
+ self.report[name][-1]['text'] += line
+
+ def set_opt(self, opt, par, fn, lineno):
+ #print "set_opt: %s, %s" % (opt, par)
+ if opt in ("-I",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.include_path.append(par[0])
+ elif opt in ("-b", "BER", "CER", "DER"):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.encoding = 'ber'
+ elif opt in ("-X", "NEW_BER"):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.new_ber = True
+ elif opt in ("PER",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.encoding = 'per'
+ elif opt in ("-p", "PROTO"):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.proto_opt = par[0]
+ self.ectx.merge_modules = True
+ elif opt in ("-F", "CREATE_FIELDS"):
+ par = self.check_par(par, 0, 1, fn, lineno)
+ tnm = '*'
+ if (len(par) > 0): tnm = par[0]
+ self.ectx.fld_opt[tnm] = True
+ elif opt in ("-T",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.tag_opt = True
+ elif opt in ("ALIGNED",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.aligned = True
+ elif opt in ("-u", "UNALIGNED"):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.aligned = False
+ elif opt in ("-d",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.dbgopt = par[0]
+ elif opt in ("-e",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.expcnf = True
+ elif opt in ("-S",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.merge_modules = True
+ elif opt in ("GROUP_BY_PROT",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.group_by_prot = True
+ elif opt in ("-o",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.outnm_opt = par[0]
+ elif opt in ("-O",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.output.outdir = par[0]
+ elif opt in ("-s",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.output.single_file = par[0]
+ elif opt in ("-k",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.ectx.output.keep = True
+ elif opt in ("-L",):
+ par = self.check_par(par, 0, 0, fn, lineno)
+ self.suppress_line = True
+ elif opt in ("EMBEDDED_PDV_CB",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.default_embedded_pdv_cb = par[0]
+ elif opt in ("EXTERNAL_TYPE_CB",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.default_external_type_cb = par[0]
+ else:
+ warnings.warn_explicit("Unknown option %s" % (opt),
+ UserWarning, fn, lineno)
def dbg_print(self):
print "\n# Conformance values"
if not self.table[t][k]['used']:
warnings.warn_explicit("Unused %s for %s" % (t, k),
UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
+ fnms = self.fn.keys()
+ fnms.sort()
+ for f in fnms:
+ keys = self.fn[f].keys()
+ keys.sort()
+ for k in keys:
+ if not self.fn[f][k]: continue
+ if not self.fn[f][k]['used']:
+ warnings.warn_explicit("Unused %s for %s" % (k, f),
+ UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
#--- EthOut -------------------------------------------------------------------
class EthOut:
def __init__(self):
+ self.ectx = None
self.outnm = None
self.outdir = '.'
self.single_file = None
- self.created_files = []
- self.unique_created_files = []
+ self.created_files = {}
+ self.created_files_ord = []
self.keep = False
+
+ def outcomment(self, ln, comment=None):
+ if comment:
+ return '%s %s\n' % (comment, ln)
+ else:
+ return '/* %-74s */\n' % (ln)
+
+ def created_file_add(self, name, keep_anyway):
+ name = os.path.normcase(os.path.abspath(name))
+ if not self.created_files.has_key(name):
+ self.created_files_ord.append(name)
+ self.created_files[name] = keep_anyway
+ else:
+ self.created_files[name] = self.created_files[name] or keep_anyway
+
+ def created_file_exists(self, name):
+ name = os.path.normcase(os.path.abspath(name))
+ return self.created_files.has_key(name)
+
#--- output_fname -------------------------------------------------------
def output_fname(self, ftype, ext='c'):
fn = ''
#--- file_open -------------------------------------------------------
def file_open(self, ftype, ext='c'):
fn = self.output_fullname(ftype, ext=ext)
- fx = file(fn, 'w')
+ if self.created_file_exists(fn):
+ fx = file(fn, 'a')
+ else:
+ fx = file(fn, 'w')
+ comment = None
if ext in ('cnf',):
- fx.write(self.fhdr(fn, comment = '#'))
+ comment = '#'
+ fx.write(self.fhdr(fn, comment = comment))
else:
- if (not self.single_file):
+ if (not self.single_file and not self.created_file_exists(fn)):
fx.write(self.fhdr(fn))
+ if not self.ectx.merge_modules:
+ fx.write('\n')
+ mstr = "--- "
+ if self.ectx.groups():
+ mstr += "Module"
+ if (len(self.ectx.modules) > 1):
+ mstr += "s"
+ for (m, p) in self.ectx.modules:
+ mstr += " %s" % (m)
+ else:
+ mstr += "Module %s" % (self.ectx.Module())
+ mstr += " --- --- ---"
+ fx.write(self.outcomment(mstr, comment))
+ fx.write('\n')
return fx
#--- file_close -------------------------------------------------------
def file_close(self, fx, discard=False, keep_anyway=False):
fx.close()
- if (discard):
+ if discard and not self.created_file_exists(fx.name):
os.unlink(fx.name)
- elif (not keep_anyway):
- self.created_files.append(os.path.normcase(os.path.abspath(fx.name)))
+ else:
+ self.created_file_add(fx.name, keep_anyway)
#--- fhdr -------------------------------------------------------
def fhdr(self, fn, comment=None):
- def outln(ln):
- if comment:
- return '# %s\n' % (ln)
- else:
- return '/* %-74s */\n' % (ln)
out = ''
- out += outln('Do not modify this file.')
- out += outln('It is created automatically by the ASN.1 to Wireshark dissector compiler')
- out += outln(fn)
- out += outln(' '.join(sys.argv))
+ out += self.outcomment('Do not modify this file.', comment)
+ out += self.outcomment('It is created automatically by the ASN.1 to Wireshark dissector compiler', comment)
+ out += self.outcomment(fn, comment)
+ out += self.outcomment(' '.join(sys.argv), comment)
out += '\n'
return out
#--- dbg_print -------------------------------------------------------
def dbg_print(self):
print "\n# Output files"
- print "\n".join(self.created_files)
+ print "\n".join(self.created_files_ord)
print "\n"
#--- make_single_file -------------------------------------------------------
out_nm = self.output_fullname('', ext='h')
self.do_include(out_nm, in_nm)
if (not self.keep):
- self.unique_created_files = []
- [self.unique_created_files.append(wrd) for wrd in self.created_files if not self.unique_created_files.count(wrd)]
- for fn in self.unique_created_files:
- os.unlink(fn)
+ for fn in self.created_files_ord:
+ if not self.created_files[fn]:
+ os.unlink(fn)
#--- do_include -------------------------------------------------------
def do_include(self, out_nm, in_nm):
def check_file(fn, fnlist):
fnfull = os.path.normcase(os.path.abspath(fn))
- if ((fnfull in fnlist) and os.path.exists(fnfull)):
+ if (fnlist.has_key(fnfull) and os.path.exists(fnfull)):
return os.path.normpath(fn)
return None
fin = file(in_nm, "r")
l.append ("".join (map (lambda (k,v): self.str_child (k, v, depth + 1),
self.__dict__.items ())))
return "\n".join (l)
- def __str__(self):
+ def __repr__(self):
return "\n" + self.str_depth (0)
def to_python (self, ctx):
return self.str_depth (ctx.indent_lev)
def eth_reg(self, ident, ectx):
pass
-#--- value_assign -------------------------------------------------------------
-class value_assign (Node):
+ def fld_obj_repr(self, ectx):
+ return "/* TO DO %s */" % (str(self))
+
+#--- ValueAssignment -------------------------------------------------------------
+class ValueAssignment (Node):
def __init__(self,*args, **kw) :
Node.__init__ (self,*args, **kw)
def eth_reg(self, ident, ectx):
- if ectx.conform.use_item('OMIT_ASSIGNMENT', self.ident): return # Assignment to omit
+ if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
ectx.eth_reg_vassign(self)
ectx.eth_reg_value(self.ident, self.typ, self.val)
+#--- ObjectAssignment -------------------------------------------------------------
+class ObjectAssignment (Node):
+ def __init__(self,*args, **kw) :
+ Node.__init__ (self,*args, **kw)
+
+ def __eq__(self, other):
+ if self.cls != other.cls:
+ return False
+ if len(self.val) != len(other.val):
+ return False
+ for f in (self.val.keys()):
+ if not other.val.has_key(f):
+ return False
+ if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
+ if not self.val[f].fld_obj_eq(other.val[f]):
+ return False
+ else:
+ if str(self.val[f]) != str(other.val[f]):
+ return False
+ return True
+
+ def eth_reg(self, ident, ectx):
+ def make_virtual_type(cls, field, prefix):
+ if isinstance(self.val, str): return
+ if self.val.has_key(field) and not isinstance(self.val[field], Type_Ref):
+ vnm = prefix + '-' + self.ident
+ virtual_tr = Type_Ref(val = vnm)
+ t = self.val[field]
+ self.val[field] = virtual_tr
+ ectx.eth_reg_assign(vnm, t, virt=True)
+ ectx.eth_reg_type(vnm, t)
+ t.eth_reg_sub(vnm, ectx)
+ if self.val.has_key(field) and ectx.conform.check_item('PDU', cls + '.' + field):
+ 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))
+ return
+ # end of make_virtual_type()
+ if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
+ ectx.eth_reg_oassign(self)
+ if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
+ make_virtual_type(self.cls, '&Type', 'TYPE')
+ if (self.cls == 'OPERATION'):
+ make_virtual_type(self.cls, '&ArgumentType', 'ARG')
+ make_virtual_type(self.cls, '&ResultType', 'RES')
+ if (self.cls == 'ERROR'):
+ make_virtual_type(self.cls, '&ParameterType', 'PAR')
+
#--- Type ---------------------------------------------------------------------
class Type (Node):
def __init__(self,*args, **kw) :
self.name = None
self.constr = None
+ self.tags = []
+ self.named_list = None
Node.__init__ (self,*args, **kw)
def IsNamed(self):
else :
return True
+ def HasSizeConstraint(self):
+ return self.HasConstraint() and self.constr.IsSize()
+
+ def HasValueConstraint(self):
+ return self.HasConstraint() and self.constr.IsValue()
+
+ def HasPermAlph(self):
+ return self.HasConstraint() and self.constr.IsPermAlph()
+
+ def HasContentsConstraint(self):
+ return self.HasConstraint() and self.constr.IsContents()
+
def HasOwnTag(self):
- return self.__dict__.has_key('tag')
+ return len(self.tags) > 0
def HasImplicitTag(self, ectx):
- return (self.HasOwnTag() and
- ((self.tag.mode == 'IMPLICIT') or
- ((self.tag.mode == 'default') and (ectx.tag_def == 'IMPLICIT'))))
+ return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
def IndetermTag(self, ectx):
return False
- def SetTag(self, tag):
- self.tag = tag
+ def AddTag(self, tag):
+ self.tags[0:0] = [tag]
def GetTag(self, ectx):
#print "GetTag(%s)\n" % self.name;
if (self.HasOwnTag()):
- return self.tag.GetTag(ectx)
+ return self.tags[0].GetTag(ectx)
else:
return self.GetTTag(ectx)
print self.str_depth(1)
return ('BER_CLASS_unknown', 'TAG_unknown')
- def SetName(self, name) :
+ def SetName(self, name):
self.name = name
def AddConstraint(self, constr):
def eth_has_vals(self):
return False
+ def eth_has_enum(self, tname, ectx):
+ return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
+
+ def eth_need_pdu(self, ectx):
+ return None
+
def eth_named_bits(self):
return None
def eth_reg_sub(self, ident, ectx):
pass
- def eth_reg(self, ident, ectx, idx='', parent=None):
+ def get_components(self, ectx):
+ print "#Unhandled get_components() in %s" % (self.type)
+ print self.str_depth(1)
+ return []
+
+ def sel_req(self, sel, ectx):
+ print "#Selection '%s' required for non-CHOICE type %s" % (sel, self.type)
+ print self.str_depth(1)
+
+ def fld_obj_eq(self, other):
+ return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
+
+ def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
+ #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
+ if (ectx.Tag() and (len(self.tags) > tstrip)):
+ tagged_type = TaggedType(val=self, tstrip=tstrip)
+ tagged_type.AddTag(self.tags[tstrip])
+ if not tagflag: # 1st tagged level
+ if self.IsNamed() and not selflag:
+ tagged_type.SetName(self.name)
+ tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
+ return
nm = ''
- if ident and self.IsNamed ():
+ if ident and self.IsNamed() and not tagflag and not selflag:
nm = ident + '/' + self.name
- elif self.IsNamed():
- nm = self.name
elif ident:
nm = ident
- if not ident and ectx.conform.use_item('OMIT_ASSIGNMENT', nm): return # Assignment to omit
+ elif self.IsNamed():
+ nm = self.name
+ if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
if not ident: # Assignment
ectx.eth_reg_assign(nm, self)
if self.type == 'Type_Ref':
ectx.eth_reg_type(nm, self)
- if (ectx.conform.check_item('PDU', nm)):
- ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', nm))
- if self.type == 'Type_Ref':
- if ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm):
- ectx.eth_reg_type(nm, self) # new type
+ virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
+ if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
+ if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
+ if ectx.conform.check_item('SET_TYPE', nm):
+ ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
+ else:
+ ectx.eth_reg_type(nm, self) # new type
trnm = nm
+ elif ectx.conform.check_item('SET_TYPE', nm):
+ trnm = ectx.conform.use_item('SET_TYPE', nm)
else:
trnm = self.val
else:
ectx.eth_reg_type(nm, self)
- if ident:
- if self.type == 'Type_Ref':
- ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
- else:
- ectx.eth_reg_field(nm, nm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
- self.eth_reg_sub(nm, ectx)
-
- def eth_get_size_constr(self):
- (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
- if not self.HasConstraint():
- (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
- elif self.constr.IsSize():
- (minv, maxv, ext) = self.constr.GetSize()
- elif (self.constr.type == 'Intersection'):
- if self.constr.subtype[0].IsSize():
- (minv, maxv, ext) = self.constr.subtype[0].GetSize()
- elif self.constr.subtype[1].IsSize():
- (minv, maxv, ext) = self.constr.subtype[1].GetSize()
+ trnm = nm
+ if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
+ vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
+ ectx.eth_reg_assign(vnm, self, virt=True)
+ ectx.eth_reg_type(vnm, self)
+ self.eth_reg_sub(vnm, ectx)
+ if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
+ ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
+ if ident and not tagflag:
+ ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
+ if ectx.conform.check_item('SET_TYPE', nm):
+ virtual_tr.eth_reg_sub(nm, ectx)
+ else:
+ self.eth_reg_sub(nm, ectx)
+
+ def eth_get_size_constr(self, ectx):
+ (minv, maxv, ext) = ('MIN', 'MAX', False)
+ if self.HasSizeConstraint():
+ if self.constr.IsSize():
+ (minv, maxv, ext) = self.constr.GetSize(ectx)
+ if (self.constr.type == 'Intersection'):
+ if self.constr.subtype[0].IsSize():
+ (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
+ elif self.constr.subtype[1].IsSize():
+ (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
+ if minv == 'MIN': minv = 'NO_BOUND'
+ if maxv == 'MAX': maxv = 'NO_BOUND'
+ if (ext): ext = 'TRUE'
+ else: ext = 'FALSE'
return (minv, maxv, ext)
- def eth_get_value_constr(self):
- (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
- if not self.HasConstraint():
- (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
- elif self.constr.IsValue():
- (minv, maxv, ext) = self.constr.GetValue()
+ def eth_get_value_constr(self, ectx):
+ (minv, maxv, ext) = ('MIN', 'MAX', False)
+ if self.HasValueConstraint():
+ (minv, maxv, ext) = self.constr.GetValue(ectx)
+ if minv == 'MIN': minv = 'NO_BOUND'
+ if maxv == 'MAX': maxv = 'NO_BOUND'
+ if str(minv).isdigit(): minv += 'U'
+ if str(maxv).isdigit(): maxv += 'U'
+ if (ext): ext = 'TRUE'
+ else: ext = 'FALSE'
return (minv, maxv, ext)
+ def eth_get_alphabet_constr(self, ectx):
+ (alph, alphlen) = ('NULL', '0')
+ if self.HasPermAlph():
+ alph = self.constr.GetPermAlph(ectx)
+ if not alph:
+ alph = 'NULL'
+ if (alph != 'NULL'):
+ if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
+ alphlen = str(len(alph) - 2)
+ else:
+ alphlen = 'strlen(%s)' % (alph)
+ return (alph, alphlen)
+
def eth_type_vals(self, tname, ectx):
if self.eth_has_vals():
print "#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)
print self.str_depth(1)
return ''
+ def eth_type_enum(self, tname, ectx):
+ if self.eth_has_enum(tname, ectx):
+ print "#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)
+ print self.str_depth(1)
+ return ''
+
def eth_type_default_table(self, ectx, tname):
return ''
'TNAME' : tname,
'ER' : ectx.encp(),
'FN_VARIANT' : '',
- 'PINFO' : 'pinfo',
'TREE' : 'tree',
'TVB' : 'tvb',
- 'OFFSET' : 'offset',
+ 'OFFSET' : 'offset',
+ 'ACTX' : 'actx',
'HF_INDEX' : 'hf_index',
'VAL_PTR' : 'NULL',
'IMPLICIT_TAG' : 'implicit_tag',
- 'CREATED_ITEM_PTR' : 'NULL',
}
- if ectx.eth_type[tname]['tree']:
+ if (ectx.eth_type[tname]['tree']):
pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
+ if (ectx.merge_modules):
+ pars['PROTOP'] = ''
+ else:
+ pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
return pars
def eth_type_fn(self, proto, tname, ectx):
pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
pars['DEFAULT_BODY'] = body
for i in range(4):
- for k in pars.keys(): pars[k] = pars[k] % pars
+ for k in pars.keys():
+ try:
+ pars[k] = pars[k] % pars
+ except (TypeError):
+ raise sys.exc_type, "%s\n%s" % (str(pars), sys.exc_value)
out = '\n'
out += self.eth_type_default_table(ectx, tname) % pars
out += ectx.eth_type_fn_hdr(tname)
def SetName(self, name) :
self.name = name
- def to_str(self):
- return str(self)
+ def to_str(self, ectx):
+ return str(self.val)
def get_dep(self):
return None
+ def fld_obj_repr(self, ectx):
+ return self.to_str(ectx)
+
+#--- Value_Ref -----------------------------------------------------------------
+class Value_Ref (Value):
+ def to_str(self, ectx):
+ return asn2c(self.val)
+
+#--- ObjectClass ---------------------------------------------------------------------
+class ObjectClass (Node):
+ def __init__(self,*args, **kw) :
+ self.name = None
+ Node.__init__ (self,*args, **kw)
+
+ def SetName(self, name):
+ self.name = name
+ add_class_ident(self.name)
+
+ def eth_reg(self, ident, ectx):
+ if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
+ ectx.eth_reg_objectclass(self.name, self)
+
+#--- Class_Ref -----------------------------------------------------------------
+class Class_Ref (ObjectClass):
+ pass
+
+#--- ObjectClassDefn ---------------------------------------------------------------------
+class ObjectClassDefn (ObjectClass):
+ def reg_types(self):
+ for fld in self.fields:
+ repr = fld.fld_repr()
+ set_type_to_class(self.name, repr[0], repr[1:])
+
+
+#--- Tag ---------------------------------------------------------------
+class Tag (Node):
+ def to_python (self, ctx):
+ return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
+ self.tag_typ,
+ self.tag.num),
+ self.typ.to_python (ctx))
+ def IsImplicit(self, ectx):
+ return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
+
+ def GetTag(self, ectx):
+ tc = ''
+ if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
+ elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
+ elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
+ elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
+ return (tc, self.num)
+
+ def eth_tname(self):
+ n = ''
+ if (self.cls == 'UNIVERSAL'): n = 'U'
+ elif (self.cls == 'APPLICATION'): n = 'A'
+ elif (self.cls == 'CONTEXT'): n = 'C'
+ elif (self.cls == 'PRIVATE'): n = 'P'
+ return n + str(self.num)
+
#--- Constraint ---------------------------------------------------------------
class Constraint (Node):
def to_python (self, ctx):
def __str__ (self):
return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
+ def eth_tname(self):
+ return '#' + self.type + '_' + str(id(self))
+
def IsSize(self):
- return self.type == 'Size' and (self.subtype.type == 'SingleValue' or self.subtype.type == 'ValueRange')
+ return (self.type == 'Size' and self.subtype.IsValue()) \
+ or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
- def GetSize(self):
- minv = 'NO_BOUND'
- maxv = 'NO_BOUND'
- ext = 'FALSE'
+ def GetSize(self, ectx):
+ (minv, maxv, ext) = ('MIN', 'MAX', False)
if self.IsSize():
- if self.subtype.type == 'SingleValue':
- minv = self.subtype.subtype
- maxv = self.subtype.subtype
- else:
- minv = self.subtype.subtype[0]
- maxv = self.subtype.subtype[1]
- if hasattr(self.subtype, 'ext') and self.subtype.ext:
- ext = 'TRUE'
- else:
- ext = 'FALSE'
+ if self.type == 'Size':
+ (minv, maxv, ext) = self.subtype.GetValue(ectx)
+ elif self.type == 'Intersection':
+ if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
+ (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
+ elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
+ (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
return (minv, maxv, ext)
def IsValue(self):
- return self.type == 'SingleValue' or self.type == 'ValueRange'
+ return self.type == 'SingleValue' \
+ or self.type == 'ValueRange' \
+ or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
+ or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
- def GetValue(self):
- minv = 'NO_BOUND'
- maxv = 'NO_BOUND'
- ext = 'FALSE'
+ def GetValue(self, ectx):
+ (minv, maxv, ext) = ('MIN', 'MAX', False)
if self.IsValue():
if self.type == 'SingleValue':
- minv = self.subtype
- maxv = self.subtype
- else:
- if self.subtype[0] == 'MIN':
- minv = 'NO_BOUND'
- else:
- minv = self.subtype[0]
- if self.subtype[1] == 'MAX':
- maxv = 'NO_BOUND'
- else:
- maxv = self.subtype[1]
- if str(minv).isdigit(): minv += 'U'
- if str(maxv).isdigit(): maxv += 'U'
- if hasattr(self, 'ext') and self.ext:
- ext = 'TRUE'
- else:
- ext = 'FALSE'
+ minv = ectx.value_get_eth(self.subtype)
+ maxv = ectx.value_get_eth(self.subtype)
+ ext = hasattr(self, 'ext') and self.ext
+ elif self.type == 'ValueRange':
+ minv = ectx.value_get_eth(self.subtype[0])
+ maxv = ectx.value_get_eth(self.subtype[1])
+ ext = hasattr(self, 'ext') and self.ext
+ elif self.type == 'Intersection':
+ if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
+ (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
+ elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
+ (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
+ elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
+ v0 = self.subtype[0].GetValue(ectx)
+ v1 = self.subtype[1].GetValue(ectx)
+ (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
+ elif self.type == 'Union':
+ if self.subtype[0].IsValue() and self.subtype[1].IsValue():
+ v0 = self.subtype[0].GetValue(ectx)
+ v1 = self.subtype[1].GetValue(ectx)
+ (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
return (minv, maxv, ext)
+ def IsAlphabet(self):
+ return self.type == 'SingleValue' \
+ or self.type == 'ValueRange' \
+ or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
+ or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
+
+ def GetAlphabet(self, ectx):
+ alph = None
+ if self.IsAlphabet():
+ if self.type == 'SingleValue':
+ alph = ectx.value_get_eth(self.subtype)
+ elif self.type == 'ValueRange':
+ if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
+ and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
+ alph = '"'
+ for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
+ alph += chr(c)
+ alph += '"'
+ elif self.type == 'Union':
+ if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
+ a0 = self.subtype[0].GetAlphabet(ectx)
+ a1 = self.subtype[1].GetAlphabet(ectx)
+ if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
+ and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
+ alph = '"' + a0[1:-1] + a1[1:-1] + '"'
+ else:
+ alph = a0 + ' ' + a1
+ return alph
+
+ def IsPermAlph(self):
+ return self.type == 'From' and self.subtype.IsAlphabet() \
+ or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
+
+ def GetPermAlph(self, ectx):
+ alph = None
+ if self.IsPermAlph():
+ if self.type == 'From':
+ alph = self.subtype.GetAlphabet(ectx)
+ elif self.type == 'Intersection':
+ if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
+ alph = self.subtype[0].GetPermAlph(ectx)
+ elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
+ alph = self.subtype[1].GetPermAlph(ectx)
+ return alph
+
+ def IsContents(self):
+ return self.type == 'Contents' \
+ or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
+
+ def GetContents(self, ectx):
+ contents = None
+ if self.IsContents():
+ if self.type == 'Contents':
+ if self.subtype.type == 'Type_Ref':
+ contents = self.subtype.val
+ elif self.type == 'Intersection':
+ if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
+ contents = self.subtype[0].GetContents(ectx)
+ elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
+ contents = self.subtype[1].GetContents(ectx)
+ return contents
+
def IsNegativ(self):
def is_neg(sval):
- return sval[0] == '-'
+ return isinstance(sval, str) and (sval[0] == '-')
if self.type == 'SingleValue':
return is_neg(self.subtype)
elif self.type == 'ValueRange':
if self.subtype[0] == 'MIN': return True
return is_neg(self.subtype[0])
- return FALSE
-
- def IsPermAlph(self):
- return self.type == 'From' and self.subtype.type == 'SingleValue'
+ return False
def eth_constrname(self):
def int2str(val):
+ if isinstance(val, Value_Ref):
+ return asn2c(val.val)
try:
if (int(val) < 0):
return 'M' + str(-int(val))
else:
return str(val)
except (ValueError, TypeError):
- return str(val)
+ return asn2c(str(val))
ext = ''
if hasattr(self, 'ext') and self.ext:
return """#%s
%s""" % (self.ident, self.body.to_python (ctx))
- def to_eth (self, ectx):
+ def get_name(self):
+ return self.ident.val
+
+ def get_proto(self, ectx):
+ if (ectx.proto):
+ prot = ectx.proto
+ else:
+ prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name())
+ return prot
+
+ def to_eth(self, ectx):
ectx.tags_def = 'EXPLICIT' # default = explicit
- if (not ectx.proto):
- ectx.proto = ectx.conform.use_item('MODULE', self.ident.val, val_dflt=self.ident.val)
+ ectx.proto = self.get_proto(ectx)
ectx.tag_def = self.tag_def.dfl_tag
- ectx.modules.append((self.ident.val, ectx.proto))
+ ectx.eth_reg_module(self)
self.body.to_eth(ectx)
class Module_Body (Node):
- def to_python (self, ctx):
- # XXX handle exports, imports.
- l = map (lambda x: x.to_python (ctx), self.assign_list)
- l = [a for a in l if a <> '']
- return "\n".join (l)
-
- def to_eth(self, ectx):
- for i in self.imports:
- mod = i.module.val
- proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
- for s in i.symbol_list:
- if isinstance(s, Type_Ref):
- ectx.eth_import_type(s.val, mod, proto)
- else:
- ectx.eth_import_value(s, mod, proto)
- for a in self.assign_list:
- a.eth_reg('', ectx)
+ def to_python (self, ctx):
+ # XXX handle exports, imports.
+ l = map (lambda x: x.to_python (ctx), self.assign_list)
+ l = [a for a in l if a <> '']
+ return "\n".join (l)
+
+ def to_eth(self, ectx):
+ # Exports
+ ectx.eth_exports(self.exports)
+ # Imports
+ for i in self.imports:
+ mod = i.module.val
+ proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
+ ectx.eth_module_dep_add(ectx.Module(), mod)
+ for s in i.symbol_list:
+ if isinstance(s, Type_Ref):
+ ectx.eth_import_type(s.val, mod, proto)
+ elif isinstance(s, Value_Ref):
+ ectx.eth_import_value(s.val, mod, proto)
+ elif isinstance(s, Class_Ref):
+ ectx.eth_import_class(s.val, mod, proto)
+ else:
+ msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
+ warnings.warn_explicit(msg, UserWarning, '', '')
+ # AssignmentList
+ for a in self.assign_list:
+ a.eth_reg('', ectx)
class Default_Tags (Node):
def to_python (self, ctx): # not to be used directly
def eth_tname(self):
return asn2c(self.val)
+ def fld_obj_repr(self, ectx):
+ return self.val
+
+ def get_components(self, ectx):
+ if not ectx.type.has_key(self.val) or ectx.type[self.val]['import']:
+ msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
+ warnings.warn_explicit(msg, UserWarning, '', '')
+ return []
+ else:
+ return ectx.type[self.val]['val'].get_components(ectx)
+
def GetTTag(self, ectx):
#print "GetTTag(%s)\n" % self.val;
if (ectx.type[self.val]['import']):
if not ectx.type[self.val].has_key('ttag'):
- if not ectx.conform.check_item('IMPORT_TAG', self.val):
+ ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
+ if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
warnings.warn_explicit(msg, UserWarning, '', '')
- ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
+ ttag = ('-1 /*imported*/', '-1 /*imported*/')
+ ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
return ectx.type[self.val]['ttag']
else:
return ectx.type[self.val]['val'].GetTag(ectx)
return ectx.type[self.val]['val'].IndetermTag(ectx)
def eth_type_default_pars(self, ectx, tname):
- pars = Type.eth_type_default_pars(self, ectx, tname)
+ if tname:
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ else:
+ pars = {}
t = ectx.type[self.val]['ethname']
pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
pars['TYPE_REF_TNAME'] = t
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),))
+ par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
+ elif (ectx.Per()):
+ body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
+ else:
+ body = '#error Can not decode %s' % (tname)
+ return body
+
+#--- SelectionType ------------------------------------------------------------
+class SelectionType (Type):
+ def to_python (self, ctx):
+ return self.val
+
+ def sel_of_typeref(self):
+ return self.typ.type == 'Type_Ref'
+
+ def eth_reg_sub(self, ident, ectx):
+ if not self.sel_of_typeref():
+ self.seltype = ''
+ return
+ self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
+ ectx.eth_dep_add(ident, self.seltype)
+
+ def eth_ftype(self, ectx):
+ (ftype, display) = ('FT_NONE', 'BASE_NONE')
+ if self.sel_of_typeref() and not ectx.type[self.seltype]['import']:
+ (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx)
+ return (ftype, display)
+
+ def GetTTag(self, ectx):
+ #print "GetTTag(%s)\n" % self.seltype;
+ if (ectx.type[self.seltype]['import']):
+ if not ectx.type[self.seltype].has_key('ttag'):
+ if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
+ msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
+ warnings.warn_explicit(msg, UserWarning, '', '')
+ ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
+ return ectx.type[self.seltype]['ttag']
+ else:
+ return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
+
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ if self.sel_of_typeref():
+ t = ectx.type[self.seltype]['ethname']
+ pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
+ pars['TYPE_REF_TNAME'] = t
+ pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
+ return pars
+
+ def eth_type_default_body(self, ectx, tname):
+ if not self.sel_of_typeref():
+ body = '#error Can not decode %s' % (tname)
+ elif (ectx.Ber()):
+ body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
elif (ectx.Per()):
body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),))
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
+ else:
+ body = '#error Can not decode %s' % (tname)
+ return body
+
+#--- TaggedType -----------------------------------------------------------------
+class TaggedType (Type):
+ def eth_tname(self):
+ tn = ''
+ for i in range(self.tstrip, len(self.val.tags)):
+ tn += self.val.tags[i].eth_tname()
+ tn += '_'
+ tn += self.val.eth_tname()
+ return tn
+
+ def eth_set_val_name(self, ident, val_name, ectx):
+ #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
+ self.val_name = val_name
+ ectx.eth_dep_add(ident, self.val_name)
+
+ def eth_reg_sub(self, ident, ectx):
+ self.val_name = ident + '/' + '_untag'
+ self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
+
+ def GetTTag(self, ectx):
+ #print "GetTTag(%s)\n" % self.seltype;
+ return self.GetTag(ectx)
+
+ def eth_ftype(self, ectx):
+ return self.val.eth_ftype(ectx)
+
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ t = ectx.type[self.val_name]['ethname']
+ pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
+ pars['TYPE_REF_TNAME'] = t
+ pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
+ (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
+ if self.HasImplicitTag(ectx):
+ pars['TAG_IMPL'] = 'TRUE'
+ else:
+ pars['TAG_IMPL'] = 'FALSE'
+ return pars
+
+ def eth_type_default_body(self, ectx, tname):
+ if (ectx.Ber()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
else:
body = '#error Can not decode %s' % (tname)
return body
class SqType (Type):
def out_item(self, f, val, optional, ext, ectx):
ef = ectx.field[f]['ethname']
+ t = ectx.eth_hf[ef]['ethtype']
efd = ef
if (ectx.Ber() and ectx.field[f]['impl']):
efd += '_impl'
opt = 'ASN1_NOT_OPTIONAL'
if (ectx.Ber()):
(tc, tn) = val.GetTag(ectx)
- out = ' { %-13s, %s, %s, dissect_%s },\n' \
- % (tc, tn, opt, efd)
+ if (ectx.NewBer()):
+ out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
+ % ('&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
+ else:
+ out = ' { %-13s, %s, %s, dissect_%s },\n' \
+ % (tc, tn, opt, efd)
elif (ectx.Per()):
- out = ' { %-30s, %-23s, %-17s, dissect_%s },\n' \
- % ('"'+(val.name or '')+'"', ext, opt, efd)
+ out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
+ % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
else:
out = ''
return out
#--- SeqType -----------------------------------------------------------
class SeqType (SqType):
+
+ def need_components(self):
+ lst = self.elt_list[:]
+ if hasattr(self, 'ext_list'):
+ lst.extend(self.ext_list)
+ if hasattr(self, 'elt_list2'):
+ lst.extend(self.elt_list2)
+ for e in (lst):
+ if e.type == 'components_of':
+ return True
+ return False
+
+ def expand_components(self, ectx):
+ while self.need_components():
+ for i in range(len(self.elt_list)):
+ if self.elt_list[i].type == 'components_of':
+ comp = self.elt_list[i].typ.get_components(ectx)
+ self.elt_list[i:i+1] = comp
+ break
+ if hasattr(self, 'ext_list'):
+ for i in range(len(self.ext_list)):
+ if self.ext_list[i].type == 'components_of':
+ comp = self.ext_list[i].typ.get_components(ectx)
+ self.ext_list[i:i+1] = comp
+ break
+ if hasattr(self, 'elt_list2'):
+ for i in range(len(self.elt_list2)):
+ if self.elt_list2[i].type == 'components_of':
+ comp = self.elt_list2[i].typ.get_components(ectx)
+ self.elt_list2[i:i+1] = comp
+ break
+
+ def get_components(self, ectx):
+ lst = self.elt_list[:]
+ if hasattr(self, 'elt_list2'):
+ lst.extend(self.elt_list2)
+ return lst
+
def eth_type_default_table(self, ectx, tname):
#print "eth_type_default_table(tname='%s')" % (tname)
fname = ectx.eth_type[tname]['ref'][0]
- table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
+ if (ectx.Ber()):
+ if (ectx.NewBer()):
+ table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
+ else:
+ table = "static const %(ER)s_old_sequence_t %(TABLE)s[] = {\n"
+ else:
+ table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
if hasattr(self, 'ext_list'):
ext = 'ASN1_EXTENSION_ROOT'
else:
for e in (self.ext_list):
f = fname + '/' + e.val.name
table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
+ if hasattr(self, 'elt_list2'):
+ for e in (self.elt_list2):
+ f = fname + '/' + e.val.name
+ table += self.out_item(f, e.val, e.optional, ext, ectx)
if (ectx.Ber()):
- table += " { 0, 0, 0, NULL }\n};\n"
+ if (ectx.NewBer()):
+ table += " { NULL, 0, 0, 0, NULL }\n};\n"
+ else:
+ table += " { 0, 0, 0, NULL }\n};\n"
else:
table += " { NULL, 0, 0, NULL }\n};\n"
return table
f = fname + '/' + self.val.name
else:
f = fname + '/' + '_item'
- table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
+ if (ectx.Ber()):
+ if (ectx.NewBer()):
+ table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
+ else:
+ table = "static const %(ER)s_old_sequence_t %(TABLE)s[1] = {\n"
+ else:
+ table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
table += "};\n"
return table
itmnm = ident
if not self.val.IsNamed ():
itmnm += '/' + '_item'
- self.val.eth_reg(itmnm, ectx, idx='[##]', parent=ident)
+ self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
def eth_tname(self):
if self.val.type != 'Type_Ref':
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
- pars['TABLE'] = '%(TNAME)s_sequence_of'
+ (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
return pars
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
- body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ if (ectx.NewBer()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
+ else:
+ body = ectx.eth_fn_call('dissect_%(ER)s_old_sequence_of', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
elif (ectx.Per() and not self.HasConstraint()):
body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(ETT_INDEX)s', '%(TABLE)s',),))
elif (ectx.Per() and self.constr.type == 'Size'):
body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(ETT_INDEX)s', '%(TABLE)s',),
('%(MIN_VAL)s', '%(MAX_VAL)s',),))
else:
itmnm = ident
if not self.val.IsNamed ():
itmnm += '/' + '_item'
- self.val.eth_reg(itmnm, ectx, idx='(##)', parent=ident)
+ self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
def eth_tname(self):
if self.val.type != 'Type_Ref':
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
- pars['TABLE'] = '%(TNAME)s_set_of'
+ (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
return pars
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
- body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ if (ectx.NewBer()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
+ else:
+ body = ectx.eth_fn_call('dissect_%(ER)s_old_set_of', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
elif (ectx.Per() and not self.HasConstraint()):
body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(ETT_INDEX)s', '%(TABLE)s',),))
elif (ectx.Per() and self.constr.type == 'Size'):
body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(ETT_INDEX)s', '%(TABLE)s',),
('%(MIN_VAL)s', '%(MAX_VAL)s',),))
else:
typ = ctx.tags_def
return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
-class Tag (Node):
- def to_python (self, ctx):
- return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
- self.tag_typ,
- self.tag.num),
- self.typ.to_python (ctx))
- def GetTag(self, ectx):
- tc = ''
- if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
- elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
- elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
- elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
- return (tc, self.num)
-
#--- SequenceType -------------------------------------------------------------
class SequenceType (SeqType):
def to_python (self, ctx):
ctx.outdent ()
return rv
- def eth_reg_sub(self, ident, ectx):
- for e in (self.elt_list):
- e.val.eth_reg(ident, ectx, parent=ident)
- if hasattr(self, 'ext_list'):
- for e in (self.ext_list):
- e.val.eth_reg(ident, ectx, parent=ident)
+ def eth_reg_sub(self, ident, ectx, components_available=False):
+ if self.need_components():
+ if components_available:
+ self.expand_components(ectx)
+ else:
+ ectx.eth_comp_req(ident)
+ return
+ for e in (self.elt_list):
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
+ if hasattr(self, 'ext_list'):
+ for e in (self.ext_list):
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
+ if hasattr(self, 'elt_list2'):
+ for e in (self.elt_list2):
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
def eth_need_tree(self):
return True
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- pars['TABLE'] = '%(TNAME)s_sequence'
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
return pars
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
- body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ if(ectx.NewBer()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
+ else:
+ body = ectx.eth_fn_call('dissect_%(ER)s_old_sequence', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
elif (ectx.Per()):
body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(ETT_INDEX)s', '%(TABLE)s',),))
else:
body = '#error Can not decode %s' % (tname)
#--- SetType ------------------------------------------------------------------
class SetType(SeqType):
- def eth_reg_sub(self, ident, ectx):
+
+ def eth_reg_sub(self, ident, ectx, components_available=False):
+ if self.need_components():
+ if components_available:
+ self.expand_components(ectx)
+ else:
+ ectx.eth_comp_req(ident)
+ return
for e in (self.elt_list):
- e.val.eth_reg(ident, ectx, parent=ident)
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
if hasattr(self, 'ext_list'):
for e in (self.ext_list):
- e.val.eth_reg(ident, ectx, parent=ident)
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
def eth_need_tree(self):
return True
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- pars['TABLE'] = '%(TNAME)s_set'
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
return pars
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
- body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ if(ectx.NewBer()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
+ else:
+ body = ectx.eth_fn_call('dissect_%(ER)s_old_set', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
elif (ectx.Per()):
body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(ETT_INDEX)s', '%(TABLE)s',),))
else:
body = '#error Can not decode %s' % (tname)
return rv
def eth_reg_sub(self, ident, ectx):
- #print "eth_reg_sub(ident='%s')" % (ident)
- for e in (self.elt_list):
- e.eth_reg(ident, ectx, parent=ident)
- if hasattr(self, 'ext_list'):
- for e in (self.ext_list):
- e.eth_reg(ident, ectx, parent=ident)
+ #print "eth_reg_sub(ident='%s')" % (ident)
+ for e in (self.elt_list):
+ e.eth_reg(ident, ectx, tstrip=1, parent=ident)
+ if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
+ ectx.eth_sel_req(ident, e.name)
+ if hasattr(self, 'ext_list'):
+ for e in (self.ext_list):
+ e.eth_reg(ident, ectx, tstrip=1, parent=ident)
+ if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
+ ectx.eth_sel_req(ident, e.name)
+
+ def sel_item(self, ident, sel, ectx):
+ lst = self.elt_list[:]
+ if hasattr(self, 'ext_list'):
+ lst.extend(self.ext_list)
+ ee = None
+ for e in (self.elt_list):
+ if e.IsNamed() and (e.name == sel):
+ ee = e
+ break
+ if not ee:
+ print "#CHOICE %s does not contain item %s" % (ident, sel)
+ return ee
+
+ def sel_req(self, ident, sel, ectx):
+ #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
+ ee = self.sel_item(ident, sel, ectx)
+ if ee:
+ ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
def eth_ftype(self, ectx):
return ('FT_UINT32', 'BASE_DEC')
+ def eth_ftype_sel(self, sel, ectx):
+ ee = self.sel_item('', sel, ectx)
+ if ee:
+ return ee.eth_ftype(ectx)
+ else:
+ return ('FT_NONE', 'BASE_NONE')
+
def eth_strings(self):
return '$$'
# cls = '-1/*choice*/'
return (cls, '-1/*choice*/')
+ def GetTTagSel(self, sel, ectx):
+ ee = self.sel_item('', sel, ectx)
+ if ee:
+ return ee.GetTag(ectx)
+ else:
+ return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
+
def IndetermTag(self, ectx):
#print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
return not self.HasOwnTag()
- def eth_type_vals(self, tname, ectx):
- out = '\n'
+ def get_vals(self, ectx):
tagval = False
if (ectx.Ber()):
- lst = self.elt_list
+ lst = self.elt_list[:]
if hasattr(self, 'ext_list'):
lst.extend(self.ext_list)
if (len(lst) > 0):
else: val = str(cnt)
vals.append((val, e.name))
cnt += 1
+ return vals
+
+ def eth_type_vals(self, tname, ectx):
+ out = '\n'
+ vals = self.get_vals(ectx)
out += ectx.eth_vals(tname, vals)
return out
+ def eth_type_enum(self, tname, ectx):
+ out = '\n'
+ vals = self.get_vals(ectx)
+ out += ectx.eth_enum(tname, vals)
+ return out
+
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- pars['TABLE'] = '%(TNAME)s_choice'
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
return pars
def eth_type_default_table(self, ectx, tname):
def out_item(val, e, ext, ectx):
+ has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
+ if (has_enum):
+ vval = ectx.eth_enum_item(tname, e.name)
+ else:
+ vval = val
f = fname + '/' + e.name
ef = ectx.field[f]['ethname']
+ t = ectx.eth_hf[ef]['ethtype']
efd = ef
if (ectx.field[f]['impl']):
efd += '_impl'
opt = ''
if (not e.HasOwnTag()):
opt = 'BER_FLAGS_NOOWNTAG'
- elif (e.tag.mode == 'IMPLICIT'):
+ elif (e.HasImplicitTag(ectx)):
if (opt): opt += '|'
opt += 'BER_FLAGS_IMPLTAG'
if (not opt): opt = '0'
if (ectx.Ber()):
(tc, tn) = e.GetTag(ectx)
- out = ' { %3s, %-13s, %s, %s, dissect_%s },\n' \
- % (val, tc, tn, opt, efd)
+ if (ectx.NewBer()):
+ out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
+ % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
+ else:
+ out = ' { %3s, %-13s, %s, %s, dissect_%s },\n' \
+ % (vval, tc, tn, opt, efd)
elif (ectx.Per()):
- out = ' { %3s, %-30s, %-23s, dissect_%s },\n' \
- % (val, '"'+e.name+'"', ext, efd)
+ out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
+ % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
else:
out = ''
return out
fname = ectx.eth_type[tname]['ref'][0]
tagval = False
if (ectx.Ber()):
- lst = self.elt_list
+ lst = self.elt_list[:]
if hasattr(self, 'ext_list'):
lst.extend(self.ext_list)
if (len(lst) > 0):
for e in (lst):
if (e.GetTag(ectx)[0] != t):
tagval = False
- table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
+ if (ectx.Ber()):
+ if (ectx.NewBer()):
+ table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
+ else:
+ table = "static const %(ER)s_old_choice_t %(TABLE)s[] = {\n"
+ else:
+ table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
cnt = 0
if hasattr(self, 'ext_list'):
ext = 'ASN1_EXTENSION_ROOT'
table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
cnt += 1
if (ectx.Ber()):
- table += " { 0, 0, 0, 0, NULL }\n};\n"
+ if (ectx.NewBer()):
+ table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
+ else:
+ table += " { 0, 0, 0, 0, NULL }\n};\n"
else:
table += " { 0, NULL, 0, NULL }\n};\n"
return table
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
- body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
- par=(('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ if (ectx.NewBer()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
+ par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
+ ('%(VAL_PTR)s',),))
+ else:
+ body = ectx.eth_fn_call('dissect_%(ER)s_old_choice', ret='offset',
+ par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
('%(VAL_PTR)s',),))
elif (ectx.Per()):
body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(ETT_INDEX)s', '%(TABLE)s',),
('%(VAL_PTR)s',),))
else:
body = '#error Can not decode %s' % (tname)
return body
+#--- ChoiceValue ----------------------------------------------------
+class ChoiceValue (Value):
+ def to_str(self, ectx):
+ return self.val.to_str(ectx)
+
+ def fld_obj_eq(self, other):
+ return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
+
#--- EnumeratedType -----------------------------------------------------------
class EnumeratedType (Type):
def to_python (self, ctx):
out += ectx.eth_vals(tname, vals)
return out
+ def reg_enum_vals(self, tname, ectx):
+ vals = self.get_vals_etc(ectx)[0]
+ for (val, id) in vals:
+ ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
+
+ def eth_type_enum(self, tname, ectx):
+ out = '\n'
+ vals = self.get_vals_etc(ectx)[0]
+ out += ectx.eth_enum(tname, vals)
+ return out
+
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
(root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
pars['EXT'] = ext
pars['EXT_NUM'] = str(ext_num)
if (map_table):
- pars['TABLE'] = '%(TNAME)s_value_map'
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
else:
pars['TABLE'] = 'NULL'
return pars
def eth_type_default_table(self, ectx, tname):
- if (not ectx.Per()): return ''
+ if (not ectx.Per()): return ''
map_table = self.get_vals_etc(ectx)[3]
if (map_table == None): return ''
table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
('%(VAL_PTR)s',),))
elif (ectx.Per()):
body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
- ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(CREATED_ITEM_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
+ ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
else:
body = '#error Can not decode %s' % (tname)
return body
-#--- AnyType -----------------------------------------------------------
-class AnyType (Type):
- def to_python (self, ctx):
- return "asn1.ANY"
+#--- EmbeddedPDVType -----------------------------------------------------------
+class EmbeddedPDVType (Type):
+ def eth_tname(self):
+ return 'EMBEDDED_PDV'
def eth_ftype(self, ectx):
return ('FT_NONE', 'BASE_NONE')
def GetTTag(self, ectx):
- return ('BER_CLASS_ANY', '0')
+ return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
+
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ if ectx.default_embedded_pdv_cb:
+ pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb
+ else:
+ pars['TYPE_REF_FN'] = 'NULL'
+ return pars
def eth_type_default_body(self, ectx, tname):
- body = '#error Can not decode %s' % (tname)
+ if (ectx.Ber()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
+ elif (ectx.Per()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
+ else:
+ body = '#error Can not decode %s' % (tname)
return body
-class Literal (Node):
- def to_python (self, ctx):
- return self.val
-
-#--- NullType -----------------------------------------------------------------
-class NullType (Type):
- def to_python (self, ctx):
- return 'asn1.NULL'
-
+#--- ExternalType -----------------------------------------------------------
+class ExternalType (Type):
def eth_tname(self):
- return 'NULL'
+ return 'EXTERNAL'
+
+ def eth_ftype(self, ectx):
+ return ('FT_NONE', 'BASE_NONE')
def GetTTag(self, ectx):
- return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
+ return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
+
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ if ectx.default_external_type_cb:
+ pars['TYPE_REF_FN'] = ectx.default_external_type_cb
+ else:
+ pars['TYPE_REF_FN'] = 'NULL'
+ return pars
def eth_type_default_body(self, ectx, tname):
- if (ectx.Ber()):
- body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
+ if (ectx.Ber()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
+ elif (ectx.Per()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
+ else:
+ body = '#error Can not decode %s' % (tname)
+ return body
+
+#--- OpenType -----------------------------------------------------------
+class OpenType (Type):
+ def to_python (self, ctx):
+ return "asn1.ANY"
+
+ def single_type(self):
+ if (self.HasConstraint() and
+ self.constr.type == 'Type' and
+ self.constr.subtype.type == 'Type_Ref'):
+ return self.constr.subtype.val
+ return None
+
+ def eth_reg_sub(self, ident, ectx):
+ t = self.single_type()
+ if t:
+ ectx.eth_dep_add(ident, t)
+
+ def eth_tname(self):
+ t = self.single_type()
+ if t:
+ return 'OpenType_' + t
+ else:
+ return Type.eth_tname(self)
+
+ def eth_ftype(self, ectx):
+ return ('FT_NONE', 'BASE_NONE')
+
+ def GetTTag(self, ectx):
+ return ('BER_CLASS_ANY', '0')
+
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ pars['FN_VARIANT'] = ectx.default_opentype_variant
+ t = self.single_type()
+ if t:
+ t = ectx.type[t]['ethname']
+ pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
+ pars['TYPE_REF_TNAME'] = t
+ pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
+ else:
+ pars['TYPE_REF_FN'] = 'NULL'
+ return pars
+
+ def eth_type_default_body(self, ectx, tname):
+ if (ectx.Per()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
+ else:
+ body = '#error Can not decode %s' % (tname)
+ return body
+
+#--- InstanceOfType -----------------------------------------------------------
+class InstanceOfType (Type):
+ def eth_tname(self):
+ return 'INSTANCE_OF'
+
+ def eth_ftype(self, ectx):
+ return ('FT_NONE', 'BASE_NONE')
+
+ def GetTTag(self, ectx):
+ return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
+
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ if ectx.default_external_type_cb:
+ pars['TYPE_REF_FN'] = ectx.default_external_type_cb
+ else:
+ pars['TYPE_REF_FN'] = 'NULL'
+ return pars
+
+ def eth_type_default_body(self, ectx, tname):
+ if (ectx.Ber()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
+ elif (ectx.Per()):
+ body = '#error Can not decode %s' % (tname)
+ else:
+ body = '#error Can not decode %s' % (tname)
+ return body
+
+#--- AnyType -----------------------------------------------------------
+class AnyType (Type):
+ def to_python (self, ctx):
+ return "asn1.ANY"
+
+ def eth_ftype(self, ectx):
+ return ('FT_NONE', 'BASE_NONE')
+
+ def GetTTag(self, ectx):
+ return ('BER_CLASS_ANY', '0')
+
+ def eth_type_default_body(self, ectx, tname):
+ body = '#error Can not decode %s' % (tname)
+ return body
+
+class Literal (Node):
+ def to_python (self, ctx):
+ return self.val
+
+#--- NullType -----------------------------------------------------------------
+class NullType (Type):
+ def to_python (self, ctx):
+ return 'asn1.NULL'
+
+ def eth_tname(self):
+ return 'NULL'
+
+ def GetTTag(self, ectx):
+ return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
+
+ def eth_type_default_body(self, ectx, tname):
+ if (ectx.Ber()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
elif (ectx.Per()):
body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),))
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
else:
body = '#error Can not decode %s' % (tname)
return body
+#--- NullValue ----------------------------------------------------
+class NullValue (Value):
+ def to_str(self, ectx):
+ return 'NULL'
+
#--- RealType -----------------------------------------------------------------
class RealType (Type):
def to_python (self, ctx):
def eth_tname(self):
return 'REAL'
+ def GetTTag(self, ectx):
+ return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
+
+ def eth_ftype(self, ectx):
+ return ('FT_DOUBLE', 'BASE_NONE')
+
def eth_type_default_body(self, ectx, tname):
- body = '#error Can not decode %s' % (tname)
+ if (ectx.Ber()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
+ ('%(VAL_PTR)s',),))
+ elif (ectx.Per()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
+ else:
+ body = '#error Can not decode %s' % (tname)
return body
#--- BooleanType --------------------------------------------------------------
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
elif (ectx.Per()):
body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
- ('%(VAL_PTR)s', '%(CREATED_ITEM_PTR)s'),))
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
else:
body = '#error Can not decode %s' % (tname)
return body
def eth_tname(self):
if not self.HasConstraint():
return 'OCTET_STRING'
- elif self.constr.IsSize():
+ elif self.constr.type == 'Size':
return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
else:
return '#' + self.type + '_' + str(id(self))
def GetTTag(self, ectx):
return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
+ def eth_need_pdu(self, ectx):
+ pdu = None
+ if self.HasContentsConstraint():
+ t = self.constr.GetContents(ectx)
+ if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
+ pdu = { 'type' : t,
+ 'new' : ectx.default_containing_variant == '_pdu_new' }
+ return pdu
+
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
+ (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
+ if self.HasContentsConstraint():
+ pars['FN_VARIANT'] = ectx.default_containing_variant
+ t = self.constr.GetContents(ectx)
+ if t:
+ if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
+ t = ectx.field[t]['ethname']
+ pars['TYPE_REF_PROTO'] = ''
+ pars['TYPE_REF_TNAME'] = t
+ pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
+ else:
+ t = ectx.type[t]['ethname']
+ pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
+ pars['TYPE_REF_TNAME'] = t
+ pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
+ else:
+ pars['TYPE_REF_FN'] = 'NULL'
return pars
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
('%(VAL_PTR)s',),))
elif (ectx.Per()):
- body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
- ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s',),))
+ if self.HasContentsConstraint():
+ body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
+ ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TYPE_REF_FN)s',),))
+ else:
+ body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
+ ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s',),))
else:
body = '#error Can not decode %s' % (tname)
return body
def eth_tname(self):
if not self.HasConstraint():
return self.eth_tsname()
- elif self.constr.IsSize():
+ elif self.constr.type == 'Size':
return self.eth_tsname() + '_' + self.constr.eth_constrname()
else:
return '#' + self.type + '_' + str(id(self))
def GetTTag(self, ectx):
return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
- def HasPermAlph(self):
- return (self.HasConstraint() and
- (self.constr.IsPermAlph() or
- (self.constr.type == 'Intersection' and (self.constr.subtype[0].IsPermAlph() or self.constr.subtype[1].IsPermAlph()))
- )
- )
-
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
+ (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
(pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
- (pars['ALPHABET'], pars['ALPHABET_LEN']) = ('NULL', '0')
- if self.HasPermAlph():
- if self.constr.IsPermAlph():
- pars['ALPHABET'] = self.constr.subtype.subtype
- elif self.constr.subtype[0].IsPermAlph():
- pars['ALPHABET'] = self.constr.subtype[0].subtype.subtype
- elif self.constr.subtype[1].IsPermAlph():
- pars['ALPHABET'] = self.constr.subtype[1].subtype.subtype
- pars['ALPHABET_LEN'] = 'strlen(%(ALPHABET)s)'
+ (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
return pars
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
- ('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
+ ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
('%(VAL_PTR)s',),))
elif (ectx.Per() and self.HasPermAlph()):
body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(MIN_VAL)s', '%(MAX_VAL)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
('%(VAL_PTR)s',),))
elif (ectx.Per()):
if (self.eth_tsname() == 'GeneralString'):
body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),))
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
elif (self.eth_tsname() == 'GeneralizedTime'):
body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(MIN_VAL)s', '%(MAX_VAL)s',),))
elif (self.eth_tsname() == 'UTCTime'):
body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(MIN_VAL)s', '%(MAX_VAL)s',),))
else:
body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
('%(MIN_VAL)s', '%(MAX_VAL)s',),))
else:
body = '#error Can not decode %s' % (tname)
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
return body
else:
return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
def eth_tsname(self):
return 'ObjectDescriptor'
+ def eth_type_default_body(self, ectx, tname):
+ if (ectx.Ber()):
+ body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
+ elif (ectx.Per()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
+ else:
+ body = '#error Can not decode %s' % (tname)
+ return body
#--- ObjectIdentifierType -----------------------------------------------------
class ObjectIdentifierType (Type):
def GetTTag(self, ectx):
return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ pars['FN_VARIANT'] = ectx.default_oid_variant
+ return pars
+
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
elif (ectx.Per()):
body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
else:
body = '#error Can not decode %s' % (tname)
return body
def get_num(self, path, val):
return str(oid_names.get(path + '/' + val, val))
- def to_str(self):
+ def to_str(self, ectx):
out = ''
path = ''
first = True
vstr = v
else:
vstr = self.get_num(path, v)
+ if not first and not vstr.isdigit():
+ vstr = ectx.value_get_val(vstr)
if first:
if vstr.isdigit():
out += '"' + vstr
else:
- out += vstr + '"'
+ out += ectx.value_get_eth(vstr) + '"'
else:
out += sep + vstr
path += sep + vstr
else:
return vstr
-class NamedNumber (Node):
+class NamedNumber(Node):
def to_python (self, ctx):
return "('%s',%s)" % (self.ident, self.val)
return "asn1.INTEGER_class ([%s])" % (",".join (
map (lambda x: x.to_python (ctx), self.named_list)))
+ def add_named_value(self, ident, val):
+ e = NamedNumber(ident = ident, val = val)
+ if not self.named_list:
+ self.named_list = []
+ self.named_list.append(e)
+
def eth_tname(self):
if self.named_list:
return Type.eth_tname(self)
def GetTTag(self, ectx):
return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
+
def eth_ftype(self, ectx):
if self.HasConstraint():
if not self.constr.IsNegativ():
else:
return False
- def eth_type_vals(self, tname, ectx):
- if not self.eth_has_vals(): return ''
- out = '\n'
+ def get_vals(self, ectx):
vals = []
for e in (self.named_list):
vals.append((int(e.val), e.ident))
+ return vals
+
+ def eth_type_vals(self, tname, ectx):
+ if not self.eth_has_vals(): return ''
+ out = '\n'
+ vals = self.get_vals(ectx)
out += ectx.eth_vals(tname, vals)
return out
+ def reg_enum_vals(self, tname, ectx):
+ vals = self.get_vals(ectx)
+ for (val, id) in vals:
+ ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
+
+ def eth_type_enum(self, tname, ectx):
+ if not self.eth_has_enum(tname, ectx): return ''
+ out = '\n'
+ vals = self.get_vals(ectx)
+ out += ectx.eth_enum(tname, vals)
+ return out
+
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- if self.HasConstraint() and self.constr.IsValue():
- (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr()
+ if self.HasValueConstraint():
+ (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
return pars
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
('%(VAL_PTR)s',),))
- elif (ectx.Per() and not self.HasConstraint()):
+ elif (ectx.Per() and not self.HasValueConstraint()):
body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
- ('%(VAL_PTR)s', '%(CREATED_ITEM_PTR)s'),))
- elif (ectx.Per() and ((self.constr.type == 'SingleValue') or (self.constr.type == 'ValueRange'))):
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
+ elif (ectx.Per() and self.HasValueConstraint()):
body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
- ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(CREATED_ITEM_PTR)s', '%(EXT)s'),))
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
+ ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
else:
body = '#error Can not decode %s' % (tname)
return body
def eth_need_tree(self):
return self.named_list
+ def eth_need_pdu(self, ectx):
+ pdu = None
+ if self.HasContentsConstraint():
+ t = self.constr.GetContents(ectx)
+ if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
+ pdu = { 'type' : t,
+ 'new' : ectx.default_containing_variant == '_pdu_new' }
+ return pdu
+
def eth_named_bits(self):
bits = []
if (self.named_list):
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
+ (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
if not pars.has_key('ETT_INDEX'):
pars['ETT_INDEX'] = '-1'
pars['TABLE'] = 'NULL'
if self.eth_named_bits():
- pars['TABLE'] = '%(TNAME)s_bits'
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
+ if self.HasContentsConstraint():
+ pars['FN_VARIANT'] = ectx.default_containing_variant
+ t = self.constr.GetContents(ectx)
+ if t:
+ if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
+ t = ectx.field[t]['ethname']
+ pars['TYPE_REF_PROTO'] = ''
+ pars['TYPE_REF_TNAME'] = t
+ pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
+ else:
+ t = ectx.type[t]['ethname']
+ pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
+ pars['TYPE_REF_TNAME'] = t
+ pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
+ else:
+ pars['TYPE_REF_FN'] = 'NULL'
return pars
def eth_type_default_table(self, ectx, tname):
def eth_type_default_body(self, ectx, tname):
if (ectx.Ber()):
body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
- par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
+ par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
('%(VAL_PTR)s',),))
elif (ectx.Per()):
- body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
- par=(('%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),
- ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
+ if self.HasContentsConstraint():
+ body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
+ ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
+ else:
+ body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
+ ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s'),))
else:
body = '#error Can not decode %s' % (tname)
return body
+#--- BStringValue ------------------------------------------------------------
+bstring_tab = {
+ '0000' : '0',
+ '0001' : '1',
+ '0010' : '2',
+ '0011' : '3',
+ '0100' : '4',
+ '0101' : '5',
+ '0110' : '6',
+ '0111' : '7',
+ '1000' : '8',
+ '1001' : '9',
+ '1010' : 'A',
+ '1011' : 'B',
+ '1100' : 'C',
+ '1101' : 'D',
+ '1110' : 'E',
+ '1111' : 'F',
+}
+class BStringValue (Value):
+ def to_str(self, ectx):
+ v = self.val[1:-2]
+ if len(v) % 8:
+ v += '0' * (8 - len(v) % 8)
+ vv = '0x'
+ for i in (range(0, len(v), 4)):
+ vv += bstring_tab[v[i:i+4]]
+ return vv
+
+#--- HStringValue ------------------------------------------------------------
+class HStringValue (Value):
+ def to_str(self, ectx):
+ vv = '0x'
+ vv += self.val[1:-2]
+ return vv
+
+#--- FieldSpec ----------------------------------------------------------------
+class FieldSpec (Node):
+ def __init__(self,*args, **kw) :
+ self.name = None
+ Node.__init__ (self,*args, **kw)
+
+ def SetName(self, name):
+ self.name = name
+
+ def get_repr(self):
+ return ['#UNSUPPORTED_' + self.type]
+
+ def fld_repr(self):
+ repr = [self.name]
+ repr.extend(self.get_repr())
+ return repr
+
+class TypeFieldSpec (FieldSpec):
+ def get_repr(self):
+ return []
+
+class FixedTypeValueFieldSpec (FieldSpec):
+ def get_repr(self):
+ if isinstance(self.typ, Type_Ref):
+ repr = ['TypeReference', self.typ.val]
+ else:
+ repr = [self.typ.type]
+ return repr
+
+class FixedTypeValueSetFieldSpec (FieldSpec):
+ pass
+
+class ObjectFieldSpec (FieldSpec):
+ def get_repr(self):
+ return ['ClassReference', self.cls]
+
+class ObjectSetFieldSpec (FieldSpec):
+ def get_repr(self):
+ return ['ClassReference', self.cls]
#==============================================================================
def p_module_list_1 (t):
- 'module_list : module_list module_def'
+ 'module_list : module_list ModuleDefinition'
t[0] = t[1] + [t[2]]
def p_module_list_2 (t):
- 'module_list : module_def'
+ 'module_list : ModuleDefinition'
t[0] = [t[1]]
# 11.2 Type references
def p_type_ref (t):
- 'type_ref : UCASE_IDENT'
- t[0] = Type_Ref(val=t[1])
+ 'type_ref : UCASE_IDENT'
+ t[0] = Type_Ref(val=t[1])
+
+# 11.3 Identifiers
+def p_identifier (t):
+ 'identifier : LCASE_IDENT'
+ t[0] = t[1]
# 11.4 Value references
def p_valuereference (t):
- 'valuereference : LCASE_IDENT'
- t[0] = t[1]
+ 'valuereference : LCASE_IDENT'
+ t[0] = Value_Ref(val=t[1])
+
+# 11.5 Module references
+def p_modulereference (t):
+ 'modulereference : UCASE_IDENT'
+ t[0] = t[1]
# 12 Module definition --------------------------------------------------------
# 12.1
-def p_module_def (t):
- 'module_def : module_ident DEFINITIONS TagDefault ASSIGNMENT BEGIN module_body END'
- t[0] = Module (ident = t[1], tag_def = t[3], body = t[6])
+def p_ModuleDefinition (t):
+ 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT BEGIN ModuleBody END'
+ t[0] = Module (ident = t[1], tag_def = t[3], body = t[6])
def p_TagDefault_1 (t):
- '''TagDefault : EXPLICIT TAGS
- | IMPLICIT TAGS
- | AUTOMATIC TAGS'''
- t[0] = Default_Tags (dfl_tag = t[1])
+ '''TagDefault : EXPLICIT TAGS
+ | IMPLICIT TAGS
+ | AUTOMATIC TAGS'''
+ t[0] = Default_Tags (dfl_tag = t[1])
def p_TagDefault_2 (t):
- 'TagDefault : '
- # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
- t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
+ 'TagDefault : '
+ # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
+ t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
-def p_module_ident (t):
- 'module_ident : type_ref assigned_ident' # name, oid
- # XXX coerce type_ref to module_ref
- t [0] = Node('module_ident', val = t[1].val, ident = t[2])
+def p_ModuleIdentifier_1 (t):
+ 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
+ t [0] = Node('module_ident', val = t[1], ident = t[2])
+def p_ModuleIdentifier_2 (t):
+ 'ModuleIdentifier : modulereference' # name, oid
+ t [0] = Node('module_ident', val = t[1], ident = None)
-# XXX originally we had both type_ref and module_ref, but that caused
-# a reduce/reduce conflict (because both were UCASE_IDENT). Presumably
-# this didn't cause a problem in the original ESNACC grammar because it
-# was LALR(1) and PLY is (as of 1.1) only SLR.
+def p_DefinitiveIdentifier (t):
+ 'DefinitiveIdentifier : ObjectIdentifierValue'
+ t[0] = t[1]
#def p_module_ref (t):
# 'module_ref : UCASE_IDENT'
# t[0] = t[1]
-def p_assigned_ident_1 (t):
- 'assigned_ident : ObjectIdentifierValue'
- t[0] = t[1]
+def p_ModuleBody_1 (t):
+ 'ModuleBody : Exports Imports AssignmentList'
+ t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
-def p_assigned_ident_2 (t):
- 'assigned_ident : LCASE_IDENT'
- t[0] = t[1]
+def p_ModuleBody_2 (t):
+ 'ModuleBody : '
+ t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
-def p_assigned_ident_3 (t):
- 'assigned_ident : '
- pass
-
-def p_module_body_1 (t):
- 'module_body : exports Imports AssignmentList'
- t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
-
-def p_module_body_2 (t):
- 'module_body : '
- t[0] = Node ('module_body', exports = [], imports = [],
- assign_list = [])
-
-def p_exports_1 (t):
- 'exports : EXPORTS syms_exported SEMICOLON'
+def p_Exports_1 (t):
+ 'Exports : EXPORTS syms_exported SEMICOLON'
t[0] = t[2]
-def p_exports_2 (t):
- 'exports : '
- t[0] = []
+def p_Exports_2 (t):
+ 'Exports : EXPORTS ALL SEMICOLON'
+ t[0] = [ 'ALL' ]
+
+def p_Exports_3 (t):
+ 'Exports : '
+ t[0] = [ 'ALL' ]
def p_syms_exported_1 (t):
'syms_exported : exp_sym_list'
t[0] = t[1] + [t[3]]
-def p_Imports_1(t):
- 'Imports : IMPORTS SymbolsImported SEMICOLON'
- t[0] = t[2]
+def p_Imports_1 (t):
+ 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
+ t[0] = t[3]
+ global lcase_ident_assigned
+ lcase_ident_assigned = {}
+
+def p_importsbegin (t):
+ 'importsbegin : '
+ global lcase_ident_assigned
+ global g_conform
+ lcase_ident_assigned = {}
+ lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
def p_Imports_2 (t):
- 'Imports : '
- t[0] = []
+ 'Imports : '
+ t[0] = []
def p_SymbolsImported_1(t):
- 'SymbolsImported : '
- t[0] = []
+ 'SymbolsImported : '
+ t[0] = []
def p_SymbolsImported_2 (t):
- 'SymbolsImported : SymbolsFromModuleList'
- t[0] = t[1]
+ 'SymbolsImported : SymbolsFromModuleList'
+ t[0] = t[1]
def p_SymbolsFromModuleList_1 (t):
- 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
- t[0] = t[1] + [t[2]]
+ 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
+ t[0] = t[1] + [t[2]]
def p_SymbolsFromModuleList_2 (t):
- 'SymbolsFromModuleList : SymbolsFromModule'
- t[0] = [t[1]]
+ 'SymbolsFromModuleList : SymbolsFromModule'
+ t[0] = [t[1]]
def p_SymbolsFromModule (t):
- 'SymbolsFromModule : SymbolList FROM module_ident'
- t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
+ 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
+ t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
+ for s in (t[0].symbol_list):
+ if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
+ if t[0].module.val == 'Remote-Operations-Information-Objects':
+ for i in range(len(t[0].symbol_list)):
+ s = t[0].symbol_list[i]
+ if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
+ x880_import(s.val)
+ if isinstance(s, Type_Ref) and is_class_ident(s.val):
+ t[0].symbol_list[i] = Class_Ref (val = s.val)
+
+def p_GlobalModuleReference (t):
+ 'GlobalModuleReference : modulereference AssignedIdentifier'
+ t [0] = Node('module_ident', val = t[1], ident = t[2])
+
+def p_AssignedIdentifier_1 (t):
+ 'AssignedIdentifier : ObjectIdentifierValue'
+ t[0] = t[1]
+
+def p_AssignedIdentifier_2 (t):
+ 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
+ t[0] = t[1]
+
+def p_AssignedIdentifier_3 (t):
+ 'AssignedIdentifier : '
+ pass
def p_SymbolList_1 (t):
- 'SymbolList : Symbol'
- t[0] = [t[1]]
+ 'SymbolList : Symbol'
+ t[0] = [t[1]]
def p_SymbolList_2 (t):
- 'SymbolList : SymbolList COMMA Symbol'
- t[0] = t[1] + [t[3]]
+ 'SymbolList : SymbolList COMMA Symbol'
+ t[0] = t[1] + [t[3]]
def p_Symbol (t):
- '''Symbol : type_ref
- | ParameterizedReference
- | identifier''' # XXX omit DefinedMacroName
- t[0] = t[1]
+ '''Symbol : Reference
+ | ParameterizedReference'''
+ t[0] = t[1]
-def p_Reference (t):
- '''Reference : type_ref
- | valuereference'''
- t[0] = t[1]
+def p_Reference_1 (t):
+ '''Reference : type_ref
+ | valuereference
+ | objectclassreference '''
+ t[0] = t[1]
+
+def p_Reference_2 (t):
+ '''Reference : LCASE_IDENT_ASSIGNED'''
+ t[0] = Value_Ref (val=t[1])
def p_AssignmentList_1 (t):
- 'AssignmentList : AssignmentList Assignment'
- t[0] = t[1] + [t[2]]
+ 'AssignmentList : AssignmentList Assignment'
+ t[0] = t[1] + [t[2]]
def p_AssignmentList_2 (t):
- 'AssignmentList : Assignment SEMICOLON'
- t[0] = [t[1]]
+ 'AssignmentList : Assignment SEMICOLON'
+ t[0] = [t[1]]
def p_AssignmentList_3 (t):
- 'AssignmentList : Assignment'
- t[0] = [t[1]]
+ 'AssignmentList : Assignment'
+ t[0] = [t[1]]
def p_Assignment (t):
- '''Assignment : TypeAssignment
- | ValueAssignment
- | pyquote
- | ParameterizedTypeAssignment'''
- t[0] = t[1]
-
-def p_pyquote (t):
- '''pyquote : PYQUOTE'''
- t[0] = PyQuote (val = t[1])
+ '''Assignment : TypeAssignment
+ | ValueAssignment
+ | ValueSetTypeAssignment
+ | ObjectClassAssignment
+ | ObjectAssignment
+ | ObjectSetAssignment
+ | ParameterizedAssignment
+ | pyquote '''
+ t[0] = t[1]
# 13 Referencing type and value definitions -----------------------------------
# 13.1
def p_DefinedType (t):
- '''DefinedType : ext_type_ref
- | type_ref
- | ParameterizedType'''
+ '''DefinedType : ExternalTypeReference
+ | type_ref
+ | ParameterizedType'''
t[0] = t[1]
def p_DefinedValue(t):
- '''DefinedValue : ext_val_ref
- | identifier'''
+ '''DefinedValue : ExternalValueReference
+ | valuereference'''
t[0] = t[1]
+# 13.6
+def p_ExternalTypeReference (t):
+ 'ExternalTypeReference : modulereference DOT type_ref'
+ t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
+
+def p_ExternalValueReference (t):
+ 'ExternalValueReference : modulereference DOT identifier'
+ t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
+
# 15 Assigning types and values -----------------------------------------------
# 15.2
def p_ValueAssignment (t):
- 'ValueAssignment : identifier Type ASSIGNMENT Value'
- t[0] = value_assign (ident = t[1], typ = t[2], val = t[4])
+ 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
+ t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
+
+# only "simple" types are supported to simplify grammer
+def p_ValueType (t):
+ '''ValueType : type_ref
+ | BooleanType
+ | IntegerType
+ | ObjectIdentifierType
+ | OctetStringType
+ | RealType '''
+
+ t[0] = t[1]
+
+# 15.6
+def p_ValueSetTypeAssignment (t):
+ 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
+ t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4])
+
+# 15.7
+def p_ValueSet (t):
+ 'ValueSet : lbraceignore rbraceignore'
+ t[0] = None
# 16 Definition of types and values -------------------------------------------
# 16.1
def p_Type (t):
'''Type : BuiltinType
- | ReferencedType
- | ConstrainedType'''
+ | ReferencedType
+ | ConstrainedType'''
t[0] = t[1]
# 16.2
| BooleanType
| CharacterStringType
| ChoiceType
+ | EmbeddedPDVType
| EnumeratedType
+ | ExternalType
+ | InstanceOfType
| IntegerType
| NullType
+ | ObjectClassFieldType
| ObjectIdentifierType
| OctetStringType
| RealType
| SequenceOfType
| SetType
| SetOfType
- | selection_type
| TaggedType'''
t[0] = t[1]
# 16.3
def p_ReferencedType (t):
'''ReferencedType : DefinedType
- | UsefulType'''
+ | UsefulType
+ | SelectionType'''
t[0] = t[1]
-def p_ext_type_ref (t):
- 'ext_type_ref : type_ref DOT type_ref'
- # XXX coerce 1st type_ref to module_ref
- t[0] = Node ('ext_type_ref', module = t[1], typ = t[3])
-
# 16.5
def p_NamedType (t):
'NamedType : identifier Type'
# 16.7
def p_Value (t):
'''Value : BuiltinValue
- | ReferencedValue'''
+ | ReferencedValue
+ | ObjectClassFieldValue'''
t[0] = t[1]
# 16.9
def p_BuiltinValue (t):
'''BuiltinValue : BooleanValue
+ | ChoiceValue
+ | IntegerValue
| ObjectIdentifierValue
- | special_real_val
- | SignedNumber
+ | RealValue
| SequenceValue
| hex_string
| binary_string
# 16.11
def p_ReferencedValue (t):
- '''ReferencedValue : DefinedValue'''
+ '''ReferencedValue : DefinedValue
+ | ValueFromObject'''
t[0] = t[1]
# 16.13
def p_IntegerType_2 (t):
'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
- t[0] = IntegerType (named_list = t[3])
+ t[0] = IntegerType(named_list = t[3])
def p_NamedNumberList_1 (t):
'NamedNumberList : NamedNumber'
def p_NamedNumber (t):
'''NamedNumber : identifier LPAREN SignedNumber RPAREN
| identifier LPAREN DefinedValue RPAREN'''
- t[0] = NamedNumber (ident = t[1], val = t[3])
+ t[0] = NamedNumber(ident = t[1], val = t[3])
def p_SignedNumber_1 (t):
'SignedNumber : NUMBER'
'SignedNumber : MINUS NUMBER'
t[0] = '-' + t[2]
+# 18.9
+def p_IntegerValue (t):
+ 'IntegerValue : SignedNumber'
+ t[0] = t [1]
# 19 Notation for the enumerated type -----------------------------------------
# 20.1
def p_RealType (t):
- 'RealType : REAL'
- t[0] = RealType ()
+ 'RealType : REAL'
+ t[0] = RealType ()
+
+# 20.6
+def p_RealValue (t):
+ '''RealValue : REAL_NUMBER
+ | SpecialRealValue'''
+ t[0] = t [1]
+
+def p_SpecialRealValue (t):
+ '''SpecialRealValue : PLUS_INFINITY
+ | MINUS_INFINITY'''
+ t[0] = t[1]
+
# 21 Notation for the bitstring type ------------------------------------------
# 23.1
def p_NullType (t):
- 'NullType : NULL'
- t[0] = NullType ()
+ 'NullType : NULL'
+ t[0] = NullType ()
# 23.3
-#def p_NullValue (t):
-# 'NullValue : NULL'
-# t[0] = t[1]
+def p_NullValue (t):
+ 'NullValue : NULL'
+ t[0] = NullValue ()
# 24 Notation for sequence types ----------------------------------------------
# 24.1
def p_SequenceType_1 (t):
- 'SequenceType : SEQUENCE LBRACE RBRACE'
- t[0] = SequenceType (elt_list = [])
+ 'SequenceType : SEQUENCE LBRACE RBRACE'
+ t[0] = SequenceType (elt_list = [])
def p_SequenceType_2 (t):
- 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
- if t[3].has_key('ext_list'):
- t[0] = SequenceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
- else:
- t[0] = SequenceType (elt_list = t[3]['elt_list'])
+ 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
+ t[0] = SequenceType (elt_list = t[3]['elt_list'])
+ if t[3].has_key('ext_list'):
+ t[0].ext_list = t[3]['ext_list']
+ if t[3].has_key('elt_list2'):
+ t[0].ext_list = t[3]['elt_list2']
def p_ExtensionAndException_1 (t):
- 'ExtensionAndException : ELLIPSIS'
- t[0] = []
+ 'ExtensionAndException : ELLIPSIS'
+ t[0] = []
def p_OptionalExtensionMarker_1 (t):
- 'OptionalExtensionMarker : COMMA ELLIPSIS'
- t[0] = True
+ 'OptionalExtensionMarker : COMMA ELLIPSIS'
+ t[0] = True
def p_OptionalExtensionMarker_2 (t):
- 'OptionalExtensionMarker : '
- t[0] = False
+ 'OptionalExtensionMarker : '
+ t[0] = False
def p_ComponentTypeLists_1 (t):
- 'ComponentTypeLists : element_type_list'
- t[0] = {'elt_list' : t[1]}
+ 'ComponentTypeLists : ComponentTypeList'
+ t[0] = {'elt_list' : t[1]}
def p_ComponentTypeLists_2 (t):
- 'ComponentTypeLists : element_type_list COMMA ExtensionAndException extension_additions OptionalExtensionMarker'
- t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
+ 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
+ t[0] = {'elt_list' : t[1], 'ext_list' : []}
def p_ComponentTypeLists_3 (t):
- 'ComponentTypeLists : ExtensionAndException extension_additions OptionalExtensionMarker'
+ 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
+ t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
+
+def p_ComponentTypeLists_4 (t):
+ 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
+ t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]}
+
+def p_ComponentTypeLists_5 (t):
+ 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
+ t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]}
+
+def p_ComponentTypeLists_6 (t):
+ 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
+ t[0] = {'elt_list' : [], 'ext_list' : []}
+
+def p_ComponentTypeLists_7 (t):
+ 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
t[0] = {'elt_list' : [], 'ext_list' : t[2]}
-def p_extension_additions_1 (t):
- 'extension_additions : extension_addition_list'
- t[0] = t[1]
+#def p_RootComponentTypeList (t):
+# 'RootComponentTypeList : ComponentTypeList'
+# t[0] = t[1]
-def p_extension_additions_2 (t):
- 'extension_additions : '
- t[0] = []
+def p_ExtensionEndMarker (t):
+ 'ExtensionEndMarker : COMMA ELLIPSIS'
+ pass
-def p_extension_addition_list_1 (t):
- 'extension_addition_list : COMMA extension_addition'
- t[0] = [t[2]]
+#def p_extension_additions_1 (t):
+# 'extension_additions : extension_addition_list'
+# t[0] = t[1]
-def p_extension_addition_list_2 (t):
- 'extension_addition_list : extension_addition_list COMMA extension_addition'
- t[0] = t[1] + [t[3]]
+#def p_extension_additions_2 (t):
+# 'extension_additions : '
+# t[0] = []
+
+def p_ExtensionAdditionList_1 (t):
+ 'ExtensionAdditionList : COMMA extension_addition'
+ t[0] = [t[2]]
+
+def p_ExtensionAdditionList_2 (t):
+ 'ExtensionAdditionList : ExtensionAdditionList COMMA extension_addition'
+ t[0] = t[1] + [t[3]]
def p_extension_addition_1 (t):
- 'extension_addition : element_type'
+ 'extension_addition : ComponentType'
t[0] = t[1]
-def p_element_type_list_1 (t):
- 'element_type_list : element_type'
- t[0] = [t[1]]
+def p_ComponentTypeList_1 (t):
+ 'ComponentTypeList : ComponentType'
+ t[0] = [t[1]]
-def p_element_type_list_2 (t):
- 'element_type_list : element_type_list COMMA element_type'
- t[0] = t[1] + [t[3]]
+def p_ComponentTypeList_2 (t):
+ 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
+ t[0] = t[1] + [t[3]]
+
+def p_ComponentType_1 (t):
+ 'ComponentType : NamedType'
+ t[0] = Node ('elt_type', val = t[1], optional = 0)
-def p_element_type_1 (t):
- 'element_type : NamedType'
- t[0] = Node ('elt_type', val = t[1], optional = 0)
+def p_ComponentType_2 (t):
+ 'ComponentType : NamedType OPTIONAL'
+ t[0] = Node ('elt_type', val = t[1], optional = 1)
-def p_element_type_2 (t):
- 'element_type : NamedType OPTIONAL'
- t[0] = Node ('elt_type', val = t[1], optional = 1)
+def p_ComponentType_3 (t):
+ 'ComponentType : NamedType DEFAULT DefaultValue'
+ t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
-def p_element_type_3 (t):
- 'element_type : NamedType DEFAULT Value'
- t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
-# /*
-# * this rules uses NamedValue instead of Value
-# * for the stupid choice value syntax (fieldname value)
-# * it should be like a set/seq value (ie with
-# * enclosing { }
-# */
+def p_ComponentType_4 (t):
+ 'ComponentType : COMPONENTS OF Type'
+ t[0] = Node ('components_of', typ = t[3])
+
+def p_DefaultValue_1 (t):
+ '''DefaultValue : ReferencedValue
+ | BooleanValue
+ | ChoiceValue
+ | IntegerValue
+ | RealValue
+ | hex_string
+ | binary_string
+ | char_string
+ | ObjectClassFieldValue'''
+ t[0] = t[1]
-# XXX get to COMPONENTS later
+def p_DefaultValue_2 (t):
+ 'DefaultValue : lbraceignore rbraceignore'
+ t[0] = ''
# 24.17
def p_SequenceValue_1 (t):
# 26.1
def p_SetType_1 (t):
- 'SetType : SET LBRACE RBRACE'
- if t[3].has_key('ext_list'):
- t[0] = SetType (elt_list = [])
+ 'SetType : SET LBRACE RBRACE'
+ t[0] = SetType (elt_list = [])
def p_SetType_2 (t):
- 'SetType : SET LBRACE ComponentTypeLists RBRACE'
- if t[3].has_key('ext_list'):
- t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
- else:
- t[0] = SetType (elt_list = t[3]['elt_list'])
+ 'SetType : SET LBRACE ComponentTypeLists RBRACE'
+ if t[3].has_key('ext_list'):
+ t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
+ else:
+ t[0] = SetType (elt_list = t[3]['elt_list'])
# 27 Notation for set-of types ------------------------------------------------
'alternative_type_list : alternative_type_list COMMA NamedType'
t[0] = t[1] + [t[3]]
-def p_selection_type (t): # XXX what is this?
- 'selection_type : identifier LT Type'
- return Node ('seltype', ident = t[1], typ = t[3])
+# 28.10
+def p_ChoiceValue_1 (t):
+ '''ChoiceValue : identifier COLON Value
+ | identifier COLON NullValue '''
+ val = t[3]
+ if not isinstance(val, Value):
+ val = Value(val=val)
+ t[0] = ChoiceValue (choice = t[1], val = val)
+
+# 29 Notation for selection types
+
+# 29.1
+def p_SelectionType (t): #
+ 'SelectionType : identifier LT Type'
+ t[0] = SelectionType (typ = t[3], sel = t[1])
# 30 Notation for tagged types ------------------------------------------------
'TaggedType : Tag Type'
t[1].mode = 'default'
t[0] = t[2]
- t[0].SetTag(t[1])
+ t[0].AddTag(t[1])
def p_TaggedType_2 (t):
'''TaggedType : Tag IMPLICIT Type
| Tag EXPLICIT Type'''
t[1].mode = t[2]
t[0] = t[3]
- t[0].SetTag(t[1])
+ t[0].AddTag(t[1])
def p_Tag (t):
'Tag : LBRACK Class ClassNumber RBRACK'
'AnyType : ANY'
t[0] = AnyType ()
-#def p_any_type_2 (t):
-# 'any_type : ANY DEFINED BY identifier'
-# t[0] = Literal (val='asn1.ANY_constr(def_by="%s")' % t[4]) # XXX
-
# 31 Notation for the object identifier type ----------------------------------
# 31.1
def p_ObjectIdentifierType (t):
'ObjectIdentifierType : OBJECT IDENTIFIER'
- t[0] = ObjectIdentifierType ()
+ t[0] = ObjectIdentifierType()
# 31.3
def p_ObjectIdentifierValue (t):
t[0] = ObjectIdentifierValue (comp_list=t[2])
def p_oid_comp_list_1 (t):
- 'oid_comp_list : oid_comp_list oid_component'
+ 'oid_comp_list : oid_comp_list ObjIdComponents'
t[0] = t[1] + [t[2]]
def p_oid_comp_list_2 (t):
- 'oid_comp_list : oid_component'
+ 'oid_comp_list : ObjIdComponents'
t[0] = [t[1]]
-def p_oid_component (t):
- '''oid_component : number_form
- | name_form
- | name_and_number_form'''
- t[0] = t[1]
+def p_ObjIdComponents (t):
+ '''ObjIdComponents : NameForm
+ | NumberForm
+ | NameAndNumberForm'''
+ t[0] = t[1]
-def p_number_form (t):
- 'number_form : NUMBER'
- t [0] = t[1]
+def p_NameForm (t):
+ '''NameForm : LCASE_IDENT
+ | LCASE_IDENT_ASSIGNED'''
+ t [0] = t[1]
+
+def p_NumberForm (t):
+ '''NumberForm : NUMBER'''
+# | DefinedValue'''
+ t [0] = t[1]
+
+def p_NameAndNumberForm (t):
+ '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
+ | LCASE_IDENT LPAREN NumberForm RPAREN'''
+ t[0] = Node('name_and_number', ident = t[1], number = t[3])
+
+# 33 Notation for the embedded-pdv type -------------------------------------------
+# 33.1
+def p_EmbeddedPDVType (t):
+ 'EmbeddedPDVType : EMBEDDED PDV'
+ t[0] = EmbeddedPDVType()
+
+# 34 Notation for the external type -------------------------------------------
+
+# 34.1
+def p_ExternalType (t):
+ 'ExternalType : EXTERNAL'
+ t[0] = ExternalType()
# 36 Notation for character string types --------------------------------------
# 46.1
def p_ElementSetSpecs_1 (t):
- 'ElementSetSpecs : RootElementSetSpec'
- t[0] = t[1]
+ 'ElementSetSpecs : RootElementSetSpec'
+ t[0] = t[1]
def p_ElementSetSpecs_2 (t):
- 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
- t[0] = t[1]
- t[0].ext = True
+ 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
+ t[0] = t[1]
+ t[0].ext = True
def p_ElementSetSpecs_3 (t):
- 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA ElementSetSpecs'
- t[0] = t[1]
- t[0].ext = True
+ 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
+ t[0] = t[1]
+ t[0].ext = True
+
+def p_RootElementSetSpec (t):
+ 'RootElementSetSpec : ElementSetSpec'
+ t[0] = t[1]
-# skip compound constraints, only simple ones are supported
+def p_AdditionalElementSetSpec (t):
+ 'AdditionalElementSetSpec : ElementSetSpec'
+ t[0] = t[1]
-def p_RootElementSetSpec_1 (t):
- 'RootElementSetSpec : SubtypeElements'
- t[0] = t[1]
+def p_ElementSetSpec (t):
+ 'ElementSetSpec : Unions'
+ t[0] = t[1]
-def p_RootElementSetSpec_2 (t):
- 'RootElementSetSpec : SubtypeElements IntersectionMark SubtypeElements'
- t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
+def p_Unions_1 (t):
+ 'Unions : Intersections'
+ t[0] = t[1]
+
+def p_Unions_2 (t):
+ 'Unions : UElems UnionMark Intersections'
+ t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
+
+def p_UElems (t):
+ 'UElems : Unions'
+ t[0] = t[1]
+
+def p_Intersections_1 (t):
+ 'Intersections : IntersectionElements'
+ t[0] = t[1]
+
+def p_Intersections_2 (t):
+ 'Intersections : IElems IntersectionMark IntersectionElements'
+ t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
+
+def p_IElems (t):
+ 'IElems : Intersections'
+ t[0] = t[1]
+
+def p_IntersectionElements (t):
+ 'IntersectionElements : Elements'
+ t[0] = t[1]
+
+def p_UnionMark (t):
+ '''UnionMark : BAR
+ | UNION'''
def p_IntersectionMark (t):
- '''IntersectionMark : CIRCUMFLEX
- | INTERSECTION'''
+ '''IntersectionMark : CIRCUMFLEX
+ | INTERSECTION'''
+
+# 46.5
+def p_Elements_1 (t):
+ 'Elements : SubtypeElements'
+ t[0] = t[1]
+
+def p_Elements_2 (t):
+ 'Elements : LPAREN ElementSetSpec RPAREN'
+ t[0] = t[2]
# 47 Subtype elements ---------------------------------------------------------
| ValueRange
| PermittedAlphabet
| SizeConstraint
+ | TypeConstraint
| InnerTypeConstraints
| PatternConstraint'''
t[0] = t[1]
# 47.3 Contained subtype
# 47.3.1
def p_ContainedSubtype (t):
- 'ContainedSubtype : Includes Type'
- t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
+ 'ContainedSubtype : Includes Type'
+ t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
def p_Includes (t):
- '''Includes : INCLUDES
- | '''
+ '''Includes : INCLUDES
+ | '''
# 47.4 Value range
# 47.4.1
def p_ValueRange (t):
- 'ValueRange : lower_end_point RANGE upper_end_point'
- t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
+ 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
+ t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
# 47.4.3
-def p_lower_end_point_1 (t):
- 'lower_end_point : lower_end_value '
- t[0] = t[1]
+def p_LowerEndpoint_1 (t):
+ 'LowerEndpoint : LowerEndValue'
+ t[0] = t[1]
-def p_lower_end_point_2 (t):
- 'lower_end_point : lower_end_value LT' # XXX LT first?
- t[0] = t[1] # but not inclusive range
+def p_LowerEndpoint_2 (t):
+ 'LowerEndpoint : LowerEndValue LT'
+ t[0] = t[1] # but not inclusive range
-def p_upper_end_point_1 (t):
- 'upper_end_point : upper_end_value'
- t[0] = t[1]
+def p_UpperEndpoint_1 (t):
+ 'UpperEndpoint : UpperEndValue'
+ t[0] = t[1]
-def p_upper_end_point_2 (t):
- 'upper_end_point : LT upper_end_value'
- t[0] = t[1] # but not inclusive range
+def p_UpperEndpoint_2 (t):
+ 'UpperEndpoint : LT UpperEndValue'
+ t[0] = t[1] # but not inclusive range
-def p_lower_end_value (t):
- '''lower_end_value : Value
- | MIN'''
- t[0] = t[1] # XXX
+# 47.4.4
+def p_LowerEndValue (t):
+ '''LowerEndValue : Value
+ | MIN'''
+ t[0] = t[1] # XXX
-def p_upper_end_value (t):
- '''upper_end_value : Value
- | MAX'''
- t[0] = t[1]
+def p_UpperEndValue (t):
+ '''UpperEndValue : Value
+ | MAX'''
+ t[0] = t[1]
# 47.5 Size constraint
# 47.5.1
# 47.6 Type constraint
# 47.6.1
-#def p_TypeConstraint (t):
-# 'TypeConstraint : Type'
-# t[0] = Constraint (type = 'Type', subtype = t[2])
+def p_TypeConstraint (t):
+ 'TypeConstraint : Type'
+ t[0] = Constraint (type = 'Type', subtype = t[1])
# 47.7 Permitted alphabet
# 47.7.1
# 49 The exception identifier
# 49.4
-def p_ExceptionSpec (t):
- 'ExceptionSpec : '
- pass
+def p_ExceptionSpec_1 (t):
+ 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
+ pass
+
+def p_ExceptionSpec_2 (t):
+ 'ExceptionSpec : '
+ pass
+
+def p_ExceptionIdentification (t):
+ '''ExceptionIdentification : SignedNumber
+ | DefinedValue
+ | Type COLON Value '''
+ pass
# /*-----------------------------------------------------------------------*/
# /* Value Notation Productions */
+def p_binary_string (t):
+ 'binary_string : BSTRING'
+ t[0] = BStringValue(val = t[1])
-def p_ext_val_ref (t):
- 'ext_val_ref : type_ref DOT identifier'
- # XXX coerce type_ref to module_ref
- return Node ('ext_val_ref', module = t[1], ident = t[3])
+def p_hex_string (t):
+ 'hex_string : HSTRING'
+ t[0] = HStringValue(val = t[1])
-def p_special_real_val (t):
- '''special_real_val : PLUS_INFINITY
- | MINUS_INFINITY'''
+def p_char_string (t):
+ 'char_string : QSTRING'
t[0] = t[1]
+def p_number (t):
+ 'number : NUMBER'
+ t[0] = t[1]
-# Note that Z39.50 v3 spec has upper-case here for, e.g., SUTRS.
-# I've hacked the grammar to be liberal about what it accepts.
-# XXX should have -strict command-line flag to only accept lowercase
-# here, since that's what X.208 says.
-def p_name_form (t):
- '''name_form : type_ref
- | identifier'''
- t[0] = t[1]
-def p_name_and_number_form_1 (t):
- '''name_and_number_form : identifier LPAREN number_form RPAREN
- | type_ref LPAREN number_form RPAREN'''
- t[0] = Node ('name_and_number', ident = t[1], number = t[3])
+#--- ITU-T Recommendation X.681 -----------------------------------------------
-def p_name_and_number_form_2 (t):
- 'name_and_number_form : identifier LPAREN DefinedValue RPAREN'
- t[0] = Node ('name_and_number', ident = t[1], val = t[3])
+# 7 ASN.1 lexical items -------------------------------------------------------
-# see X.208 if you are dubious about lcase only for identifier
-def p_identifier (t):
- 'identifier : LCASE_IDENT'
- t[0] = t[1]
+# 7.1 Information object class references
+def p_objectclassreference (t):
+ 'objectclassreference : CLASS_IDENT'
+ t[0] = Class_Ref(val=t[1])
-def p_binary_string (t):
- 'binary_string : BSTRING'
- t[0] = t[1]
+# 7.2 Information object references
-def p_hex_string (t):
- 'hex_string : HSTRING'
- t[0] = t[1]
+def p_objectreference (t):
+ 'objectreference : LCASE_IDENT'
+ t[0] = t[1]
-def p_char_string (t):
- 'char_string : QSTRING'
- t[0] = t[1]
+# 7.3 Information object set references
-def p_number (t):
- 'number : NUMBER'
- t[0] = t[1]
+#def p_objectsetreference (t):
+# 'objectsetreference : UCASE_IDENT'
+# t[0] = t[1]
+
+# 7.4 Type field references
+# ucasefieldreference
+# 7.5 Value field references
+# lcasefieldreference
+# 7.6 Value set field references
+# ucasefieldreference
+# 7.7 Object field references
+# lcasefieldreference
+# 7.8 Object set field references
+# ucasefieldreference
+
+def p_ucasefieldreference (t):
+ 'ucasefieldreference : AMPERSAND UCASE_IDENT'
+ t[0] = '&' + t[2]
+
+def p_lcasefieldreference (t):
+ 'lcasefieldreference : AMPERSAND LCASE_IDENT'
+ t[0] = '&' + t[2]
+
+# 8 Referencing definitions
+
+# 8.1
+def p_DefinedObjectClass (t):
+ '''DefinedObjectClass : objectclassreference
+ | UsefulObjectClassReference'''
+ t[0] = t[1]
+ global obj_class
+ obj_class = t[0].val
+
+def p_DefinedObject (t):
+ '''DefinedObject : objectreference'''
+ t[0] = t[1]
+
+# 8.4
+def p_UsefulObjectClassReference (t):
+ '''UsefulObjectClassReference : TYPE_IDENTIFIER
+ | ABSTRACT_SYNTAX'''
+ t[0] = Class_Ref(val=t[1])
+
+# 9 Information object class definition and assignment
+
+# 9.1
+def p_ObjectClassAssignment (t):
+ '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
+ | UCASE_IDENT ASSIGNMENT ObjectClass'''
+ t[0] = t[3]
+ t[0].SetName(t[1])
+ if isinstance(t[0], ObjectClassDefn):
+ t[0].reg_types()
+
+# 9.2
+def p_ObjectClass (t):
+ '''ObjectClass : DefinedObjectClass
+ | ObjectClassDefn'''
+ t[0] = t[1]
+
+# 9.3
+def p_ObjectClassDefn (t):
+ '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
+ | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
+ t[0] = ObjectClassDefn(fields = t[3])
+
+def p_FieldSpecs_1 (t):
+ 'FieldSpecs : FieldSpec'
+ t[0] = [t[1]]
+
+def p_FieldSpecs_2 (t):
+ 'FieldSpecs : FieldSpecs COMMA FieldSpec'
+ t[0] = t[1] + [t[3]]
+
+def p_WithSyntaxSpec (t):
+ 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
+ t[0] = None
+
+# 9.4
+def p_FieldSpec (t):
+ '''FieldSpec : TypeFieldSpec
+ | FixedTypeValueFieldSpec
+ | FixedTypeValueSetFieldSpec
+ | ObjectFieldSpec
+ | ObjectSetFieldSpec '''
+ t[0] = t[1]
+
+# 9.5
+def p_TypeFieldSpec (t):
+ '''TypeFieldSpec : ucasefieldreference
+ | ucasefieldreference TypeOptionalitySpec '''
+ t[0] = TypeFieldSpec()
+ t[0].SetName(t[1])
+
+def p_TypeOptionalitySpec_1 (t):
+ 'TypeOptionalitySpec ::= OPTIONAL'
+ pass
+
+def p_TypeOptionalitySpec_2 (t):
+ 'TypeOptionalitySpec ::= DEFAULT Type'
+ pass
+
+# 9.6
+def p_FixedTypeValueFieldSpec (t):
+ '''FixedTypeValueFieldSpec : lcasefieldreference Type
+ | lcasefieldreference Type UNIQUE
+ | lcasefieldreference Type ValueOptionalitySpec
+ | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
+ t[0] = FixedTypeValueFieldSpec(typ = t[2])
+ t[0].SetName(t[1])
+
+def p_ValueOptionalitySpec_1 (t):
+ 'ValueOptionalitySpec ::= OPTIONAL'
+ pass
+
+def p_ValueOptionalitySpec_2 (t):
+ 'ValueOptionalitySpec ::= DEFAULT Value'
+ pass
+
+# 9.9
+def p_FixedTypeValueSetFieldSpec (t):
+ '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
+ | ucasefieldreference Type ValueSetOptionalitySpec '''
+ t[0] = FixedTypeValueSetFieldSpec()
+ t[0].SetName(t[1])
+
+def p_ValueSetOptionalitySpec_1 (t):
+ 'ValueSetOptionalitySpec ::= OPTIONAL'
+ pass
+
+def p_ValueSetOptionalitySpec_2 (t):
+ 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
+ pass
+
+# 9.11
+def p_ObjectFieldSpec (t):
+ '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
+ | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
+ t[0] = ObjectFieldSpec(cls=t[2])
+ t[0].SetName(t[1])
+ global obj_class
+ obj_class = None
+
+def p_ObjectOptionalitySpec_1 (t):
+ 'ObjectOptionalitySpec ::= OPTIONAL'
+ pass
+
+def p_ObjectOptionalitySpec_2 (t):
+ 'ObjectOptionalitySpec ::= DEFAULT Object'
+ pass
+
+# 9.12
+def p_ObjectSetFieldSpec (t):
+ '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
+ | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
+ t[0] = ObjectSetFieldSpec(cls=t[2])
+ t[0].SetName(t[1])
+
+def p_ObjectSetOptionalitySpec_1 (t):
+ 'ObjectSetOptionalitySpec ::= OPTIONAL'
+ pass
+
+def p_ObjectSetOptionalitySpec_2 (t):
+ 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
+ pass
+
+# 9.13
+def p_PrimitiveFieldName (t):
+ '''PrimitiveFieldName : ucasefieldreference
+ | lcasefieldreference '''
+ t[0] = t[1]
+
+# 9.13
+def p_FieldName_1 (t):
+ 'FieldName : PrimitiveFieldName'
+ t[0] = t[1]
+
+def p_FieldName_2 (t):
+ 'FieldName : FieldName DOT PrimitiveFieldName'
+ t[0] = t[1] + '.' + t[3]
+
+# 11 Information object definition and assignment
+
+# 11.1
+def p_ObjectAssignment (t):
+ 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
+ t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4])
+ global obj_class
+ obj_class = None
+
+# 11.3
+def p_Object (t):
+ '''Object : DefinedObject
+ | ObjectDefn
+ | ParameterizedObject'''
+ t[0] = t[1]
+
+# 11.4
+def p_ObjectDefn (t):
+ 'ObjectDefn : lbraceobject bodyobject rbraceobject'
+ t[0] = t[2]
+
+# {...} block of object definition
+def p_lbraceobject(t):
+ 'lbraceobject : braceobjectbegin LBRACE'
+ t[0] = t[1]
+
+def p_braceobjectbegin(t):
+ 'braceobjectbegin : '
+ global lexer
+ global obj_class
+ if set_class_syntax(obj_class):
+ state = 'INITIAL'
+ else:
+ lexer.level = 1
+ state = 'braceignore'
+ lexer.push_state(state)
+
+def p_rbraceobject(t):
+ 'rbraceobject : braceobjectend RBRACE'
+ t[0] = t[2]
+
+def p_braceobjectend(t):
+ 'braceobjectend : '
+ global lexer
+ lexer.pop_state()
+ set_class_syntax(None)
+
+def p_bodyobject_1 (t):
+ 'bodyobject : '
+ t[0] = { }
+
+def p_bodyobject_2 (t):
+ 'bodyobject : cls_syntax_list'
+ t[0] = t[1]
+
+def p_cls_syntax_list_1 (t):
+ 'cls_syntax_list : cls_syntax_list cls_syntax'
+ t[0] = t[1]
+ t[0].update(t[2])
+def p_cls_syntax_list_2 (t):
+ 'cls_syntax_list : cls_syntax'
+ t[0] = t[1]
+
+# X.681
+def p_cls_syntax_1 (t):
+ 'cls_syntax : Type IDENTIFIED BY Value'
+ t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
+
+def p_cls_syntax_2 (t):
+ 'cls_syntax : HAS PROPERTY Value'
+ t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
+
+# X.880
+def p_cls_syntax_3 (t):
+ '''cls_syntax : ERRORS ObjectSet
+ | LINKED ObjectSet
+ | RETURN RESULT BooleanValue
+ | SYNCHRONOUS BooleanValue
+ | INVOKE PRIORITY Value
+ | RESULT_PRIORITY Value
+ | PRIORITY Value
+ | ALWAYS RESPONDS BooleanValue
+ | IDEMPOTENT BooleanValue '''
+ t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
+
+def p_cls_syntax_4 (t):
+ '''cls_syntax : ARGUMENT Type
+ | RESULT Type
+ | PARAMETER Type
+ | CODE Value '''
+ t[0] = { get_class_fieled(t[1]) : t[2] }
+
+def p_cls_syntax_5 (t):
+ '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
+ | RESULT Type OPTIONAL BooleanValue
+ | PARAMETER Type OPTIONAL BooleanValue '''
+ t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
+
+# 12 Information object set definition and assignment
+
+# 12.1
+def p_ObjectSetAssignment (t):
+ 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
+ t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
+
+# 12.3
+def p_ObjectSet (t):
+ 'ObjectSet : lbraceignore rbraceignore'
+ t[0] = None
+
+# 14 Notation for the object class field type ---------------------------------
+
+# 14.1
+def p_ObjectClassFieldType (t):
+ 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
+ t[0] = get_type_from_class(t[1], t[3])
+
+# 14.6
+def p_ObjectClassFieldValue (t):
+ '''ObjectClassFieldValue : OpenTypeFieldVal'''
+ t[0] = t[1]
+
+def p_OpenTypeFieldVal (t):
+ '''OpenTypeFieldVal : Type COLON Value
+ | NullType COLON NullValue'''
+ t[0] = t[3]
+
+
+# 15 Information from objects -------------------------------------------------
+
+# 15.1
+
+def p_ValueFromObject (t):
+ 'ValueFromObject : LCASE_IDENT DOT FieldName'
+ t[0] = t[1] + '.' + t[3]
+
+
+# Annex C - The instance-of type ----------------------------------------------
+
+# C.2
+def p_InstanceOfType (t):
+ 'InstanceOfType : INSTANCE OF DefinedObjectClass'
+ t[0] = InstanceOfType()
+
+
+# --- tables ---
+
+useful_object_class_types = {
+ # Annex A
+ 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
+ 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
+ # Annex B
+ 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
+ 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
+ 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
+}
+
+object_class_types = { }
+
+object_class_typerefs = { }
+
+object_class_classrefs = { }
+
+class_types_creator = {
+ 'BooleanType' : lambda : BooleanType(),
+ 'IntegerType' : lambda : IntegerType(),
+ 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
+ 'OpenType' : lambda : OpenType(),
+}
+
+class_names = { }
+
+x681_syntaxes = {
+ 'TYPE-IDENTIFIER' : {
+ ' ' : '&Type',
+ 'IDENTIFIED' : 'IDENTIFIED',
+ #'BY' : 'BY',
+ 'IDENTIFIED BY' : '&id',
+ },
+ 'ABSTRACT-SYNTAX' : {
+ ' ' : '&Type',
+ 'IDENTIFIED' : 'IDENTIFIED',
+ #'BY' : 'BY',
+ 'IDENTIFIED BY' : '&id',
+ 'HAS' : 'HAS',
+ 'PROPERTY' : 'PROPERTY',
+ 'HAS PROPERTY' : '&property',
+ },
+}
+
+class_syntaxes_enabled = {
+ 'TYPE-IDENTIFIER' : True,
+ 'ABSTRACT-SYNTAX' : True,
+}
+
+class_syntaxes = {
+ 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
+ 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
+}
+
+class_current_syntax = None
+
+def get_syntax_tokens(syntaxes):
+ tokens = { }
+ for s in (syntaxes):
+ for k in (syntaxes[s].keys()):
+ if k.find(' ') < 0:
+ tokens[k] = k
+ tokens[k] = tokens[k].replace('-', '_')
+ return tokens.values()
+
+tokens = tokens + get_syntax_tokens(x681_syntaxes)
+
+def set_class_syntax(syntax):
+ global class_syntaxes_enabled
+ global class_current_syntax
+ #print "set_class_syntax", syntax, class_current_syntax
+ if class_syntaxes_enabled.get(syntax, False):
+ class_current_syntax = syntax
+ return True
+ else:
+ class_current_syntax = None
+ return False
+
+def is_class_syntax(name):
+ global class_syntaxes
+ global class_current_syntax
+ #print "is_class_syntax", name, class_current_syntax
+ if not class_current_syntax:
+ return False
+ return class_syntaxes[class_current_syntax].has_key(name)
+
+def get_class_fieled(name):
+ if not class_current_syntax:
+ return None
+ return class_syntaxes[class_current_syntax][name]
+
+def is_class_ident(name):
+ return class_names.has_key(name)
+
+def add_class_ident(name):
+ class_names[name] = name
+
+def get_type_from_class(cls, fld):
+ flds = fld.split('.')
+ if (isinstance(cls, Class_Ref)):
+ key = cls.val + '.' + flds[0]
+ else:
+ key = cls + '.' + flds[0]
+
+ if object_class_classrefs.has_key(key):
+ return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:]))
+
+ if object_class_typerefs.has_key(key):
+ return Type_Ref(val=object_class_typerefs[key])
+
+ creator = lambda : AnyType()
+ creator = useful_object_class_types.get(key, creator)
+ creator = object_class_types.get(key, creator)
+ return creator()
+
+def set_type_to_class(cls, fld, pars):
+ key = cls + '.' + fld
+ typename = 'OpenType'
+ if (len(pars) > 0):
+ typename = pars[0]
+ else:
+ pars.append(typename)
+ typeref = None
+ if (len(pars) > 1):
+ if (isinstance(pars[1], Class_Ref)):
+ pars[1] = pars[1].val
+ typeref = pars[1]
+
+ msg = None
+ if object_class_types.has_key(key):
+ msg = object_class_types[key]().type
+ if object_class_typerefs.has_key(key):
+ msg = "TypeReference " + object_class_typerefs[key]
+ if object_class_classrefs.has_key(key):
+ msg = "ClassReference " + object_class_classrefs[key]
+
+ if msg == ' '.join(pars):
+ msg = None
+
+ if msg:
+ msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars))
+ msg1 = "Already defined as '%s'" % (msg)
+ raise msg0 + msg1
+
+ if (typename == 'ClassReference'):
+ if not typeref: return False
+ object_class_classrefs[key] = typeref
+ return True
+
+ if (typename == 'TypeReference'):
+ if not typeref: return False
+ object_class_typerefs[key] = typeref
+ return True
+
+ creator = class_types_creator.get(typename)
+ if creator:
+ object_class_types[key] = creator
+ return True
+ else:
+ return False
#--- ITU-T Recommendation X.682 -----------------------------------------------
# 8.1
def p_GeneralConstraint (t):
- '''GeneralConstraint : UserDefinedConstraint'''
-# | TableConstraint
-# | ContentsConstraint''
- t[0] = t[1]
+ '''GeneralConstraint : UserDefinedConstraint
+ | TableConstraint
+ | ContentsConstraint'''
+ t[0] = t[1]
# 9 User-defined constraints --------------------------------------------------
# 9.1
def p_UserDefinedConstraint (t):
- 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
- t[0] = Constraint(type = 'UserDefined', subtype = t[4])
+ 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
+ t[0] = Constraint(type = 'UserDefined', subtype = t[4])
def p_UserDefinedConstraintParameterList_1 (t):
'UserDefinedConstraintParameterList : '
# 9.3
def p_UserDefinedConstraintParameter (t):
- 'UserDefinedConstraintParameter : type_ref'
+ 'UserDefinedConstraintParameter : Type'
t[0] = t[1]
+# 10 Table constraints, including component relation constraints --------------
+
+# 10.3
+def p_TableConstraint (t):
+ '''TableConstraint : SimpleTableConstraint
+ | ComponentRelationConstraint'''
+ t[0] = Constraint(type = 'Table', subtype = t[1])
+
+def p_SimpleTableConstraint (t):
+ 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
+ t[0] = t[2]
+
+# 10.7
+def p_ComponentRelationConstraint (t):
+ 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
+ t[0] = t[2] + str(t[5])
+
+def p_AtNotations_1 (t):
+ 'AtNotations : AtNotation'
+ t[0] = [t[1]]
+
+def p_AtNotations_2 (t):
+ 'AtNotations : AtNotations COMMA AtNotation'
+ t[0] = t[1] + [t[3]]
+
+def p_AtNotation_1 (t):
+ 'AtNotation : AT ComponentIdList'
+ t[0] = '@' + t[2]
+
+def p_AtNotation_2 (t):
+ 'AtNotation : AT DOT Level ComponentIdList'
+ t[0] = '@.' + t[3] + t[4]
+
+def p_Level_1 (t):
+ 'Level : DOT Level'
+ t[0] = '.' + t[2]
+
+def p_Level_2 (t):
+ 'Level : '
+ t[0] = ''
+
+def p_ComponentIdList_1 (t):
+ 'ComponentIdList : LCASE_IDENT'
+ t[0] = t[1]
+
+def p_ComponentIdList_2 (t):
+ 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
+ t[0] = t[1] + '.' + t[3]
+
+# 11 Contents constraints -----------------------------------------------------
+
+# 11.1
+def p_ContentsConstraint (t):
+ 'ContentsConstraint : CONTAINING type_ref'
+ t[0] = Constraint(type = 'Contents', subtype = t[2])
+
#--- ITU-T Recommendation X.683 -----------------------------------------------
# 8 Parameterized assignments -------------------------------------------------
# 8.1
+def p_ParameterizedAssignment (t):
+ '''ParameterizedAssignment : ParameterizedTypeAssignment
+ | ParameterizedObjectAssignment
+ | ParameterizedObjectSetAssignment'''
+ t[0] = t[1]
# 8.2
def p_ParameterizedTypeAssignment (t):
'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
t[0] = t[4]
- t[0].SetName(t[1] + 'xxx')
+ t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
+
+def p_ParameterizedObjectAssignment (t):
+ 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
+ t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
+ global obj_class
+ obj_class = None
+
+def p_ParameterizedObjectSetAssignment (t):
+ 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
+ t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
# 8.3
def p_ParameterList (t):
- 'ParameterList : LBRACE Parameters RBRACE'
- t[0] = t[2]
+ 'ParameterList : lbraceignore rbraceignore'
-def p_Parameters_1 (t):
- 'Parameters : Parameter'
- t[0] = [t[1]]
+#def p_ParameterList (t):
+# 'ParameterList : LBRACE Parameters RBRACE'
+# t[0] = t[2]
-def p_Parameters_2 (t):
- 'Parameters : Parameters COMMA Parameter'
- t[0] = t[1] + [t[3]]
+#def p_Parameters_1 (t):
+# 'Parameters : Parameter'
+# t[0] = [t[1]]
-def p_Parameter_1 (t):
- 'Parameter : Type COLON Reference'
- t[0] = [t[1], t[3]]
+#def p_Parameters_2 (t):
+# 'Parameters : Parameters COMMA Parameter'
+# t[0] = t[1] + [t[3]]
-def p_Parameter_2 (t):
- 'Parameter : Reference'
- t[0] = t[1]
+#def p_Parameter_1 (t):
+# 'Parameter : Type COLON Reference'
+# t[0] = [t[1], t[3]]
+
+#def p_Parameter_2 (t):
+# 'Parameter : Reference'
+# t[0] = t[1]
# 9 Referencing parameterized definitions -------------------------------------
# 9.1
def p_ParameterizedReference (t):
- 'ParameterizedReference : type_ref LBRACE RBRACE'
+ 'ParameterizedReference : Reference LBRACE RBRACE'
t[0] = t[1]
- t[0].val += 'xxx'
+ #t[0].val += 'xxx'
# 9.2
def p_ParameterizedType (t):
'ParameterizedType : type_ref ActualParameterList'
t[0] = t[1]
- t[0].val += 'xxx'
+ #t[0].val += 'xxx'
+
+
+def p_ParameterizedObject (t):
+ 'ParameterizedObject : DefinedObject ActualParameterList'
+ t[0] = t[1]
+ #t[0].val += 'xxx'
# 9.5
def p_ActualParameterList (t):
- 'ActualParameterList : LBRACE ActualParameters RBRACE'
- t[0] = t[2]
+ 'ActualParameterList : lbraceignore rbraceignore'
-def p_ActualParameters_1 (t):
- 'ActualParameters : ActualParameter'
- t[0] = [t[1]]
+#def p_ActualParameterList (t):
+# 'ActualParameterList : LBRACE ActualParameters RBRACE'
+# t[0] = t[2]
-def p_ActualParameters_2 (t):
- 'ActualParameters : ActualParameters COMMA ActualParameter'
- t[0] = t[1] + [t[3]]
+#def p_ActualParameters_1 (t):
+# 'ActualParameters : ActualParameter'
+# t[0] = [t[1]]
+
+#def p_ActualParameters_2 (t):
+# 'ActualParameters : ActualParameters COMMA ActualParameter'
+# t[0] = t[1] + [t[3]]
+
+#def p_ActualParameter (t):
+# '''ActualParameter : Type
+# | Value'''
+# t[0] = t[1]
+
+
+#--- ITU-T Recommendation X.880 -----------------------------------------------
+
+x880_classes = {
+ 'OPERATION' : {
+ '&ArgumentType' : [],
+ '&argumentTypeOptional' : [ 'BooleanType' ],
+ '&returnResult' : [ 'BooleanType' ],
+ '&ResultType' : [],
+ '&resultTypeOptional' : [ 'BooleanType' ],
+ '&Errors' : [ 'ClassReference', 'ERROR' ],
+ '&Linked' : [ 'ClassReference', 'OPERATION' ],
+ '&synchronous' : [ 'BooleanType' ],
+ '&idempotent' : [ 'BooleanType' ],
+ '&alwaysReturns' : [ 'BooleanType' ],
+# '&InvokePriority' #UNSUPPORTED_FixedTypeValueSetFieldSpec
+# '&ResultPriority' #UNSUPPORTED_FixedTypeValueSetFieldSpec
+ '&operationCode' : [ 'TypeReference', 'Code' ],
+ },
+ 'ERROR' : {
+ '&ParameterType' : [],
+ '¶meterTypeOptional' : [ 'BooleanType' ],
+# '&ErrorPriority' #UNSUPPORTED_FixedTypeValueSetFieldSpec
+ '&errorCode' : [ 'TypeReference', 'Code' ],
+ },
+ 'OPERATION-PACKAGE' : {
+ },
+ 'CONNECTION-PACKAGE' : {
+ },
+ 'CONTRACT' : {
+ },
+ 'ROS-OBJECT-CLASS' : {
+ },
+}
+
+x880_syntaxes = {
+ 'OPERATION' : {
+ 'ARGUMENT' : '&ArgumentType',
+ 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
+ 'RESULT' : '&ResultType',
+ 'RESULT OPTIONAL' : '&resultTypeOptional',
+ 'RETURN' : 'RETURN',
+ 'RETURN RESULT' : '&returnResult',
+ 'ERRORS' : '&Errors',
+ 'LINKED' : '&Linked',
+ 'SYNCHRONOUS' : '&synchronous',
+ 'IDEMPOTENT' : '&idempotent',
+ 'ALWAYS' : 'ALWAYS',
+ 'RESPONDS' : 'RESPONDS',
+ 'ALWAYS RESPONDS' : '&alwaysReturns',
+ 'INVOKE' : 'INVOKE',
+ 'PRIORITY' : 'PRIORITY',
+ 'INVOKE PRIORITY' : '&InvokePriority',
+ 'RESULT-PRIORITY': '&ResultPriority',
+ 'CODE' : '&operationCode',
+ },
+ 'ERROR' : {
+ 'PARAMETER' : '&ParameterType',
+ 'PARAMETER OPTIONAL' : '¶meterTypeOptional',
+ 'PRIORITY' : '&ErrorPriority',
+ 'CODE' : '&errorCode',
+ },
+# 'OPERATION-PACKAGE' : {
+# },
+# 'CONNECTION-PACKAGE' : {
+# },
+# 'CONTRACT' : {
+# },
+# 'ROS-OBJECT-CLASS' : {
+# },
+}
+
+def x880_import(name):
+ if x880_syntaxes.has_key(name):
+ class_syntaxes_enabled[name] = True
+ class_syntaxes[name] = x880_syntaxes[name]
+ if x880_classes.has_key(name):
+ add_class_ident(name)
+ for f in (x880_classes[name].keys()):
+ set_type_to_class(name, f, x880_classes[name][f])
+
+tokens = tokens + get_syntax_tokens(x880_syntaxes)
+
+# {...} OID value
+#def p_lbrace_oid(t):
+# 'lbrace_oid : brace_oid_begin LBRACE'
+# t[0] = t[1]
+
+#def p_brace_oid_begin(t):
+# 'brace_oid_begin : '
+# global in_oid
+# in_oid = True
+
+#def p_rbrace_oid(t):
+# 'rbrace_oid : brace_oid_end RBRACE'
+# t[0] = t[2]
+
+#def p_brace_oid_end(t):
+# 'brace_oid_end : '
+# global in_oid
+# in_oid = False
-def p_ActualParameter (t):
- '''ActualParameter : Type
- | Value'''
+# {...} block to be ignored
+def p_lbraceignore(t):
+ 'lbraceignore : braceignorebegin LBRACE'
t[0] = t[1]
+def p_braceignorebegin(t):
+ 'braceignorebegin : '
+ global lexer
+ lexer.level = 1
+ lexer.push_state('braceignore')
+
+def p_rbraceignore(t):
+ 'rbraceignore : braceignoreend RBRACE'
+ t[0] = t[2]
+
+def p_braceignoreend(t):
+ 'braceignoreend : '
+ global lexer
+ lexer.pop_state()
def p_error(t):
- raise ParseError(str(t))
+ global input_file
+ raise ParseError(t, input_file)
+
+def p_pyquote (t):
+ '''pyquote : PYQUOTE'''
+ t[0] = PyQuote (val = t[1])
+
def testlex (s):
lexer.input (s)
def eth_usage():
print """
asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c conform_file] [-e] input_file(s) ...
- -h|? : usage
- -b : BER (default is PER)
- -u : unaligned (default is aligned)
- -p proto : protocol name (implies -S)
- default is module-name from input_file (renamed by #.MODULE if present)
- -o name : output files name core (default is <proto>)
- -O dir : output directory
+ -h|? : usage
+ -b : BER (default is PER)
+ -u : unaligned (default is aligned)
+ -p proto : protocol name (implies -S)
+ default is module-name from input_file (renamed by #.MODULE if present)
+ -F : create 'field functions'
+ -T : tagged type support (experimental)
+ -o name : output files name core (default is <proto>)
+ -O dir : output directory
-c conform_file : conformation file
- -e : create conformation file for exported types
- -S : single output for multiple modules
- -s template : single file output (template is input file without .c/.h extension)
- -k : keep intermediate files though single file output is used
- input_file : input ASN.1 file
-
- -d dbg : debug output, dbg = [l][y][p][s][a][t][c][o]
+ -I path : path for conformance file includes
+ -e : create conformation file for exported types
+ -S : single output for multiple modules
+ -s template : single file output (template is input file without .c/.h extension)
+ -k : keep intermediate files though single file output is used
+ -L : suppress #line directive from .cnf file
+ input_file(s) : input ASN.1 file(s)
+
+ -d dbg : debug output, dbg = [l][y][p][s][a][t][c][m][o]
l - lex
y - yacc
p - parsing
a - list of assignments
t - tables
c - conformance values
+ m - list of compiled modules with dependency
o - list of output files
"""
def eth_main():
+ global input_file
+ global g_conform
+ global lexer
print "ASN.1 to Wireshark dissector compiler";
try:
- opts, args = getopt.getopt(sys.argv[1:], "h?d:buXp:o:O:c:eSs:k");
+ opts, args = getopt.getopt(sys.argv[1:], "h?d:buXp:FTo:O:c:I:eSs:kL");
except getopt.GetoptError:
eth_usage(); sys.exit(2)
if len(args) < 1:
eth_usage(); sys.exit(2)
conform = EthCnf()
+ conf_to_read = None
output = EthOut()
ectx = EthCtx(conform, output)
ectx.encoding = 'per'
ectx.proto_opt = None
+ ectx.fld_opt = {}
+ ectx.tag_opt = False
ectx.outnm_opt = None
ectx.aligned = True
ectx.dbgopt = ''
ectx.new = True
ectx.expcnf = False
ectx.merge_modules = False
+ ectx.group_by_prot = False
+ ectx.conform.last_group = 0
+ ectx.conform.suppress_line = False;
ectx.output.outnm = None
ectx.output.single_file = None
for o, a in opts:
if o in ("-h", "-?"):
eth_usage(); sys.exit(2)
- if o in ("-b",):
- ectx.encoding = 'ber'
- if o in ("-p",):
- ectx.proto_opt = a
- ectx.merge_modules = True
if o in ("-c",):
- ectx.conform.read(a)
- if o in ("-u",):
- ectx.aligned = False
- if o in ("-d",):
- ectx.dbgopt = a
- if o in ("-e",):
- ectx.expcnf = True
- if o in ("-S",):
- ectx.merge_modules = True
- if o in ("-o",):
- ectx.outnm_opt = a
- if o in ("-O",):
- ectx.output.outdir = a
- if o in ("-s",):
- ectx.output.single_file = a
- if o in ("-k",):
- ectx.output.keep = True
- if o in ("-X",):
- warnings.warn("Command line option -X is obsolete and can be removed")
+ conf_to_read = a
+ if o in ("-I",):
+ ectx.conform.include_path.append(a)
+ #if o in ("-X",):
+ # warnings.warn("Command line option -X is obsolete and can be removed")
+
+ if conf_to_read:
+ ectx.conform.read(conf_to_read)
+
+ for o, a in opts:
+ if o in ("-h", "-?", "-c", "-I"):
+ pass # already processed
+ else:
+ par = []
+ if a: par.append(a)
+ ectx.conform.set_opt(o, par, "commandline", 0)
(ld, yd, pd) = (0, 0, 0);
if ectx.dbg('l'): ld = 1
if ectx.dbg('y'): yd = 1
if ectx.dbg('p'): pd = 2
lexer = lex.lex(debug=ld)
- yacc.yacc(method='SLR', debug=yd)
+ yacc.yacc(method='LALR', debug=yd)
+ g_conform = ectx.conform
ast = []
for fn in args:
+ input_file = fn
+ lexer.lineno = 1
f = open (fn, "r")
ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
f.close ()
ectx.eth_clean()
- for module in ast:
- eth_do_module(module, ectx)
- if (not ectx.merge_modules): # output for each module
- ectx.eth_prepare()
- ectx.eth_do_output()
- ectx.eth_clean()
if (ectx.merge_modules): # common output for all module
+ ectx.eth_clean()
+ for module in ast:
+ eth_do_module(module, ectx)
ectx.eth_prepare()
ectx.eth_do_output()
+ elif (ectx.groups()): # group by protocols/group
+ groups = []
+ pr2gr = {}
+ if (ectx.group_by_prot): # group by protocols
+ for module in ast:
+ prot = module.get_proto(ectx)
+ if not pr2gr.has_key(prot):
+ pr2gr[prot] = len(groups)
+ groups.append([])
+ groups[pr2gr[prot]].append(module)
+ else: # group by groups
+ pass
+ for gm in (groups):
+ ectx.eth_clean()
+ for module in gm:
+ eth_do_module(module, ectx)
+ ectx.eth_prepare()
+ ectx.eth_do_output()
+ else: # output for each module
+ for module in ast:
+ ectx.eth_clean()
+ eth_do_module(module, ectx)
+ ectx.eth_prepare()
+ ectx.eth_do_output()
+
+ if ectx.dbg('m'):
+ ectx.dbg_modules()
if ectx.dbg('c'):
ectx.conform.dbg_print()