00001
00002
00003 '''
00004 parse a MAVLink protocol XML file and generate a python implementation
00005
00006 Copyright Andrew Tridgell 2011
00007 Released under GNU GPL version 3 or later
00008
00009 '''
00010 import sys, textwrap, os
00011 from . import mavparse
00012
00013
00014 schemaFile = os.path.join(os.path.dirname(os.path.realpath(__file__)), "mavschema.xsd")
00015
00016
00017 DEFAULT_WIRE_PROTOCOL = mavparse.PROTOCOL_1_0
00018 DEFAULT_LANGUAGE = 'Python'
00019 DEFAULT_ERROR_LIMIT = 200
00020 DEFAULT_VALIDATE = True
00021
00022
00023 supportedLanguages = ["C", "CS", "JavaScript", "Python", "WLua", "ObjC", "Java"]
00024
00025
00026 def mavgen(opts, args) :
00027 """Generate mavlink message formatters and parsers (C and Python ) using options
00028 and args where args are a list of xml files. This function allows python
00029 scripts under Windows to control mavgen using the same interface as
00030 shell scripts under Unix"""
00031
00032 xml = []
00033
00034
00035 if opts.validate:
00036 try:
00037 from lib.genxmlif import GenXmlIfError
00038 from lib.minixsv import pyxsval
00039 except:
00040 print("WARNING: Unable to load XML validator libraries. XML validation will not be performed")
00041 opts.validate = False
00042
00043 def mavgen_validate(fname, schema, errorLimitNumber) :
00044 """Uses minixsv to validate an XML file with a given XSD schema file. We define mavgen_validate
00045 here because it relies on the XML libs that were loaded in mavgen(), so it can't be called standalone"""
00046
00047 domTreeWrapper = pyxsval.parseAndValidate(fname, xsdFile=schema, errorLimit=errorLimitNumber)
00048
00049
00050 for fname in args:
00051 if opts.validate:
00052 print("Validating %s" % fname)
00053 mavgen_validate(fname, schemaFile, opts.error_limit);
00054 else:
00055 print("Validation skipped for %s." % fname)
00056
00057 print("Parsing %s" % fname)
00058 xml.append(mavparse.MAVXML(fname, opts.wire_protocol))
00059
00060
00061 for x in xml[:]:
00062 for i in x.include:
00063 fname = os.path.join(os.path.dirname(x.filename), i)
00064
00065
00066 if opts.validate:
00067 print("Validating %s" % fname)
00068 mavgen_validate(fname, schemaFile, opts.error_limit);
00069 else:
00070 print("Validation skipped for %s." % fname)
00071
00072
00073 print("Parsing %s" % fname)
00074 xml.append(mavparse.MAVXML(fname, opts.wire_protocol))
00075
00076
00077 for idx in range(0, 256):
00078 if x.message_lengths[idx] == 0:
00079 x.message_lengths[idx] = xml[-1].message_lengths[idx]
00080 x.message_crcs[idx] = xml[-1].message_crcs[idx]
00081 x.message_names[idx] = xml[-1].message_names[idx]
00082
00083
00084 largest_payload = 0
00085 for x in xml:
00086 if x.largest_payload > largest_payload:
00087 largest_payload = x.largest_payload
00088 for x in xml:
00089 x.largest_payload = largest_payload
00090
00091 if mavparse.check_duplicates(xml):
00092 sys.exit(1)
00093
00094 print("Found %u MAVLink message types in %u XML files" % (
00095 mavparse.total_msgs(xml), len(xml)))
00096
00097
00098 opts.language = opts.language.lower()
00099 if opts.language == 'python':
00100 from . import mavgen_python
00101 mavgen_python.generate(opts.output, xml)
00102 elif opts.language == 'c':
00103 from . import mavgen_c
00104 mavgen_c.generate(opts.output, xml)
00105 elif opts.language == 'wlua':
00106 from . import mavgen_wlua
00107 mavgen_wlua.generate(opts.output, xml)
00108 elif opts.language == 'cs':
00109 from . import mavgen_cs
00110 mavgen_cs.generate(opts.output, xml)
00111 elif opts.language == 'javascript':
00112 from . import mavgen_javascript
00113 mavgen_javascript.generate(opts.output, xml)
00114 elif opts.language == 'objc':
00115 from . import mavgen_objc
00116 mavgen_objc.generate(opts.output, xml)
00117 elif opts.language == 'java':
00118 from . import mavgen_java
00119 mavgen_java.generate(opts.output, xml)
00120 else:
00121 print("Unsupported language %s" % opts.language)
00122
00123
00124
00125 class Opts:
00126 def __init__(self, output, wire_protocol=DEFAULT_WIRE_PROTOCOL, language=DEFAULT_LANGUAGE, validate=DEFAULT_VALIDATE, error_limit=DEFAULT_ERROR_LIMIT):
00127 self.wire_protocol = wire_protocol
00128 self.error_limit = error_limit
00129 self.language = language
00130 self.output = output
00131 self.validate = validate
00132
00133 def mavgen_python_dialect(dialect, wire_protocol):
00134 '''generate the python code on the fly for a MAVLink dialect'''
00135 dialects = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'dialects')
00136 mdef = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'message_definitions')
00137 if wire_protocol == mavparse.PROTOCOL_0_9:
00138 py = os.path.join(dialects, 'v09', dialect + '.py')
00139 xml = os.path.join(dialects, 'v09', dialect + '.xml')
00140 if not os.path.exists(xml):
00141 xml = os.path.join(mdef, 'v0.9', dialect + '.xml')
00142 else:
00143 py = os.path.join(dialects, 'v10', dialect + '.py')
00144 xml = os.path.join(dialects, 'v10', dialect + '.xml')
00145 if not os.path.exists(xml):
00146 xml = os.path.join(mdef, 'v1.0', dialect + '.xml')
00147 opts = Opts(py, wire_protocol)
00148
00149
00150 try:
00151 import StringIO as io
00152 except ImportError:
00153 import io
00154
00155
00156 stdout_saved = sys.stdout
00157 sys.stdout = io.StringIO()
00158 try:
00159 xml = os.path.relpath(xml)
00160 mavgen( opts, [xml] )
00161 except Exception:
00162 sys.stdout = stdout_saved
00163 raise
00164 sys.stdout = stdout_saved
00165
00166 if __name__ == "__main__":
00167 raise DeprecationWarning("Executable was moved to pymavlink.tools.mavgen")