#!/usr/bin/env python """ Generate function define macros. """ from __future__ import print_function import string import sys import os # type -> (, , # , # , # , # ) type_table = { "string": ("const char*", "char*", "json_array_get_string_or_null_element", "searpc_set_string_to_ret_object", "json_array_add_string_or_null_element", "NULL"), "int": ("int", "int", "json_array_get_int_element", "searpc_set_int_to_ret_object", "json_array_add_int_element", "-1"), "int64": ("gint64", "gint64", "json_array_get_int_element", "searpc_set_int_to_ret_object", "json_array_add_int_element", "-1"), "object": ("GObject*", "GObject*", "", "searpc_set_object_to_ret_object", "", "NULL"), "objlist": ("GList*", "GList*", "", "searpc_set_objlist_to_ret_object", "", "NULL"), "json": ("const json_t*", "json_t*", "json_array_get_json_or_null_element", "searpc_set_json_to_ret_object", "json_array_add_json_or_null_element", "NULL"), } marshal_template = r""" static char * ${marshal_name} (void *func, json_t *param_array, gsize *ret_len) { GError *error = NULL; ${get_parameters} ${func_call} json_t *object = json_object (); ${convert_ret} return searpc_marshal_set_ret_common (object, ret_len, error); } """ def generate_marshal(ret_type, arg_types): ret_type_item = type_table[ret_type] ret_type_in_c = ret_type_item[1] template = string.Template(marshal_template) if len(arg_types) == 0: marshal_name = "marshal_" + ret_type + "__void" else: marshal_name = "marshal_" + ret_type + "__" + ('_'.join(arg_types)) get_parameters = "" for i, arg_type in enumerate(arg_types): type_item = type_table[arg_type] stmt = " %s param%d = %s (param_array, %d);\n" %( type_item[0], i+1, type_item[2], i+1) get_parameters += stmt # func_prototype should be something like # GList* (*)(const char*, int, GError **) func_prototype = ret_type_in_c + " (*)(" for arg_type in arg_types: func_prototype += type_table[arg_type][0] + ", " func_prototype += "GError **)" func_args = "" for i in range(1, len(arg_types)+1): func_args += "param%d, " % (i) func_args += "&error" func_call = "%s ret = ((%s)func) (%s);" % (ret_type_in_c, func_prototype, func_args) convert_ret = "%s (object, ret);" % ret_type_item[3] return template.substitute(marshal_name=marshal_name, get_parameters=get_parameters, func_call=func_call, convert_ret=convert_ret) def write_file(f, s): f.write(s) f.write('\n') def gen_marshal_functions(f): for item in func_table: write_file(f, generate_marshal(item[0], item[1])) marshal_register_item = r""" { searpc_server_register_marshal (${signature_name}(), ${marshal_name}); } """ def generate_marshal_register_item(ret_type, arg_types): if len(arg_types) == 0: marshal_name = "marshal_" + ret_type + "__void" else: marshal_name = "marshal_" + ret_type + "__" + ('_'.join(arg_types)) if len(arg_types) == 0: signature_name = "searpc_signature_" + ret_type + "__void" else: signature_name = "searpc_signature_" + ret_type + "__" + ( '_'.join(arg_types)) return string.Template(marshal_register_item).substitute( marshal_name=marshal_name, signature_name=signature_name) def gen_marshal_register_function(f): write_file(f, "static void register_marshals(void)""") write_file(f, "{") for item in func_table: write_file(f, generate_marshal_register_item(item[0], item[1])) write_file(f, "}") signature_template = r""" inline static gchar * ${signature_name}(void) { return searpc_compute_signature (${args}); } """ def generate_signature(ret_type, arg_types): ret_type_item = type_table[ret_type] ret_type_in_c = ret_type_item[1] if len(arg_types) == 0: signature_name = "searpc_signature_" + ret_type + "__void" else: signature_name = "searpc_signature_" + ret_type + "__" + ( '_'.join(arg_types)) args = "\"" + ret_type + "\"" + ", " + str(len(arg_types)) for arg_type in arg_types: args += ", " + "\"" + arg_type + "\"" template = string.Template(signature_template) return template.substitute(signature_name=signature_name, args=args) def gen_signature_list(): with open('searpc-signature.h', 'w') as f: for item in func_table: write_file(f, generate_signature(item[0], item[1])) if __name__ == "__main__": sys.path.append(os.getcwd()) # load function table if len(sys.argv) == 2: abspath = os.path.abspath(sys.argv[1]) with open(abspath, 'r') as fp: exec(fp.read()) print("loaded func_table from %s" % abspath) else: # load from default rpc_table.py from rpc_table import func_table # gen code with open('searpc-marshal.h', 'w') as marshal: gen_marshal_functions(marshal) gen_marshal_register_function(marshal) gen_signature_list()