generate.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import yaml
00004 import jinja2
00005 import re
00006 
00007 with open("sbp.yaml", 'r') as f:
00008   ds = yaml.load(f)
00009 
00010 LATEX_SUBS = (
00011     (re.compile(r'\\'), r'\\textbackslash'),
00012     (re.compile(r'([{}_#%&$])'), r'\\\1'),
00013     (re.compile(r'~'), r'\~{}'),
00014     (re.compile(r'\^'), r'\^{}'),
00015     (re.compile(r'_'), r'_'),
00016     (re.compile(r'"'), r"''"),
00017     (re.compile(r'\.\.\.+'), r'\\ldots'),
00018 )
00019 
00020 def escape_tex(value):
00021     newval = value
00022     for pattern, replacement in LATEX_SUBS:
00023         newval = pattern.sub(replacement, newval)
00024     return newval
00025 
00026 def commentify(value):
00027   return '\n'.join([' * ' + l for l in value.split('\n')[:-1]])
00028 
00029 acronyms = ['GPS', 'ECEF', 'LLH', 'NED']
00030 def classnameify(s):
00031   return ''.join(w if w in acronyms else w.title() for w in s.split('_'))
00032 
00033 jenv = jinja2.Environment(
00034     block_start_string = '((*',
00035     block_end_string = '*))',
00036     variable_start_string = '(((',
00037     variable_end_string = ')))',
00038     comment_start_string = '((=',
00039     comment_end_string = '=))',
00040     loader=jinja2.FileSystemLoader("./")
00041 )
00042 jenv.filters['escape_tex'] = escape_tex
00043 jenv.filters['commentify'] = commentify
00044 jenv.filters['classnameify'] = classnameify
00045 
00046 sizes = {
00047     'u8': 1,
00048     'u16': 2,
00049     'u32': 4,
00050     'u64': 8,
00051     's8': 1,
00052     's16': 2,
00053     's32': 4,
00054     's64': 8,
00055     'float': 4,
00056     'double': 8,
00057 }
00058 
00059 pystruct_code = {
00060     'u8': 'B',
00061     'u16': 'H',
00062     'u32': 'I',
00063     'u64': 'Q',
00064     's8': 'b',
00065     's16': 'h',
00066     's32': 'i',
00067     's64': 'q',
00068     'float': 'f',
00069     'double': 'd',
00070 }
00071 
00072 
00073 def pystruct_format(fields):
00074   return '<' + ''.join(pystruct_code[f['type']] for f in fields)
00075 jenv.filters['pystruct'] = pystruct_format
00076 
00077 def rejig_values(values):
00078     new_values = []
00079     for v in values:
00080         value, desc = v.iteritems().next()
00081         new_values.append({
00082             'value': value,
00083             'desc': desc
00084         })
00085     return new_values
00086 
00087 def rejig_bitfields(bfs):
00088     new_bfs = []
00089     n_with_values = 0
00090     for bf in bfs:
00091         rng, info = bf.iteritems().next()
00092         if 'values' in info:
00093             n_with_values += 1
00094             info['vals'] = rejig_values(info['values'])
00095             del info['values']
00096         rng = map(int, str(rng).split('-'))
00097         if len(rng) == 1:
00098             lsb = rng[0]
00099             bf_len = 1
00100         else:
00101             lsb, msb = rng
00102             bf_len = msb + 1 - lsb
00103         rng = ':'.join(map(str, rng))
00104         new_bfs.append(dict(info, **{
00105             'lsb': lsb,
00106             'range': rng,
00107             'len': bf_len,
00108         }))
00109     return new_bfs, n_with_values
00110 
00111 msgs = [[dict({'name': k}, **v) for k, v in d.iteritems()][0] for d in ds]
00112 for m in msgs:
00113     fields = []
00114     offset = 0
00115     max_type_len = 0
00116     max_name_len = 0
00117     for f in m['fields']:
00118         name, info = f.iteritems().next()
00119         if not 'units' in info:
00120             info.update({'units': ''})
00121         info['n_with_values'] = 0
00122         if 'fields' in info:
00123             info['fields'], info['n_with_values'] = rejig_bitfields(info['fields'])
00124         fields.append(dict(info, **{
00125             'name': name,
00126             'offset': offset,
00127             'size': sizes[info['type']],
00128         }))
00129         offset += sizes[info['type']]
00130         max_type_len = max(max_type_len, len(info['type']))
00131         max_name_len = max(max_name_len, len(name))
00132     m['max_type_len'] = max_type_len
00133     m['max_name_len'] = max_name_len
00134     m['fields'] = fields
00135     m['size'] = offset
00136 
00137 latex_template = jenv.get_template('message_descs.tex')
00138 with open("sbp_out.tex", 'w') as f:
00139     f.write(latex_template.render(msgs=msgs))
00140 
00141 c_template = jenv.get_template('sbp_messages_template.h')
00142 with open("../include/libswiftnav/sbp_messages.h", 'w') as f:
00143     f.write(c_template.render(msgs=msgs))
00144 
00145 py_template = jenv.get_template('sbp_messages_template.py')
00146 with open("sbp_messages.py", 'w') as f:
00147     f.write(py_template.render(msgs=msgs))
00148 
00149 import subprocess
00150 
00151 subprocess.call(["pdflatex" , "sbp_out.tex"])
00152 subprocess.call(["mv" , "sbp_out.pdf", "../docs/sbp.pdf"])
00153 


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:50