#!/usr/local/bin/python """A program to generate C# code for DHCP option parsing. Usage: GenDhcpOptions.py """ import sys import re # DhcpOptions.txt to C-Sharp types mappings csTypes = { "Byte" : ("byte", "value"), "MultiByte" : ("byte []", "values"), "Word" : ("ushort", "value"), "MultiWord" : ("ushort []", "values"), "DWord" : ("uint", "value"), "MultiDWord" : ("uint []", "values"), "IPv4" : ("IPv4", "address"), "MultiIPv4" : ("IPv4 []", "addresses"), "String" : ("char []", "chars") } def GetDhcpOptionValues(lines): optionPattern = re.compile("^([0-9]+)\s+(\w+)\s+(\w+)") options = [] for line in lines: match = optionPattern.match(line) if match != None: options.append(match.groups()) return options def WriteDhcpFragment(optionValue, optionName, typeName): (csArgType, csArgName) = csTypes[typeName] print """ public class Dhcp%s { public const byte OptionCode = %s; public static IDhcpOption Create(%s %s) { return new Dhcp%sOption(OptionCode, %s); } }""" % (optionName, optionValue, csArgType, csArgName, typeName, csArgName) def OutputGeneratedCode(options): for o in options: WriteDhcpFragment(o[0], o[1], o[2]) def OutputGeneratedTable(options): for o in options: print " parsers.Add(Dhcp%s.OptionCode," % o[1] print " new Parser(\"%s\"," % o[1] print " new ParseDhcpOption(Dhcp%sOption.Parse)));" % o[2] def OutputSourceAndGeneratedCode(sourceLines, options): begin_table_region = re.compile("^#region\s+GeneratedTable.*") end_table_region = re.compile("^#endregion\s+//\s+GeneratedTable.*") in_table_region = False sourceIter = iter(sourceLines) while True: try: line = sourceIter.next() except StopIteration: break if in_table_region == False: print line, if begin_table_region.match(line): in_table_region = True OutputGeneratedTable(options) if end_table_region.match(line): print line, break; begin_class_region = re.compile("^#region\s+GeneratedClasses.*") end_class_region = re.compile("^#endregion\s+//\s+GeneratedClasses.*") in_class_region = False while True: try: line = sourceIter.next() except StopIteration: break if in_class_region == False: print line, if begin_class_region.match(line): in_class_region = True OutputGeneratedCode(options) if end_class_region.match(line): in_class_region = False print line, def main(): if len(sys.argv) != 3: print "Usage: GenDhcpOptions " return 2 sourceFile = open(sys.argv[1], 'r') optionsFile = open(sys.argv[2], 'r') sourceLines = sourceFile.readlines() optionLines = optionsFile.readlines() dhcpOptions = GetDhcpOptionValues(optionLines) OutputSourceAndGeneratedCode(sourceLines, dhcpOptions) return 0 if __name__ == "__main__": sys.exit(main())