from __future__ import with_statement ## Copyright 2010, 2011, 2012 Tony Garnock-Jones . ## ## This file is part of Hop. ## ## Hop is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Hop is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ## License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Hop. If not, see . copyright_stmt = \ '''/* Copyright 2010, 2011, 2012 Tony Garnock-Jones . * * This file is part of Hop. * * Hop is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Hop is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with Hop. If not, see . */ ''' 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]()