forked from Archive/PX4-Autopilot
193 lines
4.3 KiB
Python
Executable File
193 lines
4.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
import xml.etree.ElementTree as ET
|
|
import os
|
|
import re
|
|
import codecs
|
|
|
|
class Scope(object):
|
|
"""
|
|
Single parameter group
|
|
"""
|
|
re_deep_lines = re.compile(r'.*\/.*\/')
|
|
def __init__(self, ):
|
|
self.scope = set()
|
|
|
|
|
|
def __str__(self):
|
|
return self.scope.__str__()
|
|
|
|
def Add(self, scope):
|
|
"""
|
|
Add Scope to set
|
|
"""
|
|
self.scope.add(scope)
|
|
|
|
def Has(self, scope):
|
|
"""
|
|
Check for existance
|
|
"""
|
|
if len(self.scope) == 0:
|
|
return True
|
|
# Anything in the form xxxxx/yyyyy/zzzzz....
|
|
# is treated as xxxxx/yyyyy
|
|
while (self.re_deep_lines.match(scope)):
|
|
scope = os.path.dirname(scope)
|
|
return scope in self.scope
|
|
|
|
|
|
class CMakeParser(object):
|
|
"""
|
|
Parses provided data and stores all found paths in scope.
|
|
"""
|
|
re_split_lines = re.compile(r'[\r\n]+')
|
|
re_comment = re.compile(r'^\#')
|
|
re_start = re.compile(r'set\s*\(\s*config_module_list')
|
|
re_end = re.compile(r'\)\s*')
|
|
|
|
def Parse(self, scope, contents):
|
|
"""
|
|
Incrementally parse cmake file contents and append all found path scope
|
|
to scope.
|
|
"""
|
|
# This code is essentially a comment-parsing grammar. "state"
|
|
# represents parser state. It contains human-readable state
|
|
# names.
|
|
state = None
|
|
for line in self.re_split_lines.split(contents):
|
|
line = line.strip()
|
|
# Ignore empty lines
|
|
if line == "":
|
|
continue
|
|
if self.re_comment.match(line):
|
|
continue
|
|
elif self.re_start.match(line):
|
|
state = "gather"
|
|
continue
|
|
elif state is not None and state == "gather":
|
|
if self.re_end.match(line):
|
|
return True
|
|
scope.Add(line)
|
|
return False
|
|
|
|
|
|
if len(os.sys.argv) < 2:
|
|
print("Error in %s" % os.sys.argv[0])
|
|
print("Usage: %s <parameters.xml> [cmake-file-scoping] " % os.sys.argv[0])
|
|
raise SystemExit
|
|
|
|
|
|
scope = Scope()
|
|
if len(os.sys.argv) == 3:
|
|
with codecs.open(os.sys.argv[2], 'r', 'utf-8') as f:
|
|
try:
|
|
contents = f.read()
|
|
f.close()
|
|
parser = CMakeParser()
|
|
parser.Parse(scope, contents)
|
|
except:
|
|
contents = ''
|
|
print('Failed reading file: %s, skipping scoping.' % os.sys.argv[2])
|
|
pass
|
|
|
|
fp_header = open("px4_parameters.h", "w")
|
|
fp_src = open("px4_parameters.c", "w")
|
|
|
|
tree = ET.parse(os.sys.argv[1])
|
|
root = tree.getroot()
|
|
|
|
# Generate the header file content
|
|
header = """
|
|
#include <stdint.h>
|
|
#include <systemlib/param/param.h>
|
|
|
|
// DO NOT EDIT
|
|
// This file is autogenerated from parameters.xml
|
|
|
|
__BEGIN_DECLS
|
|
|
|
struct px4_parameters_t {
|
|
"""
|
|
start_name = ""
|
|
end_name = ""
|
|
|
|
for group in root:
|
|
if group.tag == "group" and "no_code_generation" not in group.attrib:
|
|
section = """
|
|
/*****************************************************************
|
|
* %s
|
|
****************************************************************/""" % group.attrib["name"]
|
|
for param in group:
|
|
scope_ = param.find('scope').text
|
|
if not scope.Has(scope_):
|
|
continue
|
|
if not start_name:
|
|
start_name = param.attrib["name"]
|
|
end_name = param.attrib["name"]
|
|
header += section
|
|
section =""
|
|
header += """
|
|
const struct param_info_s __param__%s;""" % param.attrib["name"]
|
|
header += """
|
|
const unsigned int param_count;
|
|
};
|
|
|
|
extern const struct px4_parameters_t px4_parameters;
|
|
"""
|
|
|
|
# Generate the C file content
|
|
src = """
|
|
#include <px4_parameters.h>
|
|
|
|
// DO NOT EDIT
|
|
// This file is autogenerated from paramaters.xml
|
|
|
|
const
|
|
#ifndef __PX4_DARWIN
|
|
__attribute__((used, section("__param")))
|
|
#endif
|
|
struct px4_parameters_t px4_parameters = {
|
|
"""
|
|
i=0
|
|
for group in root:
|
|
if group.tag == "group" and "no_code_generation" not in group.attrib:
|
|
section = """
|
|
/*****************************************************************
|
|
* %s
|
|
****************************************************************/""" % group.attrib["name"]
|
|
for param in group:
|
|
scope_ = param.find('scope').text
|
|
if not scope.Has(scope_):
|
|
continue
|
|
if not start_name:
|
|
start_name = param.attrib["name"]
|
|
end_name = param.attrib["name"]
|
|
val_str = "#error UNKNOWN PARAM TYPE, FIX px_generate_params.py"
|
|
if (param.attrib["type"] == "FLOAT"):
|
|
val_str = ".val.f = "
|
|
elif (param.attrib["type"] == "INT32"):
|
|
val_str = ".val.i = "
|
|
i+=1
|
|
src += section
|
|
section =""
|
|
src += """
|
|
{
|
|
"%s",
|
|
PARAM_TYPE_%s,
|
|
%s%s
|
|
},
|
|
""" % (param.attrib["name"], param.attrib["type"], val_str, param.attrib["default"])
|
|
src += """
|
|
%d
|
|
};
|
|
|
|
//extern const struct px4_parameters_t px4_parameters;
|
|
|
|
__END_DECLS
|
|
|
|
""" % i
|
|
|
|
fp_header.write(header)
|
|
fp_src.write(src)
|
|
fp_header.close()
|
|
fp_src.close()
|