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 ' print '#include ' print '#include ' print '#include ' print print '#include ' 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]()