1
0
mirror of https://github.com/haiwen/libsearpc.git synced 2025-04-29 11:03:20 +00:00
libsearpc/lib/searpc-codegen.py

196 lines
5.7 KiB
Python
Raw Normal View History

#!/usr/bin/env python
2011-04-08 12:58:15 +00:00
"""
Generate function define macros.
"""
from __future__ import print_function
2011-04-08 12:58:15 +00:00
import string
import sys
2012-06-20 12:24:49 +00:00
import os
2011-04-08 12:58:15 +00:00
# type -> (<c type if used as parameter>, <c type if used as ret type>,
# <function to get value from array>,
# <function to set value to the ret_object>,
# <function to set value to array>,
# <default_ret_value>)
type_table = {
2013-08-08 08:24:20 +00:00
"string": ("const char*",
"char*",
2011-04-08 12:58:15 +00:00
"json_array_get_string_or_null_element",
"searpc_set_string_to_ret_object",
2011-04-08 12:58:15 +00:00
"json_array_add_string_or_null_element",
"NULL"),
"int": ("int",
"int",
2011-04-08 12:58:15 +00:00
"json_array_get_int_element",
"searpc_set_int_to_ret_object",
2011-04-08 12:58:15 +00:00
"json_array_add_int_element",
"-1"),
"int64": ("gint64",
"gint64",
2011-10-20 12:55:11 +00:00
"json_array_get_int_element",
"searpc_set_int_to_ret_object",
2011-10-20 12:55:11 +00:00
"json_array_add_int_element",
"-1"),
"object": ("GObject*",
2011-04-08 12:58:15 +00:00
"GObject*",
"",
"searpc_set_object_to_ret_object",
2011-04-08 12:58:15 +00:00
"",
"NULL"),
"objlist": ("GList*",
"GList*",
"",
"searpc_set_objlist_to_ret_object",
2011-04-08 12:58:15 +00:00
"",
"NULL"),
2016-06-28 02:46:17 +00:00
"json": ("const json_t*",
"json_t*",
2016-06-28 04:00:44 +00:00
"json_array_get_json_or_null_element",
2016-06-28 02:46:17 +00:00
"searpc_set_json_to_ret_object",
2016-06-28 04:00:44 +00:00
"json_array_add_json_or_null_element",
2016-06-28 02:46:17 +00:00
"NULL"),
2011-04-08 12:58:15 +00:00
}
marshal_template = r"""
2013-08-08 08:24:20 +00:00
static char *
${marshal_name} (void *func, json_t *param_array, gsize *ret_len)
2011-04-08 12:58:15 +00:00
{
GError *error = NULL;
${get_parameters}
${func_call}
2013-08-08 08:24:20 +00:00
json_t *object = json_object ();
2011-04-08 12:58:15 +00:00
${convert_ret}
return searpc_marshal_set_ret_common (object, ret_len, error);
2011-04-08 12:58:15 +00:00
}
"""
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
2011-04-08 12:58:15 +00:00
# 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)
2011-04-08 12:58:15 +00:00
convert_ret = "%s (object, ret);" % ret_type_item[3]
2011-04-08 12:58:15 +00:00
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')
2014-07-23 06:56:35 +00:00
def gen_marshal_functions(f):
2011-04-08 12:58:15 +00:00
for item in func_table:
write_file(f, generate_marshal(item[0], item[1]))
2011-04-08 12:58:15 +00:00
marshal_register_item = r"""
{
searpc_server_register_marshal (${signature_name}(), ${marshal_name});
2011-04-08 12:58:15 +00:00
}
"""
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)
2014-07-23 06:56:35 +00:00
def gen_marshal_register_function(f):
write_file(f, "static void register_marshals()""")
write_file(f, "{")
2011-04-08 12:58:15 +00:00
for item in func_table:
write_file(f, generate_marshal_register_item(item[0], item[1]))
write_file(f, "}")
2011-04-08 12:58:15 +00:00
signature_template = r"""
2011-11-13 06:09:58 +00:00
inline static gchar *
2011-04-08 12:58:15 +00:00
${signature_name}()
{
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))
2011-04-08 12:58:15 +00:00
args = "\"" + ret_type + "\"" + ", " + str(len(arg_types))
for arg_type in arg_types:
args += ", " + "\"" + arg_type + "\""
2011-04-08 12:58:15 +00:00
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]))
2011-04-08 12:58:15 +00:00
if __name__ == "__main__":
2012-06-20 12:24:49 +00:00
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()