96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
from __future__ import with_statement
|
|
|
|
# Copyright (C) 2010, 2011 Tony Garnock-Jones. All rights reserved.
|
|
copyright_stmt = '/* Copyright (C) 2010, 2011 Tony Garnock-Jones. All rights reserved. */'
|
|
|
|
import sys
|
|
import json
|
|
|
|
def cify(s):
|
|
s = s.replace('-', '_')
|
|
s = s.replace(' ', '_')
|
|
return s
|
|
|
|
class MessageType:
|
|
def __init__(self, j):
|
|
self.wire_selector = j['selector']
|
|
self.selector = cify(self.wire_selector)
|
|
self.wire_argnames = j['args']
|
|
self.argnames = map(cify, self.wire_argnames)
|
|
|
|
def format_args(self, template, separator = ', '):
|
|
return separator.join([template % (x,) for x in self.argnames])
|
|
|
|
with file("../../protocol/messages.json") as f:
|
|
spec = map(MessageType, json.load(f)['definitions'])
|
|
|
|
def entrypoint_header():
|
|
print copyright_stmt
|
|
print
|
|
print '#ifndef cmsg_messages_h'
|
|
print '#define cmsg_messages_h'
|
|
print
|
|
print 'extern void init_messages(void);'
|
|
print
|
|
for t in spec:
|
|
print 'extern sexp_t *selector_%s;' % (t.selector,)
|
|
print
|
|
for t in spec:
|
|
print 'extern sexp_t *message_%s(%s);' % (t.selector, t.format_args('sexp_t *%s'))
|
|
print
|
|
print 'typedef union parsed_message_t_ {'
|
|
for t in spec:
|
|
if t.argnames:
|
|
print ' struct { sexp_t %s; } %s;' % (t.format_args('*%s'), t.selector)
|
|
print '} parsed_message_t;'
|
|
for t in spec:
|
|
print
|
|
print 'static inline int parse_%s(sexp_t *message, parsed_message_t *out) {' % \
|
|
(t.selector,)
|
|
print ' if (!sexp_pairp(message)) return 0;'
|
|
print ' if (sexp_cmp(sexp_head(message), selector_%s) != 0) return 0;' % (t.selector,)
|
|
for n in t.argnames:
|
|
print ' if (!sexp_pseudo_pop(&message)) return 0;'
|
|
print ' out->%s.%s = sexp_head(message);' % (t.selector, n)
|
|
print ' return sexp_tail(message) == NULL;'
|
|
print '}'
|
|
print
|
|
print '#endif'
|
|
|
|
def entrypoint_body():
|
|
print copyright_stmt
|
|
print
|
|
print '#include <stdlib.h>'
|
|
print '#include <string.h>'
|
|
print '#include <stdio.h>'
|
|
print '#include <signal.h>'
|
|
print
|
|
print '#include <assert.h>'
|
|
print
|
|
print '#include "cmsg_private.h"'
|
|
print '#include "ref.h"'
|
|
print '#include "sexp.h"'
|
|
print '#include "messages.h"'
|
|
print
|
|
for t in spec:
|
|
print 'sexp_t *selector_%s = NULL;' % (t.selector,)
|
|
print
|
|
print 'void init_messages(void) {'
|
|
for t in spec:
|
|
print ' selector_%s = sexp_cstring("%s");' % (t.selector, t.wire_selector)
|
|
for t in spec:
|
|
print ' INCREF(selector_%s);' % (t.selector,)
|
|
print '}'
|
|
for t in spec:
|
|
print
|
|
print 'sexp_t *message_%s(%s) {' % (t.selector, t.format_args('sexp_t *%s'))
|
|
print ' sexp_t *m = NULL;'
|
|
for n in reversed(t.argnames):
|
|
print ' m = sexp_cons(%s, m);' % (n,)
|
|
print ' return sexp_cons(selector_%s, m);' % (t.selector,)
|
|
print '}'
|
|
|
|
if __name__ == '__main__':
|
|
drivername = sys.argv[1]
|
|
globals()['entrypoint_' + drivername]()
|