Skip to content

Commit 6d429b2

Browse files
committed
Generator for Python bindings.
Includes: 0. Command-line tool for generating Python bindings from YAML specifications. 1. Uses Python's Construct library for flexible, declarative binary parsing. 2. Basic syntax and schema validation on YAML specifications. Closes swift-nav#3, swift-nav#9, swift-nav#16. /cc @fnoble, @mfine
1 parent 200c60e commit 6d429b2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1880
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.DS_Store
22
*.*~
3+
limbo/
34

45
# Byte-compiled / optimized / DLL files
56
__pycache__/

generator/.coveragerc

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[run]
2+
branch = True
3+
include = sbp/*
4+
5+
[report]
6+
exclude_lines =
7+
# Have to re-enable the standard pragma
8+
pragma: no cover
9+
10+
# Don't complain about missing debug-only code:
11+
def __repr__
12+
if self\.debug
13+
14+
# Don't complain if non-runnable code isn't run:
15+
if 0:
16+
if __name__ == .__main__.:
17+
18+
ignore_errors = True
19+
20+
[omit]
21+
omit =
22+
tests/*
23+
limbo/*

generator/.gitignore

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
.DS_Store
2+
*.*~
3+
4+
# Byte-compiled / optimized / DLL files
5+
__pycache__/
6+
*.py[cod]
7+
8+
# C extensions
9+
*.so
10+
11+
# Distribution / packaging
12+
.Python
13+
env/
14+
build/
15+
develop-eggs/
16+
dist/
17+
downloads/
18+
eggs/
19+
lib/
20+
lib64/
21+
parts/
22+
sdist/
23+
var/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
28+
# PyInstaller
29+
# Usually these files are written by a python script from a template
30+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
31+
*.manifest
32+
*.spec
33+
34+
# Installer logs
35+
pip-log.txt
36+
pip-delete-this-directory.txt
37+
38+
# Unit test / coverage reports
39+
htmlcov/
40+
.tox/
41+
.coverage
42+
.cache
43+
nosetests.xml
44+
coverage.xml
45+
46+
# Translations
47+
*.mo
48+
*.pot
49+
50+
# Django stuff:
51+
*.log
52+
53+
# Sphinx documentation
54+
docs/_build/
55+
56+
# PyBuilder
57+
target/

generator/MANIFEST.in

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
include *.cfg
2+
include *.md
3+
include *.py
4+
include .coveragerc
5+
include .gitignore
6+
include LICENSE
7+
include tox.ini
8+
recursive-include doc/ *
9+
recursive-include sbp/ *.html
10+
recursive-include sbp/ *.j2
11+
recursive-include sbp/ *.py
12+
recursive-include tests *.py

generator/README.md

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## SBP Generator
2+
3+
A quite basic, template-based generator for generating SBP bindings in
4+
different languages.
5+
6+
## Usage
7+
8+
Courtesy of `argparse`:
9+
10+
```
11+
usage: generator.py [-h] -i INPUT_FILE -o OUTPUT_DIR [--python] [--c] [--docs] [-v]
12+
13+
Swift Navigation SBP generator.
14+
15+
optional arguments:
16+
-h, --help show this help message and exit
17+
-i INPUT_FILE, --input_file INPUT_FILE
18+
Input spec file or directory.
19+
-o OUTPUT_DIR, --output_dir OUTPUT_DIR
20+
Output directory.
21+
--python Target language: Python.
22+
--c Target language: C.
23+
-v, --verbose Print debugging info.
24+
```
25+
26+
For example,
27+
28+
```shell
29+
# Output C bindings:
30+
python sbp/generator.py -i ../spec/yaml/swift/sbp/ -o ../c/ --c
31+
32+
# Output Python bindings:
33+
python sbp/generator.py -i ../spec/yaml/swift/sbp/ -o ../python/ --c
34+
python sbp/generator.py -i ../spec/yaml/swift/sbp/navigation.yaml -o ../python/ --c
35+
36+
```
37+
38+
## Testing and Deployment
39+
40+
```shell
41+
# Install dependencies
42+
pip install -r requirements.txt
43+
44+
# Running tests
45+
py.test -q -vv test/
46+
47+
# Deploying to pypi
48+
49+
50+
```
51+
52+
## LICENSE
53+
54+
Copyright © 2015 Swift Navigation
55+
56+
Distributed under LGPLv3.0.

generator/requirements.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Jinja2
2+
PyYAML
3+
coverage
4+
docutils
5+
flake8
6+
mccabe
7+
pep8
8+
pyflakes
9+
pylint
10+
pytest
11+
tox
12+
voluptuous
13+
pytest-cov
14+
pytest-xdist

generator/sbp/__init__.py

Whitespace-only changes.

generator/sbp/generator.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/python
2+
3+
# Copyright (C) 2015 Swift Navigation Inc.
4+
# Contact: Bhaskar Mookerji <[email protected]>
5+
#
6+
# This source is subject to the license found in the file 'LICENSE' which must
7+
# be be distributed together with this source. All other rights reserved.
8+
#
9+
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10+
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
11+
# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12+
13+
"""
14+
Main executable.
15+
"""
16+
17+
import argparse
18+
import os
19+
import pprint
20+
import sbp.specs.yaml2 as yaml
21+
import sbp.targets.python as py
22+
import sbp.targets.c as c
23+
24+
def get_args():
25+
parser = argparse.ArgumentParser(description='Swift Navigation SBP generator.')
26+
parser.add_argument('-i',
27+
'--input_file',
28+
nargs=1,
29+
required=True,
30+
help='Input spec file or directory.')
31+
parser.add_argument('-o',
32+
'--output_dir',
33+
nargs=1,
34+
required=True,
35+
help='Output directory.')
36+
parser.add_argument('--python',
37+
action="store_true",
38+
help='Target language: Python.')
39+
parser.add_argument('--c',
40+
action="store_true",
41+
help='Target language: C.')
42+
parser.add_argument('-v',
43+
'--verbose',
44+
action="store_true",
45+
help='Print debugging info.')
46+
return parser
47+
48+
49+
# f = '../spec/yaml/swift/sbp/'
50+
# file_index = yaml.resolve_deps(*yaml.get_files(f))
51+
52+
def main():
53+
try:
54+
# Parse and validate arguments.
55+
args = get_args().parse_args()
56+
verbose = args.verbose
57+
assert args.python or args.c, "Please specify a target language."
58+
input_file = os.path.abspath(args.input_file[0])
59+
assert len(args.input_file) == 1
60+
assert os.path.exists(input_file), \
61+
"Invalid input file: %s. Exiting!" % input_file
62+
output_dir = os.path.abspath(args.output_dir[0])
63+
assert len(args.output_dir) == 1, "Only 1 output directory at a time."
64+
assert os.path.exists(output_dir), \
65+
"Invalid output directory: %s. Exiting!" % output_dir
66+
# Ingest, parse, and validate.
67+
file_index = yaml.resolve_deps(*yaml.get_files(input_file))
68+
if verbose:
69+
print "Reading files..."
70+
pprint.pprint(file_index.keys())
71+
print "Writing to %s" % output_dir
72+
# for fname, spec in file_index.items():
73+
# print yaml.parse_spec(spec)
74+
for fname, spec in file_index.items():
75+
parsed = yaml.parse_spec(spec)
76+
if not parsed.render_source:
77+
continue
78+
if args.python:
79+
py.render_source(output_dir, parsed)
80+
if args.c:
81+
c.render_source(output_dir, parsed)
82+
except KeyboardInterrupt:
83+
pass
84+
85+
if __name__ == '__main__':
86+
main()

generator/sbp/specs/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)