def generate_psub_node(self, node, tp, fld, prim): tnm = type(node) dprint('generate_psub_node() CALLED ON', tnm) if tnm in self.psub_funmap: return self.psub_funmap[tnm](node, tp, fld, prim) else: raise Exception('No psub generator for ' + str(tnm))
def psubTypeAssignment(self, node, tp, fld, prim): # In lieu of typing context, fld is None; tp probably is too self.newcomma('; \\\n\t', '#define DEFINE_DER_PSUB_' + tosym (self.unit) + '_' + tosym(node.type_name) + ' \\\n\t') tp = tosym(node.type_name) subquads = self.generate_psub_node(node.type_decl, tp, '0', prim) dprint('SUBTRIPLES =', subquads) if subquads: self.generate_psub_sub(node.type_decl, subquads, tp, None) self.write(';\n\n') return []
def psubTypeAssignment(self, node, tp, fld, prim): # In lieu of typing context, fld is None; tp probably is too self.newcomma('; \\\n\t', '#define DEFINE_DER_PSUB_' + self.unit + '_' + tosym(node.type_name) + ' \\\n\t') tp = tosym(node.type_name) subquads = self.generate_psub_node(node.type_decl, tp, '0', prim) dprint('SUBTRIPLES =', subquads) if subquads: self.generate_psub_sub(node.type_decl, subquads, tp, None) self.write(';\n\n') return []
def generate_psub(self): self.writeln() self.writeln() self.writeln('/* Recursive parser-sub definitions in support of SEQUENCE OF and SET OF */') self.writeln() for assigncompos in dependency_sort(self.semamod.assignments): for assign in assigncompos: tnm = type(assign) if tnm in self.psub_funmap: dprint('Recursive call for', tnm) self.psub_funmap[tnm](assign, None, None, True) dprint('Recursion done for', tnm) else: raise Exception('No psub generator for ' + str(tnm))
def psubRepeatingStructureType(self, node, tp, fld, prim): elem_type = node.type_decl if isinstance(elem_type, NamedType): # We can ignore node.identifier... if fld == '0': # ...but in lieu of any name, why not, if it makes rfc4511 cool! fld = tosym(elem_type.identifier) elem_type = elem_type.type_decl if prim: # 1. produce derwalk for the nested field dprint('FIRST STEP OF psubRepeatingStructureType()') self.comma() self.write('const derwalk DER_PACK_' + tosym(self.unit) + '_' + tp + ('_' + fld if fld else '') + ' [] = {') surround_comma = self.getcomma() self.newcomma(', \\\n\t\t', ' \\\n\t\t') self.generate_pack_node(elem_type, implicit=False) self.comma() self.write('DER_PACK_END }') self.setcomma(*surround_comma) # 2. retrieve subquads for the nested field dprint('SECOND STEP OF psubRepeatingStructureType()') dprint('PROVIDED', tp) subquads = self.generate_psub_node(elem_type, tp, fld, False) # 3. produce triple structure definition for the nested field dprint('THIRD STEP OF psubRepeatingStructureType()') self.generate_psub_sub(node, subquads, tp, fld) else: pass # TODO:DEBUG# print 'FIRST,SECOND,THIRD STEP OF psubRepeatingStructureType() SKIPPED: SECONDARY' # 4. return a fresh triple structure defining this repeating field dprint('FOURTH STEP OF psubRepeatingStructureType()') nam = tosym(self.unit) + '_' + tp idx = '0' esz = 'DER_ELEMSZ (' + tosym( self.unit) + ',' + tp + ',' + (fld or '') + ')' if fld: fld = '_' + fld else: fld = '' pck = 'DER_PACK_' + nam + fld psb = 'DER_PSUB_' + nam + fld return [(idx, esz, pck, psb)]
def psubRepeatingStructureType(self, node, tp, fld, prim): elem_type = node.type_decl if isinstance(elem_type, NamedType): # We can ignore node.identifier... if fld == '0': # ...but in lieu of any name, why not, if it makes rfc4511 cool! fld = tosym(elem_type.identifier) elem_type = elem_type.type_decl if prim: # 1. produce derwalk for the nested field dprint('FIRST STEP OF psubRepeatingStructureType()') self.comma() self.write('const derwalk DER_PACK_' + tosym (self.unit) + '_' + tp + ('_' + fld if fld else '') + ' [] = {') surround_comma = self.getcomma() self.newcomma(', \\\n\t\t', ' \\\n\t\t') self.generate_pack_node(elem_type, implicit=False) self.comma() self.write('DER_PACK_END }') self.setcomma(*surround_comma) # 2. retrieve subquads for the nested field dprint('SECOND STEP OF psubRepeatingStructureType()') dprint('PROVIDED', tp) subquads = self.generate_psub_node(elem_type, tp, fld, False) # 3. produce triple structure definition for the nested field dprint('THIRD STEP OF psubRepeatingStructureType()') self.generate_psub_sub(node, subquads, tp, fld) else: pass # TODO:DEBUG# print 'FIRST,SECOND,THIRD STEP OF psubRepeatingStructureType() SKIPPED: SECONDARY' # 4. return a fresh triple structure defining this repeating field dprint('FOURTH STEP OF psubRepeatingStructureType()') nam = tosym (self.unit) + '_' + tp idx = '0' esz = 'DER_ELEMSZ (' + tosym (self.unit) + ',' + tp + ',' + (fld or '') + ')' if fld: fld = '_' + fld else: fld = '' pck = 'DER_PACK_' + nam + fld psb = 'DER_PSUB_' + nam + fld return [(idx, esz, pck, psb)]
def realise(incdirs, restargs): defmods = {} refmods = {} incdirs.append(os.path.curdir) for file_ in restargs: modnm = os.path.basename(file_).lower() dprint('Parsing ASN.1 syntaxdef for "%s"', modnm) with open(file_, 'r') as asn1fh: asn1txt = asn1fh.read() asn1tree = parser.parse_asn1(asn1txt) dprint('Building semantic model for "%s"', modnm) asn1sem = build_semantic_model(asn1tree) defmods[os.path.basename(file_)] = asn1sem[0] refmods[os.path.splitext(modnm)[0]] = asn1sem[0] dprint('Realised semantic model for "%s"', modnm) imports = list(refmods.keys()) while len(imports) > 0: dm = refmods[imports.pop(0).lower()] if not dm.imports: continue for rm in dm.imports.imports.keys(): rm = str(rm).lower() if rm not in refmods: dprint('Importing ASN.1 include for "%s"', rm) modfh = None for incdir in incdirs: try: modfh = open(incdir + os.path.sep + rm + '.asn1', 'r') break except IOError: continue if modfh is None: raise Exception('No include file "{}.asn1" found'.format(rm)) asn1txt = modfh.read() asn1tree = parser.parse_asn1(asn1txt) dprint('Building semantic model for "%s"', rm) asn1sem = build_semantic_model(asn1tree) refmods[rm] = asn1sem[0] imports.append(rm) dprint('Realised semantic model for "%s"', rm) return defmods, refmods
def generate(langsel, defmods, refmods, testcases): # Generate C header files if 'c' in langsel: for modnm in defmods.keys(): dprint('Generating C header file for "%s"', modnm) cogen = QuickDER2c(defmods[modnm], modnm, refmods) cogen.generate_head() cogen.generate_overlay() cogen.generate_pack() cogen.generate_psub() cogen.generate_tail() cogen.close() dprint('Ready with C header file for "%s"', modnm) # Generate Python modules if 'python' in langsel: for modnm in defmods.keys(): dprint('Generating Python module for "%s"', modnm) cogen = QuickDER2py(defmods[modnm], modnm, refmods) cogen.generate_head() cogen.generate_classes() cogen.generate_values() cogen.generate_tail() cogen.close() dprint('Ready with Python module for "%s"', modnm) if 'source' in langsel: for modnm in defmods.keys(): dprint('Generating C pack/unpack source for "%s"', modnm) cogen = QuickDER2source(defmods[modnm], modnm, refmods) cogen.generate_head() cogen.generate_pack() cogen.generate_unpack() cogen.generate_tail() cogen.close() dprint('Ready with C pack/unpack source for "%s"', modnm) # Generate test data if testcases != {}: for modnm in defmods.keys(): print ('Generating test cases for ' + modnm) cogen = QuickDER2testdata(defmods[modnm], modnm, refmods) cogen.generate_testdata() for typenm in cogen.all_typenames(): if typenm in testcases: cases = testcases[typenm] elif '' in testcases: cases = testcases[''] else: cases = [] casestr = ','.join([str(s) + '-' + str(e) for (s, e) in cases]) for (casenr, der_packer) in cogen.fetch_multi(typenm, cases): if der_packer is None: break print ('Type %s case %s packer %s' % (typenm, casenr, der_packer.encode('hex'))) cogen.close() print('Generated test cases for ' + modnm)
def psubConstructedType(self, node, tp, fld, prim): # Iterate over field names, recursively retrieving quads; # add the field's offset to each of the quads, for its holding field compquads = [] for comp in node.components: if isinstance(comp, ExtensionMarker): continue subfld = tosym(comp.identifier) dprint('subfld is ', subfld) dprint('Generating PSUB node for %s', comp.type_decl.type_name) subquads = self.generate_psub_node(comp.type_decl, tp, subfld, prim) dprint('Generated PSUB node for %s', comp.type_decl.type_name) dprint('quads are %s', subquads) if fld == '0': subtp = tp else: subtp = tp + '_' + fld # TODO:TEST# subtp = tp + ('_' + fld if fld else '') # TODO:TEST# if subfld != '0': # TODO:TEST# if subfld: if subfld != '0': ofs = 'DER_OFFSET (' + tosym( self.unit) + ',' + subtp + ',' + subfld + ')' else: ofs = '0' for (idx, esz, pck, psb) in subquads: dprint('DEALING WITH', pck) if str(idx) == '0': idx = ofs else: idx = ofs + ' \\\n\t\t+ ' + str(idx) compquads.append((idx, esz, pck, psb)) dprint('psubConstructedType() RETURNS COMPONENT TRIPLES', compquads) return compquads
def psubDefinedType(self, node, tp, fld, prim): dprint('DefinedType type:', node.type_name, '::', type(node.type_name)) modnm = node.module_ref dprint('AFTER modnm = node.module_ref', modnm) if not modnm and self.semamod.imports: syms = self.semamod.imports.imports dprint('SYMS.KEYS() =', syms.keys()) for mod in syms.keys(): if node.type_name in syms[mod]: modnm = str(mod).lower() dprint('AFTER modnm = str(mod).lower ()', modnm) break if modnm is None: # NOT_IN_GENERAL# modnm = node.module_ref modnm = self.unit.lower() dprint('AFTER modnm = self.unit.lower ()', modnm) dprint('MODNM =', modnm, '::', type(modnm)) dprint('Referenced module:', modnm, '::', type(modnm)) dprint('Searching case-insensitively in:', self.refmods.keys()) if modnm not in self.refmods: raise Exception('Module name "%s" not found' % modnm) thetype = self.refmods[modnm].user_types()[node.type_name] dprint('References:', thetype, '::', type(thetype)) popunit = self.unit popsema = self.semamod self.unit = modnm self.semamod = self.refmods[modnm] tp2 = tosym(node.type_name) fld2 = '0' subtuples = self.generate_psub_node( thetype, tp2, fld2, prim and (popunit == self.unit) and (tp == tp2)) self.semamod = popsema self.unit = popunit dprint('SUBTUPLES =', subtuples) return subtuples
def realise(incdirs, restargs): defmods = {} refmods = {} incdirs.append(os.path.curdir) for file_ in restargs: modnm = os.path.basename(file_).lower() dprint('Parsing ASN.1 syntaxdef for "%s"', modnm) with open(file_, 'r') as asn1fh: asn1txt = asn1fh.read() asn1tree = parser.parse_asn1(asn1txt) dprint('Building semantic model for "%s"', modnm) asn1sem = build_semantic_model(asn1tree) defmods[os.path.basename(file_)] = asn1sem[0] refmods[os.path.splitext(modnm)[0]] = asn1sem[0] dprint('Realised semantic model for "%s"', modnm) imports = list(refmods.keys()) while len(imports) > 0: dm = refmods[imports.pop(0).lower()] if not dm.imports: continue for rm in dm.imports.imports.keys(): rm = str(rm).lower() if rm not in refmods: dprint('Importing ASN.1 include for "%s"', rm) modfh = None for incdir in incdirs: try: modfh = open(incdir + os.path.sep + rm + '.asn1', 'r') break except IOError: continue if modfh is None: raise Exception( 'No include file "{}.asn1" found'.format(rm)) asn1txt = modfh.read() asn1tree = parser.parse_asn1(asn1txt) dprint('Building semantic model for "%s"', rm) asn1sem = build_semantic_model(asn1tree) refmods[rm] = asn1sem[0] imports.append(rm) dprint('Realised semantic model for "%s"', rm) return defmods, refmods
def generate(langsel, defmods, refmods, testcases): # Generate C header files if 'c' in langsel: for modnm in defmods.keys(): dprint('Generating C header file for "%s"', modnm) cogen = QuickDER2c(defmods[modnm], modnm, refmods) cogen.generate_head() cogen.generate_overlay() cogen.generate_pack() cogen.generate_psub() cogen.generate_tail() cogen.close() dprint('Ready with C header file for "%s"', modnm) # Generate Python modules if 'python' in langsel: for modnm in defmods.keys(): dprint('Generating Python module for "%s"', modnm) cogen = QuickDER2py(defmods[modnm], modnm, refmods) cogen.generate_head() cogen.generate_classes() cogen.generate_values() cogen.generate_tail() cogen.close() dprint('Ready with Python module for "%s"', modnm) if 'source' in langsel: for modnm in defmods.keys(): dprint('Generating C pack/unpack source for "%s"', modnm) cogen = QuickDER2source(defmods[modnm], modnm, refmods) cogen.generate_head() cogen.generate_pack() cogen.generate_unpack() cogen.generate_tail() cogen.close() dprint('Ready with C pack/unpack source for "%s"', modnm) # Generate test data if testcases != {}: for modnm in defmods.keys(): print('Generating test cases for ' + modnm) cogen = QuickDER2testdata(defmods[modnm], modnm, refmods) cogen.generate_testdata() for typenm in cogen.all_typenames(): if typenm in testcases: cases = testcases[typenm] elif '' in testcases: cases = testcases[''] else: cases = [] casestr = ','.join([str(s) + '-' + str(e) for (s, e) in cases]) for (casenr, der_packer) in cogen.fetch_multi(typenm, cases): if der_packer is None: break print('Type %s case %s packer %s' % (typenm, casenr, der_packer.encode('hex'))) cogen.close() print('Generated test cases for ' + modnm)
def psubConstructedType(self, node, tp, fld, prim): # Iterate over field names, recursively retrieving quads; # add the field's offset to each of the quads, for its holding field compquads = [] for comp in node.components: if isinstance(comp, ExtensionMarker): continue subfld = tosym(comp.identifier) dprint('subfld is ', subfld) dprint('Generating PSUB node for %s', comp.type_decl.type_name) subquads = self.generate_psub_node(comp.type_decl, tp, subfld, prim) dprint('Generated PSUB node for %s', comp.type_decl.type_name) dprint('quads are %s', subquads) if fld == '0': subtp = tp else: subtp = tp + '_' + fld # TODO:TEST# subtp = tp + ('_' + fld if fld else '') # TODO:TEST# if subfld != '0': # TODO:TEST# if subfld: if subfld != '0': ofs = 'DER_OFFSET (' + tosym (self.unit) + ',' + subtp + ',' + subfld + ')' else: ofs = '0' for (idx, esz, pck, psb) in subquads: dprint('DEALING WITH', pck) if str(idx) == '0': idx = ofs else: idx = ofs + ' \\\n\t\t+ ' + str(idx) compquads.append((idx, esz, pck, psb)) dprint('psubConstructedType() RETURNS COMPONENT TRIPLES', compquads) return compquads
def psubDefinedType(self, node, tp, fld, prim): dprint('DefinedType type:', node.type_name, '::', type(node.type_name)) modnm = node.module_ref dprint('AFTER modnm = node.module_ref', modnm) if not modnm and self.semamod.imports: syms = self.semamod.imports.imports dprint('SYMS.KEYS() =', syms.keys()) for mod in syms.keys(): if node.type_name in syms[mod]: modnm = str(mod).lower() dprint('AFTER modnm = str(mod).lower ()', modnm) break if modnm is None: # NOT_IN_GENERAL# modnm = node.module_ref modnm = self.unit.lower() dprint('AFTER modnm = self.unit.lower ()', modnm) dprint('MODNM =', modnm, '::', type(modnm)) dprint('Referenced module:', modnm, '::', type(modnm)) dprint('Searching case-insensitively in:', self.refmods.keys()) if modnm not in self.refmods: raise Exception('Module name "%s" not found' % modnm) thetype = self.refmods[modnm].user_types()[node.type_name] dprint('References:', thetype, '::', type(thetype)) popunit = self.unit popsema = self.semamod self.unit = modnm self.semamod = self.refmods[modnm] tp2 = tosym(node.type_name) fld2 = '0' subtuples = self.generate_psub_node(thetype, tp2, fld2, prim and (popunit == self.unit) and (tp == tp2)) self.semamod = popsema self.unit = popunit dprint('SUBTUPLES =', subtuples) return subtuples