You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
634 lines
21 KiB
634 lines
21 KiB
#
|
|
# This file is part of pysmi software.
|
|
#
|
|
# Copyright (c) 2015-2019, Ilya Etingof <etingof@gmail.com>
|
|
# License: http://snmplabs.com/pysmi/license.html
|
|
#
|
|
# Build an internally used symbol table for each passed MIB.
|
|
#
|
|
import sys
|
|
from keyword import iskeyword
|
|
from pysmi.mibinfo import MibInfo
|
|
from pysmi.codegen.base import AbstractCodeGen, dorepr
|
|
from pysmi import error
|
|
from pysmi import debug
|
|
|
|
if sys.version_info[0] > 2:
|
|
# noinspection PyShadowingBuiltins
|
|
unicode = str
|
|
# noinspection PyShadowingBuiltins
|
|
long = int
|
|
|
|
|
|
class SymtableCodeGen(AbstractCodeGen):
|
|
symsTable = {
|
|
'MODULE-IDENTITY': ('ModuleIdentity',),
|
|
'OBJECT-TYPE': ('MibScalar', 'MibTable', 'MibTableRow', 'MibTableColumn'),
|
|
'NOTIFICATION-TYPE': ('NotificationType',),
|
|
'TEXTUAL-CONVENTION': ('TextualConvention',),
|
|
'MODULE-COMPLIANCE': ('ModuleCompliance',),
|
|
'OBJECT-GROUP': ('ObjectGroup',),
|
|
'NOTIFICATION-GROUP': ('NotificationGroup',),
|
|
'AGENT-CAPABILITIES': ('AgentCapabilities',),
|
|
'OBJECT-IDENTITY': ('ObjectIdentity',),
|
|
'TRAP-TYPE': ('NotificationType',), # smidump always uses NotificationType
|
|
'BITS': ('Bits',),
|
|
}
|
|
|
|
constImports = {
|
|
'SNMPv2-SMI': ('iso',
|
|
'Bits', # XXX
|
|
'Integer32', # XXX
|
|
'TimeTicks', # bug in some IETF MIBs
|
|
'Counter32', # bug in some IETF MIBs (e.g. DSA-MIB)
|
|
'Counter64', # bug in some MIBs (e.g.A3COM-HUAWEI-LswINF-MIB)
|
|
'NOTIFICATION-TYPE', # bug in some MIBs (e.g. A3COM-HUAWEI-DHCPSNOOP-MIB)
|
|
'Gauge32', # bug in some IETF MIBs (e.g. DSA-MIB)
|
|
'MODULE-IDENTITY', 'OBJECT-TYPE', 'OBJECT-IDENTITY', 'Unsigned32', 'IpAddress', # XXX
|
|
'MibIdentifier'), # OBJECT IDENTIFIER
|
|
'SNMPv2-TC': ('DisplayString', 'TEXTUAL-CONVENTION',), # XXX
|
|
'SNMPv2-CONF': ('MODULE-COMPLIANCE', 'NOTIFICATION-GROUP',), # XXX
|
|
}
|
|
|
|
baseTypes = ['Integer', 'Integer32', 'Bits', 'ObjectIdentifier', 'OctetString']
|
|
|
|
typeClasses = {
|
|
'COUNTER32': 'Counter32',
|
|
'COUNTER64': 'Counter64',
|
|
'GAUGE32': 'Gauge32',
|
|
'INTEGER': 'Integer32', # XXX
|
|
'INTEGER32': 'Integer32',
|
|
'IPADDRESS': 'IpAddress',
|
|
'NETWORKADDRESS': 'IpAddress',
|
|
'OBJECT IDENTIFIER': 'ObjectIdentifier',
|
|
'OCTET STRING': 'OctetString',
|
|
'OPAQUE': 'Opaque',
|
|
'TIMETICKS': 'TimeTicks',
|
|
'UNSIGNED32': 'Unsigned32',
|
|
'Counter': 'Counter32',
|
|
'Gauge': 'Gauge32',
|
|
'NetworkAddress': 'IpAddress', # RFC1065-SMI, RFC1155-SMI -> SNMPv2-SMI
|
|
'nullSpecific': 'zeroDotZero', # RFC1158-MIB -> SNMPv2-SMI
|
|
'ipRoutingTable': 'ipRouteTable', # RFC1158-MIB -> RFC1213-MIB
|
|
'snmpEnableAuthTraps': 'snmpEnableAuthenTraps' # RFC1158-MIB -> SNMPv2-MIB
|
|
}
|
|
|
|
smiv1IdxTypes = ['INTEGER', 'OCTET STRING', 'IPADDRESS', 'NETWORKADDRESS']
|
|
ifTextStr = 'if mibBuilder.loadTexts: '
|
|
indent = ' ' * 4
|
|
fakeidx = 1000 # starting index for fake symbols
|
|
|
|
def __init__(self):
|
|
self._rows = set()
|
|
self._cols = {} # k, v = name, datatype
|
|
self._exports = set()
|
|
self._postponedSyms = {} # k, v = symbol, (parents, properties)
|
|
self._parentOids = set()
|
|
self._importMap = {} # k, v = symbol, MIB
|
|
self._symsOrder = []
|
|
self._out = {} # k, v = symbol, properties
|
|
self.moduleName = ['DUMMY']
|
|
self._moduleRevision = None
|
|
self.genRules = {'text': True}
|
|
|
|
def symTrans(self, symbol):
|
|
if symbol in self.symsTable:
|
|
return self.symsTable[symbol]
|
|
|
|
return symbol,
|
|
|
|
@staticmethod
|
|
def transOpers(symbol):
|
|
if iskeyword(symbol):
|
|
symbol = 'pysmi_' + symbol
|
|
|
|
return symbol.replace('-', '_')
|
|
|
|
def prepData(self, pdata, classmode=False):
|
|
data = []
|
|
for el in pdata:
|
|
if not isinstance(el, tuple):
|
|
data.append(el)
|
|
|
|
elif len(el) == 1:
|
|
data.append(el[0])
|
|
|
|
else:
|
|
data.append(self.handlersTable[el[0]](self, self.prepData(el[1:], classmode=classmode), classmode=classmode))
|
|
|
|
return data
|
|
|
|
def genImports(self, imports):
|
|
# convertion to SNMPv2
|
|
toDel = []
|
|
for module in list(imports):
|
|
|
|
if module in self.convertImportv2:
|
|
|
|
for symbol in imports[module]:
|
|
|
|
if symbol in self.convertImportv2[module]:
|
|
toDel.append((module, symbol))
|
|
|
|
for newImport in self.convertImportv2[module][symbol]:
|
|
newModule, newSymbol = newImport
|
|
|
|
if newModule in imports:
|
|
imports[newModule].append(newSymbol)
|
|
else:
|
|
imports[newModule] = [newSymbol]
|
|
|
|
# removing converted symbols
|
|
for d in toDel:
|
|
imports[d[0]].remove(d[1])
|
|
|
|
# merging mib and constant imports
|
|
for module in self.constImports:
|
|
if module in imports:
|
|
imports[module] += self.constImports[module]
|
|
else:
|
|
imports[module] = self.constImports[module]
|
|
|
|
for module in sorted(imports):
|
|
symbols = ()
|
|
for symbol in set(imports[module]):
|
|
symbols += self.symTrans(symbol)
|
|
|
|
if symbols:
|
|
self._importMap.update([(self.transOpers(s), module) for s in symbols])
|
|
|
|
return {}, tuple(sorted(imports))
|
|
|
|
def allParentsExists(self, parents):
|
|
parentsExists = True
|
|
for parent in parents:
|
|
if not (parent in self._out or
|
|
parent in self._importMap or
|
|
parent in self.baseTypes or
|
|
parent in ('MibTable', 'MibTableRow', 'MibTableColumn') or
|
|
parent in self._rows):
|
|
parentsExists = False
|
|
break
|
|
|
|
return parentsExists
|
|
|
|
def regSym(self, symbol, symProps, parents=()):
|
|
if symbol in self._out or symbol in self._postponedSyms: # add to strict mode - or symbol in self._importMap:
|
|
raise error.PySmiSemanticError('Duplicate symbol found: %s' % symbol)
|
|
|
|
if self.allParentsExists(parents):
|
|
self._out[symbol] = symProps
|
|
self._symsOrder.append(symbol)
|
|
self.regPostponedSyms()
|
|
|
|
else:
|
|
self._postponedSyms[symbol] = (parents, symProps)
|
|
|
|
def regPostponedSyms(self):
|
|
regedSyms = []
|
|
for sym, val in self._postponedSyms.items():
|
|
parents, symProps = val
|
|
|
|
if self.allParentsExists(parents):
|
|
self._out[sym] = symProps
|
|
self._symsOrder.append(sym)
|
|
regedSyms.append(sym)
|
|
|
|
for sym in regedSyms:
|
|
self._postponedSyms.pop(sym)
|
|
|
|
# Clause handlers
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genAgentCapabilities(self, data, classmode=False):
|
|
origName, release, status, description, reference, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'AgentCapabilities',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genModuleIdentity(self, data, classmode=False):
|
|
origName, lastUpdated, organization, contactInfo, description, revisions, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'ModuleIdentity',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
if revisions:
|
|
self._moduleRevision = revisions[0]
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genModuleCompliance(self, data, classmode=False):
|
|
origName, status, description, reference, compliances, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'ModuleCompliance',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genNotificationGroup(self, data, classmode=False):
|
|
origName, objects, status, description, reference, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'NotificationGroup',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genNotificationType(self, data, classmode=False):
|
|
origName, objects, status, description, reference, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'NotificationType',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genObjectGroup(self, data, classmode=False):
|
|
origName, objects, status, description, reference, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'ObjectGroup',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genObjectIdentity(self, data, classmode=False):
|
|
origName, status, description, reference, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'ObjectIdentity',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genObjectType(self, data, classmode=False):
|
|
origName, syntax, units, maxaccess, status, description, reference, augmention, index, defval, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'ObjectType',
|
|
'oid': oid,
|
|
'syntax': syntax, # (type, module), subtype
|
|
'origName': origName}
|
|
|
|
parents = [syntax[0][0]]
|
|
|
|
if augmention:
|
|
parents.append(self.transOpers(augmention))
|
|
|
|
if defval: # XXX
|
|
symProps['defval'] = defval
|
|
|
|
if index and index[1]:
|
|
namepart, fakeIndexes, fakeSymSyntax = index
|
|
for fakeIdx, fakeSyntax in zip(fakeIndexes, fakeSymSyntax):
|
|
fakeName = namepart + str(fakeIdx)
|
|
|
|
fakeSymProps = {'type': 'fakeColumn',
|
|
'oid': oid + (fakeIdx,),
|
|
'syntax': fakeSyntax,
|
|
'origName': fakeName}
|
|
|
|
self.regSym(fakeName, fakeSymProps)
|
|
|
|
self.regSym(pysmiName, symProps, parents)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genTrapType(self, data, classmode=False):
|
|
origName, enterprise, variables, description, reference, value = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'NotificationType',
|
|
'oid': enterprise + (0, value),
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genTypeDeclaration(self, data, classmode=False):
|
|
origName, declaration = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
if declaration:
|
|
parentType, attrs = declaration
|
|
if parentType: # skipping SEQUENCE case
|
|
symProps = {'type': 'TypeDeclaration',
|
|
'syntax': declaration, # (type, module), subtype
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps, [declaration[0][0]])
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genValueDeclaration(self, data, classmode=False):
|
|
origName, oid = data
|
|
|
|
pysmiName = self.transOpers(origName)
|
|
|
|
symProps = {'type': 'MibIdentifier',
|
|
'oid': oid,
|
|
'origName': origName}
|
|
|
|
self.regSym(pysmiName, symProps)
|
|
|
|
# Subparts generation functions
|
|
# noinspection PyUnusedLocal,PyMethodMayBeStatic
|
|
def genBitNames(self, data, classmode=False):
|
|
names = data[0]
|
|
return names
|
|
|
|
# noinspection PyUnusedLocal,PyMethodMayBeStatic
|
|
def genBits(self, data, classmode=False):
|
|
bits = data[0]
|
|
return ('Bits', ''), bits
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genCompliances(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genConceptualTable(self, data, classmode=False):
|
|
row = data[0]
|
|
if row[0] and row[0][0]:
|
|
self._rows.add(self.transOpers(row[0][0]))
|
|
return ('MibTable', ''), ''
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genContactInfo(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genDisplayHint(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genDefVal(self, data, classmode=False): # XXX should be fixed, see pysnmp.py
|
|
defval = data[0]
|
|
|
|
if isinstance(defval, (int, long)): # number
|
|
val = str(defval)
|
|
|
|
elif self.isHex(defval): # hex
|
|
val = 'hexValue="' + defval[1:-2] + '"' # not working for Integer baseTypes
|
|
|
|
elif self.isBinary(defval): # binary
|
|
binval = defval[1:-2]
|
|
hexval = binval and hex(int(binval, 2))[2:] or ''
|
|
val = 'hexValue="' + hexval + '"'
|
|
|
|
elif isinstance(defval, list): # bits list
|
|
val = defval
|
|
|
|
elif defval[0] == defval[-1] and defval[0] == '"': # quoted strimg
|
|
val = dorepr(defval[1:-1])
|
|
|
|
else: # symbol (oid as defval) or name for enumeration member
|
|
if defval in self._out or defval in self._importMap:
|
|
val = defval + '.getName()'
|
|
else:
|
|
val = dorepr(defval)
|
|
|
|
return val
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genDescription(self, data, classmode=False):
|
|
return ''
|
|
|
|
def genReference(self, data, classmode=False):
|
|
return ''
|
|
|
|
def genStatus(self, data, classmode=False):
|
|
return ''
|
|
|
|
def genProductRelease(self, data, classmode=False):
|
|
return ''
|
|
|
|
def genEnumSpec(self, data, classmode=False):
|
|
return self.genBits(data, classmode=classmode)[1]
|
|
|
|
def genIndex(self, data, classmode=False):
|
|
indexes = data[0]
|
|
|
|
fakeIdxName = 'pysmiFakeCol'
|
|
fakeIndexes, fakeSymsSyntax = [], []
|
|
|
|
for idx in indexes:
|
|
idxName = idx[1]
|
|
if idxName in self.smiv1IdxTypes: # SMIv1 support
|
|
idxType = idxName
|
|
|
|
objType = self.typeClasses.get(idxType, idxType)
|
|
objType = self.transOpers(objType)
|
|
|
|
fakeIndexes.append(self.fakeidx)
|
|
fakeSymsSyntax.append((('MibTableColumn', ''), objType))
|
|
self.fakeidx += 1
|
|
|
|
return fakeIdxName, fakeIndexes, fakeSymsSyntax
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genIntegerSubType(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genMaxAccess(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genOctetStringSubType(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genOid(self, data, classmode=False):
|
|
out = ()
|
|
for el in data[0]:
|
|
if isinstance(el, (str, unicode)):
|
|
parent = self.transOpers(el)
|
|
self._parentOids.add(parent)
|
|
out += ((parent, self._importMap.get(parent, self.moduleName[0])),)
|
|
|
|
elif isinstance(el, (int, long)):
|
|
out += (el,)
|
|
|
|
elif isinstance(el, tuple):
|
|
out += (el[1],) # XXX Do we need to create a new object el[0]?
|
|
|
|
else:
|
|
raise error.PySmiSemanticError('unknown datatype for OID: %s' % el)
|
|
|
|
return out
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genObjects(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genTime(self, data, classmode=False):
|
|
return ''
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genLastUpdated(self, data, classmode=False):
|
|
return data[0]
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genOrganization(self, data, classmode=False):
|
|
return data[0]
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genRevisions(self, data, classmode=False):
|
|
lastRevision, lastDescription = data[0][0][0], data[0][0][1][1]
|
|
return lastRevision, lastDescription
|
|
|
|
def genRow(self, data, classmode=False):
|
|
row = data[0]
|
|
row = self.transOpers(row)
|
|
return row in self._rows and (('MibTableRow', ''), '') or self.genSimpleSyntax(data, classmode=classmode)
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genSequence(self, data, classmode=False):
|
|
cols = data[0]
|
|
self._cols.update(cols)
|
|
return '', ''
|
|
|
|
# noinspection PyUnusedLocal
|
|
def genSimpleSyntax(self, data, classmode=False):
|
|
objType = data[0]
|
|
|
|
module = ''
|
|
|
|
objType = self.typeClasses.get(objType, objType)
|
|
objType = self.transOpers(objType)
|
|
|
|
if objType not in self.baseTypes:
|
|
module = self._importMap.get(objType, self.moduleName[0])
|
|
|
|
subtype = len(data) == 2 and data[1] or ''
|
|
|
|
return (objType, module), subtype
|
|
|
|
# noinspection PyUnusedLocal,PyMethodMayBeStatic
|
|
def genTypeDeclarationRHS(self, data, classmode=False):
|
|
if len(data) == 1:
|
|
parentType, attrs = data[0] # just syntax
|
|
|
|
else:
|
|
# Textual convention
|
|
display, status, description, reference, syntax = data
|
|
parentType, attrs = syntax
|
|
|
|
return parentType, attrs
|
|
|
|
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
|
|
def genUnits(self, data, classmode=False):
|
|
return ''
|
|
|
|
handlersTable = {
|
|
'agentCapabilitiesClause': genAgentCapabilities,
|
|
'moduleIdentityClause': genModuleIdentity,
|
|
'moduleComplianceClause': genModuleCompliance,
|
|
'notificationGroupClause': genNotificationGroup,
|
|
'notificationTypeClause': genNotificationType,
|
|
'objectGroupClause': genObjectGroup,
|
|
'objectIdentityClause': genObjectIdentity,
|
|
'objectTypeClause': genObjectType,
|
|
'trapTypeClause': genTrapType,
|
|
'typeDeclaration': genTypeDeclaration,
|
|
'valueDeclaration': genValueDeclaration,
|
|
|
|
'ApplicationSyntax': genSimpleSyntax,
|
|
'BitNames': genBitNames,
|
|
'BITS': genBits,
|
|
'ComplianceModules': genCompliances,
|
|
'conceptualTable': genConceptualTable,
|
|
'CONTACT-INFO': genContactInfo,
|
|
'DISPLAY-HINT': genDisplayHint,
|
|
'DEFVAL': genDefVal,
|
|
'DESCRIPTION': genDescription,
|
|
'REFERENCE': genReference,
|
|
'Status': genStatus,
|
|
'PRODUCT-RELEASE': genProductRelease,
|
|
'enumSpec': genEnumSpec,
|
|
'INDEX': genIndex,
|
|
'integerSubType': genIntegerSubType,
|
|
'MaxAccessPart': genMaxAccess,
|
|
'Notifications': genObjects,
|
|
'octetStringSubType': genOctetStringSubType,
|
|
'objectIdentifier': genOid,
|
|
'Objects': genObjects,
|
|
'LAST-UPDATED': genLastUpdated,
|
|
'ORGANIZATION': genOrganization,
|
|
'Revisions': genRevisions,
|
|
'row': genRow,
|
|
'SEQUENCE': genSequence,
|
|
'SimpleSyntax': genSimpleSyntax,
|
|
'typeDeclarationRHS': genTypeDeclarationRHS,
|
|
'UNITS': genUnits,
|
|
'VarTypes': genObjects,
|
|
}
|
|
|
|
def genCode(self, ast, symbolTable, **kwargs):
|
|
self.genRules['text'] = kwargs.get('genTexts', False)
|
|
self._rows.clear()
|
|
self._cols.clear()
|
|
self._parentOids.clear()
|
|
self._symsOrder = []
|
|
self._postponedSyms.clear()
|
|
self._importMap.clear()
|
|
self._out = {} # should be new object, do not use `clear` method
|
|
self.moduleName[0], moduleOid, imports, declarations = ast
|
|
|
|
out, importedModules = self.genImports(imports or {})
|
|
|
|
for declr in declarations or []:
|
|
if declr:
|
|
clausetype = declr[0]
|
|
classmode = clausetype == 'typeDeclaration'
|
|
self.handlersTable[declr[0]](self, self.prepData(declr[1:], classmode), classmode)
|
|
|
|
if self._postponedSyms:
|
|
raise error.PySmiSemanticError('Unknown parents for symbols: %s' % ', '.join(self._postponedSyms))
|
|
|
|
for sym in self._parentOids:
|
|
if sym not in self._out and sym not in self._importMap:
|
|
raise error.PySmiSemanticError('Unknown parent symbol: %s' % sym)
|
|
|
|
self._out['_symtable_order'] = list(self._symsOrder)
|
|
self._out['_symtable_cols'] = list(self._cols)
|
|
self._out['_symtable_rows'] = list(self._rows)
|
|
|
|
debug.logger & debug.flagCodegen and debug.logger(
|
|
'canonical MIB name %s (%s), imported MIB(s) %s, Symbol table size %s symbols' % (
|
|
self.moduleName[0], moduleOid, ','.join(importedModules) or '<none>', len(self._out)))
|
|
|
|
return MibInfo(oid=None,
|
|
name=self.moduleName[0],
|
|
revision=self._moduleRevision,
|
|
imported=tuple([x for x in importedModules])), self._out
|