#!/usr/bin/python # This script generates the boilerplate versions of most fops in the client, # mostly so that we can use STACK_WIND instead of STACK_WIND_TAIL (see # fop-template.c for the details). The problem we're solving is that we sit # under DHT, which makes assumptions about getting callbacks only from its # direct children. If we didn't define our own versions of these fops, the # default versions would use STACK_WIND_TAIL and the callbacks would come from # DHT's grandchildren. The code-generation approach allows us to handle this # with a minimum of code, and also keep up with any changes to the fop table. import sys sys.path.append("../../nsr-server/src") # Blech. import codegen type_re = "([a-z_0-9]+)" name_re = "\(\*fop_([a-z0-9]+)_t\)" full_re = type_re + " *" + name_re fop_cg = codegen.CodeGenerator() fop_cg.skip = 2 fop_cg.parse_decls(sys.argv[1],full_re) fop_cg.load_templates(sys.argv[2]) # Use the multi-template feature to generate multiple callbacks from the same # parsed declarations. type_re = "([a-z_0-9]+)" name_re = "\(\*fop_([a-z0-9]+)_cbk_t\)" full_re = type_re + " *" + name_re cbk_cg = codegen.CodeGenerator() cbk_cg.skip = 5 cbk_cg.parse_decls(sys.argv[1],full_re) cbk_cg.load_templates(sys.argv[2]) # This is a nasty little trick to handle the case where a generated fop needs # a set of default arguments for the corresponding callback. # # Yes, it's ironic that I'm copying and pasting the generator code. fop_cg.make_defaults = cbk_cg.make_defaults # Sorry, getspec, you're not a real fop until someone writes a stub function # for you. del fop_cg.decls["getspec"] del cbk_cg.decls["getspec"] # cbk is used by both fop and continue, so emit first for f_name in cbk_cg.decls.keys(): cbk_cg.emit(f_name,"cbk") print("") # continue is used by fop, so emit next for f_name in fop_cg.decls.keys(): fop_cg.emit(f_name,"cont-func") print("") for f_name in fop_cg.decls.keys(): fop_cg.emit(f_name,"fop") print("")