aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorTomas Kukosa <tomas.kukosa@siemens.com>2007-05-29 14:32:46 +0000
committerTomas Kukosa <tomas.kukosa@siemens.com>2007-05-29 14:32:46 +0000
commit41ac0624795df179822d41b775d6f5b4c60cfd11 (patch)
treebdfca0487747f91afd50fbdc2c5664eed4dcd05f /tools
parent0bf864bc32fd4af1fa607a913a9cfadc4accefa9 (diff)
- COMPONENTS OF implementation (can be used only inside one module or more modules compiled together, can not be done across exported/imported types)
- if protocol name contains dot '.' it is replaced with dash '-' for default output filename - fix bug in more modules output handling if they are not merged together but output is done one by one - new #.OPT option EXTERNAL_TYPE_CB for default EXTERNAL type callback - start of X.880 support implementation svn path=/trunk/; revision=21984
Diffstat (limited to 'tools')
-rwxr-xr-xtools/asn2wrs.py319
1 files changed, 238 insertions, 81 deletions
diff --git a/tools/asn2wrs.py b/tools/asn2wrs.py
index 789a72359c..21f1f86593 100755
--- a/tools/asn2wrs.py
+++ b/tools/asn2wrs.py
@@ -33,6 +33,9 @@
# 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
@@ -322,6 +325,7 @@ def t_QSTRING (t):
def t_UCASE_IDENT (t):
r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
+ if (is_x880_syntax(t.value)): t.type = t.value
t.type = reserved_words.get(t.value, t.type)
return t
@@ -495,6 +499,7 @@ class EthCtx:
self.default_oid_variant = ''
self.default_opentype_variant = ''
self.default_containing_variant = '_pdu_new'
+ self.default_external_type_cb = None
def encp(self): # encoding protocol
encp = self.encoding
@@ -659,6 +664,10 @@ class EthCtx:
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 not self.type_dep.has_key(type):
@@ -772,6 +781,7 @@ class EthCtx:
self.type_dep = {}
self.sel_req = {}
self.sel_req_ord = []
+ self.comp_req_ord = []
self.vassign = {}
self.vassign_ord = []
self.value = {}
@@ -842,6 +852,11 @@ class EthCtx:
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:
@@ -1685,6 +1700,7 @@ class EthCtx:
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()
@@ -2271,6 +2287,10 @@ class EthCnf:
elif opt in ("-L",):
par = self.check_par(par, 0, 0, fn, lineno)
self.suppress_line = True
+ 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)
@@ -2317,9 +2337,28 @@ class EthOut:
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 = ''
@@ -2336,39 +2375,42 @@ class EthOut:
#--- 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):
fx.write(self.fhdr(fn))
+ if not self.ectx.merge_modules:
+ fx.write(self.outcomment("--- Module %s --- --- ---" % (self.ectx.module()), 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 -------------------------------------------------------
@@ -2382,16 +2424,15 @@ class EthOut:
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")
@@ -2578,6 +2619,11 @@ class Type (Node):
def eth_reg_sub(self, ident, ectx):
pass
+ 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)
@@ -3039,6 +3085,14 @@ class Type_Ref (Type):
def eth_tname(self):
return asn2c(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']):
@@ -3215,6 +3269,36 @@ class SqType (Type):
#--- SeqType -----------------------------------------------------------
class SeqType (SqType):
+
+ def need_components(self):
+ lst = []
+ lst.extend(self.elt_list)
+ if hasattr(self, 'ext_list'):
+ lst.extend(self.ext_list)
+ for e in (self.elt_list):
+ 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
+
+ def get_components(self, ectx):
+ comp = []
+ comp.extend(self.elt_list)
+ return comp
+
def eth_type_default_table(self, ectx, tname):
#print "eth_type_default_table(tname='%s')" % (tname)
fname = ectx.eth_type[tname]['ref'][0]
@@ -3443,12 +3527,18 @@ class SequenceType (SeqType):
ctx.outdent ()
return rv
- def eth_reg_sub(self, ident, ectx):
- 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)
+ 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)
def eth_need_tree(self):
return True
@@ -3481,7 +3571,14 @@ class SequenceType (SeqType):
#--- 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, tstrip=1, parent=ident)
if hasattr(self, 'ext_list'):
@@ -3569,7 +3666,8 @@ class ChoiceType (Type):
ectx.eth_sel_req(ident, e.name)
def sel_item(self, ident, sel, ectx):
- lst = self.elt_list
+ lst = []
+ lst.extend(self.elt_list)
if hasattr(self, 'ext_list'):
lst.extend(self.ext_list)
ee = None
@@ -3907,7 +4005,10 @@ class ExternalType (Type):
def eth_type_default_pars(self, ectx, tname):
pars = Type.eth_type_default_pars(self, ectx, tname)
- pars['TYPE_REF_FN'] = 'NULL'
+ 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):
@@ -4691,8 +4792,15 @@ def p_SymbolsFromModuleList_2 (t):
def p_SymbolsFromModule (t):
'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
- for s in t[1]:
+ for s in (t[0].symbol_list):
if (isinstance(s, str) and s[0].islower()): lcase_ident_assigned[s] = 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'
@@ -5031,40 +5139,44 @@ def p_NullType (t):
# 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'
+ 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'])
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'
+ 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException extension_additions OptionalExtensionMarker'
t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
def p_ComponentTypeLists_3 (t):
'ComponentTypeLists : ExtensionAndException extension_additions OptionalExtensionMarker'
t[0] = {'elt_list' : [], 'ext_list' : t[2]}
+#def p_RootComponentTypeList (t):
+# 'RootComponentTypeList : ComponentTypeList'
+# t[0] = t[1]
+
def p_extension_additions_1 (t):
'extension_additions : extension_addition_list'
t[0] = t[1]
@@ -5082,34 +5194,32 @@ def p_extension_addition_list_2 (t):
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_element_type_1 (t):
- 'element_type : NamedType'
- t[0] = Node ('elt_type', val = t[1], optional = 0)
+def p_ComponentType_1 (t):
+ 'ComponentType : NamedType'
+ t[0] = Node ('elt_type', val = t[1], optional = 0)
-def p_element_type_2 (t):
- 'element_type : NamedType OPTIONAL'
- t[0] = Node ('elt_type', val = t[1], optional = 1)
+def p_ComponentType_2 (t):
+ 'ComponentType : NamedType OPTIONAL'
+ t[0] = Node ('elt_type', val = t[1], optional = 1)
-def p_element_type_3 (t):
- 'element_type : NamedType DEFAULT DefaultValue'
- 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_3 (t):
+ 'ComponentType : NamedType DEFAULT DefaultValue'
+ t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
+
+def p_ComponentType_4 (t):
+ 'ComponentType : COMPONENTS OF Type'
+ t[0] = Node ('components_of', typ = t[3])
def p_DefaultValue_1 (t):
'''DefaultValue : ReferencedValue
@@ -5125,8 +5235,6 @@ def p_DefaultValue_2 (t):
'DefaultValue : lbraceignore rbraceignore'
t[0] = ''
-# XXX get to COMPONENTS later
-
# 24.17
def p_SequenceValue_1 (t):
'SequenceValue : LBRACE RBRACE'
@@ -5741,6 +5849,10 @@ def p_DefinedObjectClass (t):
| UsefulObjectClassReference'''
t[0] = t[1]
+def p_DefinedObject (t):
+ '''DefinedObject : objectreference'''
+ t[0] = t[1]
+
# 8.4
def p_UsefulObjectClassReference (t):
'''UsefulObjectClassReference : TYPE_IDENTIFIER
@@ -5784,9 +5896,15 @@ def p_ObjectAssignment (t):
'ObjectAssignment : objectreference CLASS_IDENT ASSIGNMENT Object'
t[0] = Node('ObjectAssignment', name=t[1], cls=t[2], val=t[4])
-# 11.4
+# 11.3
def p_Object (t):
- 'Object : lbraceignore rbraceignore'
+ '''Object : DefinedObject
+ | ObjectDefn'''
+ t[0] = t[1]
+
+# 11.4
+def p_ObjectDefn (t):
+ 'ObjectDefn : lbraceignore rbraceignore'
t[0] = None
# 12 Information object set definition and assignment
@@ -5808,9 +5926,6 @@ def p_ObjectClassFieldType (t):
'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
t[0] = get_type_from_class(t[1], t[3])
-class_names = {
-}
-
useful_object_class_types = {
# Annex A
'TYPE-IDENTIFIER/id' : lambda : ObjectIdentifierType(),
@@ -5821,11 +5936,9 @@ useful_object_class_types = {
'ABSTRACT-SYNTAX/property' : lambda : BitStringType(),
}
-object_class_types = {
-}
+object_class_types = { }
-object_class_typerefs = {
-}
+object_class_typerefs = { }
class_types_creator = {
'IntegerType' : lambda : IntegerType(),
@@ -5833,6 +5946,8 @@ class_types_creator = {
'OpenType' : lambda : OpenType(),
}
+class_names = { }
+
def is_class_ident(name):
return class_names.has_key(name)
@@ -6003,6 +6118,48 @@ def p_ActualParameterList (t):
# t[0] = t[1]
+#--- ITU-T Recommendation X.880 -----------------------------------------------
+
+x880_syntaxes = {
+ 'OPERATION' : {
+ 'ARGUMENT' : 'ARGUMENT',
+ 'RESULT' : 'RESULT',
+ 'RETURN' : 'RETURN',
+ 'ERRORS' : 'ERRORS',
+ 'LINKED' : 'LINKED',
+ 'SYNCHRONOUS' : 'SYNCHRONOUS',
+ 'IDEMPOTENT' : 'IDEMPOTENT',
+ 'ALWAYS' : 'ALWAYS',
+ 'RESPONDS' : 'RESPONDS',
+ 'INVOKE' : 'INVOKE',
+ 'PRIORITY' : 'PRIORITY',
+ 'RESULT-PRIORITY': 'RESULT-PRIORITY',
+ 'CODE' : 'CODE',
+ },
+ 'ERROR' : {
+ },
+ 'OPERATION-PACKAGE' : {
+ },
+ 'CONNECTION-PACKAGE' : {
+ },
+ 'CONTRACT' : {
+ },
+ 'ROS-OBJECT-CLASS' : {
+ },
+
+}
+
+x880_syntaxes_enabled = { }
+x880_current_syntaxes = None
+
+def x880_import(name):
+ if x880_syntaxes.has_key(name):
+ x880_syntaxes_enabled[name] = True
+ add_class_ident(name)
+
+def is_x880_syntax(name):
+ return False
+
# {...} OID value
#def p_lbrace_oid(t):
# 'lbrace_oid : brace_oid_begin LBRACE'