mavgen.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
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 # XSD schema file
00014 schemaFile = os.path.join(os.path.dirname(os.path.realpath(__file__)), "mavschema.xsd")
00015 
00016 # Set defaults for generating MAVLink code
00017 DEFAULT_WIRE_PROTOCOL = mavparse.PROTOCOL_1_0
00018 DEFAULT_LANGUAGE = 'Python'
00019 DEFAULT_ERROR_LIMIT = 200
00020 DEFAULT_VALIDATE = True
00021 
00022 # List the supported languages. This is done globally because it's used by the GUI wrapper too
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     # Enable validation by default, disabling it if explicitly requested
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         # use default values of minixsv, location of the schema file must be specified in the XML file
00047         domTreeWrapper = pyxsval.parseAndValidate(fname, xsdFile=schema, errorLimit=errorLimitNumber)
00048 
00049     # Process all XML files, validating them as necessary.
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     # expand includes
00061     for x in xml[:]:
00062         for i in x.include:
00063             fname = os.path.join(os.path.dirname(x.filename), i)
00064 
00065             ## Validate XML file with XSD file if possible.
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             ## Parsing
00073             print("Parsing %s" % fname)
00074             xml.append(mavparse.MAVXML(fname, opts.wire_protocol))
00075 
00076             # include message lengths and CRCs too
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     # work out max payload size across all includes
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     # Convert language option to lowercase and validate
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 # build all the dialects in the dialects subpackage
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      # Python 2 to 3 compatibility
00150     try:
00151         import StringIO as io
00152     except ImportError:
00153         import io
00154 
00155     # throw away stdout while generating
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")


mavlink
Author(s): Lorenz Meier
autogenerated on Wed Sep 9 2015 18:06:17