mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-18 03:53:33 +08:00
Fix param scoping to use cmake for parsing.
This commit is contained in:
committed by
Lorenz Meier
parent
44c8857354
commit
85f62f5da0
@@ -1 +1 @@
|
||||
__all__ = ["srcscanner", "srcparser", "xmlout", "dokuwikiout", "dokuwikirpc", "cmakeparser", "scope"]
|
||||
__all__ = ["srcscanner", "srcparser", "xmlout", "dokuwikiout", "dokuwikirpc", "scope"]
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import re
|
||||
import codecs
|
||||
import sys
|
||||
|
||||
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
|
||||
+50
-94
@@ -1,107 +1,63 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Param source code generation script.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import xml.etree.ElementTree as ET
|
||||
import os
|
||||
import re
|
||||
import codecs
|
||||
import argparse
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
import os
|
||||
|
||||
from px4params import scope, cmakeparser
|
||||
def generate(xml_file, dest='.', modules=None):
|
||||
"""
|
||||
Generate px4 param source from xml.
|
||||
|
||||
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
|
||||
@param xml_file: input parameter xml file
|
||||
@param dest: Destination directory for generated files
|
||||
@param modules: The list of px4 modules to search for params.
|
||||
None means to scan everything.
|
||||
"""
|
||||
# pylint: disable=broad-except
|
||||
tree = ET.parse(xml_file)
|
||||
root = tree.getroot()
|
||||
|
||||
cmake_scope = 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.CMakeParser()
|
||||
parser.Parse(cmake_scope, contents)
|
||||
except:
|
||||
contents = ''
|
||||
print('Failed reading file: %s, skipping scoping.' % os.sys.argv[2])
|
||||
pass
|
||||
params = []
|
||||
for group in root:
|
||||
if group.tag == "group" and "no_code_generation" not in group.attrib:
|
||||
for param in group:
|
||||
scope_ = param.find('scope').text
|
||||
if (modules is not None) and (not scope_ in modules):
|
||||
continue
|
||||
params.append(param)
|
||||
|
||||
fp_header = open("px4_parameters.h", "w")
|
||||
fp_src = open("px4_parameters.c", "w")
|
||||
params = sorted(params, key=lambda name: name.attrib["name"])
|
||||
|
||||
tree = ET.parse(os.sys.argv[1])
|
||||
root = tree.getroot()
|
||||
script_path = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Generate the header file content
|
||||
header = """
|
||||
#include <stdint.h>
|
||||
#include <systemlib/param/param.h>
|
||||
# for jinja docs see: http://jinja.pocoo.org/docs/2.9/api/
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(os.path.join(script_path, 'templates')))
|
||||
|
||||
// DO NOT EDIT
|
||||
// This file is autogenerated from parameters.xml
|
||||
if not os.path.isdir(dest):
|
||||
os.path.mkdir(dest)
|
||||
|
||||
__BEGIN_DECLS
|
||||
template_files = [
|
||||
'px4_parameters.h.jinja',
|
||||
'px4_parameters.c.jinja',
|
||||
]
|
||||
for template_file in template_files:
|
||||
template = env.get_template(template_file)
|
||||
with open(os.path.join(
|
||||
dest, template_file.replace('.jinja','')), 'w') as fid:
|
||||
fid.write(template.render(params=params))
|
||||
|
||||
struct px4_parameters_t {
|
||||
"""
|
||||
params = []
|
||||
for group in root:
|
||||
if group.tag == "group" and "no_code_generation" not in group.attrib:
|
||||
for param in group:
|
||||
scope_ = param.find('scope').text
|
||||
if not cmake_scope.Has(scope_):
|
||||
continue
|
||||
params.append(param)
|
||||
if __name__ == "__main__":
|
||||
arg_parser = argparse.ArgumentParser()
|
||||
arg_parser.add_argument("--xml", help="parameter xml file")
|
||||
arg_parser.add_argument("--modules", help="px4 module list", default=None)
|
||||
arg_parser.add_argument("--dest", help="destination path", default=os.path.curdir)
|
||||
args = arg_parser.parse_args()
|
||||
generate(xml_file=args.xml, modules=args.modules, dest=args.dest)
|
||||
|
||||
params = sorted(params, key=lambda name: name.attrib["name"])
|
||||
for param in params:
|
||||
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 param in params:
|
||||
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 += """
|
||||
{
|
||||
"%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()
|
||||
# vim: set et fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
@@ -50,7 +50,7 @@ from __future__ import print_function
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
from px4params import srcscanner, srcparser, xmlout, dokuwikiout, dokuwikirpc, scope, cmakeparser
|
||||
from px4params import srcscanner, srcparser, xmlout, dokuwikiout, dokuwikirpc
|
||||
|
||||
import re
|
||||
import json
|
||||
@@ -112,11 +112,12 @@ def main():
|
||||
default="Automagically updated parameter documentation from code.",
|
||||
help="DokuWiki page edit summary")
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help="verbose output")
|
||||
parser.add_argument('--scope', default=None, action='store', help="pass the scope (list of compiled modules)")
|
||||
parser.add_argument("-o", "--overrides",
|
||||
default="{}",
|
||||
metavar="OVERRIDES",
|
||||
help="a dict of overrides in the form of a json string")
|
||||
parser.add_argument('--modules', default=None, action='store', help="list of compiled modules")
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -133,22 +134,8 @@ def main():
|
||||
# Scan directories, and parse the files
|
||||
if (args.verbose): print("Scanning source path " + args.src_path)
|
||||
|
||||
use_scope = False
|
||||
cmake_scope = scope.Scope();
|
||||
|
||||
if args.scope:
|
||||
with codecs.open(args.scope, 'r', 'utf-8') as f:
|
||||
try:
|
||||
contents = f.read()
|
||||
f.close()
|
||||
cmake_parser = cmakeparser.CMakeParser()
|
||||
cmake_parser.Parse(cmake_scope, contents)
|
||||
use_scope = True
|
||||
except:
|
||||
use_scope = False
|
||||
pass
|
||||
if use_scope and len(cmake_scope.scope) > 0:
|
||||
if not scanner.ScanDir([os.path.join(args.src_path, p) for p in cmake_scope.scope], parser):
|
||||
if args.modules is not None:
|
||||
if not scanner.ScanDir([os.path.join(args.src_path, p) for p in args.modules.split(',')], parser):
|
||||
sys.exit(1)
|
||||
else:
|
||||
if not scanner.ScanDir([args.src_path], parser):
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
{# jinja syntax: http://jinja.pocoo.org/docs/2.9/templates/ #}
|
||||
#include <px4_parameters.h>
|
||||
|
||||
// DO NOT EDIT
|
||||
// This file is autogenerated from paramaters.xml
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
const
|
||||
#ifndef __PX4_DARWIN
|
||||
__attribute__((used, section("__param")))
|
||||
#endif
|
||||
|
||||
struct px4_parameters_t px4_parameters = {
|
||||
{% for param in params %}
|
||||
{
|
||||
"{{ param.attrib["name"] }}",
|
||||
PARAM_TYPE_{{ param.attrib["type"] }},
|
||||
{%- if param.attrib["type"] == "FLOAT" %}
|
||||
.val.f = {{ param.attrib["default"] }}
|
||||
{%- elif param.attrib["type"] == "INT32" %}
|
||||
.val.i = {{ param.attrib["default"] }}
|
||||
{%- endif %}
|
||||
},
|
||||
{% endfor %}
|
||||
{{ params | length }}
|
||||
};
|
||||
|
||||
//extern const struct px4_parameters_t px4_parameters;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
{# vim: set noet ft=jinja fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : #}
|
||||
@@ -0,0 +1,21 @@
|
||||
{# jinja syntax: http://jinja.pocoo.org/docs/2.9/templates/ #}
|
||||
#include <stdint.h>
|
||||
#include <systemlib/param/param.h>
|
||||
|
||||
// DO NOT EDIT
|
||||
// This file is autogenerated from parameters.xml
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct px4_parameters_t {
|
||||
{%- for param in params %}
|
||||
const struct param_info_s __param__{{ param.attrib["name"] }};
|
||||
{%- endfor %}
|
||||
const unsigned int param_count;
|
||||
};
|
||||
|
||||
extern const struct px4_parameters_t px4_parameters;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
{# vim: set noet ft=jinja fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : #}
|
||||
Reference in New Issue
Block a user