00001
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