202 lines
4.3 KiB
Python
202 lines
4.3 KiB
Python
import logging
|
|
log = logging.getLogger("efl.eolian.conv")
|
|
|
|
import re
|
|
import keyword
|
|
|
|
from efl import eolian
|
|
|
|
class EolianTypeError(Exception):
|
|
pass
|
|
|
|
docstring_replacements = (
|
|
("@brief ", ""),
|
|
(re.compile(r"@ingroup .+", re.S), r""),
|
|
(re.compile(r"@see (.+)(?!@)"), r":see: \1"),
|
|
("@return ", ":return: "),
|
|
(re.compile(r"@(note|warning) "), r".. \1:: "),
|
|
(re.compile(r"@(p|c) (\w+)"), r"``\2``"),
|
|
(re.compile(r"@(b) (\w+)"), r"**\2**"),
|
|
(re.compile(r"@(i) (\w+)"), r"*\2*"),
|
|
("EINA_TRUE", "True"),
|
|
("EINA_FALSE", "False"),
|
|
("NULL", "None"),
|
|
)
|
|
|
|
builtin_types = ( # automatically converted by cython
|
|
"byte",
|
|
"ubyte",
|
|
#"char",
|
|
"short",
|
|
"ushort",
|
|
"int",
|
|
"uint",
|
|
"long",
|
|
"ulong",
|
|
"llong",
|
|
"ullong",
|
|
"int8",
|
|
"uint8",
|
|
"int16",
|
|
"uint16",
|
|
"int32",
|
|
"uint32",
|
|
"int64",
|
|
"uint64",
|
|
"int128",
|
|
"uint128",
|
|
"size",
|
|
"ssize",
|
|
"intptr",
|
|
"uintptr",
|
|
"ptrdiff",
|
|
#"time",
|
|
"float",
|
|
"double",
|
|
#"bool",
|
|
#"void",
|
|
"Evas_Coord",
|
|
"Evas_Real"
|
|
)
|
|
|
|
complex_types = (
|
|
"Eina_List"
|
|
)
|
|
|
|
mapping_in = {
|
|
# c_type: pyx_type
|
|
"bool": "bint",
|
|
"char": "",
|
|
"Evas_Object": "_Eo_Base",
|
|
"Eo": "_Eo_Base",
|
|
}
|
|
|
|
conversions_in = {
|
|
# c_type: conversion
|
|
"bool": None,
|
|
"char": "if isinstance({0}, unicode): {0} = PyUnicode_AsUTF8String({0})",
|
|
"Evas_Object": None,
|
|
"Eo": None,
|
|
}
|
|
|
|
mapping_out = {
|
|
# c_type: pyx_type
|
|
"bool": "bint",
|
|
"char": "unicode",
|
|
"Elm_Object_Item": "_ObjectItem",
|
|
"Evas_Object": "_Eo_Base",
|
|
"Eo": "_Eo_Base",
|
|
}
|
|
|
|
conversions_out = {
|
|
# c_type: conversion
|
|
"bool": "bool({0})",
|
|
"char": '{0}.decode("utf-8")',
|
|
"Elm_Object_Item *": 'object_item_to_python({0})',
|
|
"Evas_Object *": 'object_from_instance({0})',
|
|
"Eo": 'object_from_instance({0})',
|
|
}
|
|
|
|
|
|
def conv_cls_name(cls):
|
|
if cls.namespaces:
|
|
lib_name = ".".join(map(unicode.lower, cls.namespaces))
|
|
name = cls.name
|
|
else:
|
|
s = cls.name.split("_")
|
|
if len(s) > 1:
|
|
lib_name = s[0]
|
|
name = "_".join(s[1:])
|
|
else:
|
|
lib_name = s
|
|
name = s
|
|
|
|
return lib_name, name
|
|
|
|
|
|
def remove_type_prefixes(ctype):
|
|
for t in "const ", "unsigned ", "short ":
|
|
ctype = ctype.replace(t, "")
|
|
return ctype
|
|
|
|
|
|
def convert_in_param(tp, param_name, is_nonull=None):
|
|
c_type = tp.c_type
|
|
if tp.type == eolian.TypeType.POINTER:
|
|
tp = tp.base_type
|
|
if tp.type == eolian.TypeType.CLASS:
|
|
return None, "Eo", "{0}.obj".format(param_name)
|
|
|
|
key = tp.name if tp.name else c_type
|
|
|
|
if key in builtin_types:
|
|
return "", c_type, param_name
|
|
|
|
if not key in mapping_in:
|
|
raise EolianTypeError("Unknown IN type: %s" % (key))
|
|
|
|
conv_expr = conversions_in.get(key)
|
|
if conv_expr is not None:
|
|
conv_expr = conv_expr.format(param_name)
|
|
|
|
conv_t = mapping_in[key]
|
|
#if conv_t is None:
|
|
#conv_t = ""
|
|
|
|
if not is_nonull:
|
|
key = "<{0}>{1} if {1} is not None else NULL".format(c_type, param_name)
|
|
|
|
if keyword.iskeyword(param_name):
|
|
param_name += "_"
|
|
|
|
return conv_expr, conv_t, param_name
|
|
|
|
|
|
def convert_out_param(tp, param_name):
|
|
if tp.type == eolian.TypeType.POINTER:
|
|
tp = tp.base_type
|
|
if tp.type == eolian.TypeType.CLASS:
|
|
# TODO: set obj
|
|
return tp.c_type, param_name
|
|
|
|
key = tp.name if tp.name else tp.c_type
|
|
|
|
if key in builtin_types:
|
|
return tp.c_type, param_name
|
|
|
|
if not key in mapping_out:
|
|
raise EolianTypeError("Unknown OUT type: %s" % (key))
|
|
|
|
conv = conversions_out.get(key)
|
|
|
|
if conv:
|
|
param_name = conv.format(param_name)
|
|
|
|
if keyword.iskeyword(param_name):
|
|
param_name += "_"
|
|
|
|
return tp.c_type, param_name
|
|
|
|
|
|
def conv_type_ret(tp):
|
|
if tp.type == eolian.TypeType.POINTER:
|
|
tp = tp.base_type
|
|
|
|
c_type = tp.c_type
|
|
key = tp.name if tp.name else c_type
|
|
|
|
if key in builtin_types:
|
|
return c_type, c_type
|
|
|
|
py_t = mapping_out.get(key)
|
|
if py_t is None:
|
|
raise EolianTypeError("Unknown RET type: %s" % (key))
|
|
|
|
py_ret_type = py_t[0]
|
|
|
|
return py_ret_type, c_type
|
|
|
|
def event_conversion_get(tp):
|
|
if tp.type != eolian.TypeType.UNKNOWN:
|
|
return "Eo_Event_%s" % tp.name
|