import logging log = logging.getLogger("efl.eolian.conv") import re from efl import eolian 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 "short", "ushort", #"char", "int", "uint", "double", "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(name): s = name.split("_") if len(s) > 1: return s[0], "_".join(s[1:]) else: return name, name def remove_type_prefixes(ctype): for t in "const ", "unsigned ", "short ": ctype = ctype.replace(t, "") return ctype def convert_in_param(tp, 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, c_type, "{0}.obj".format(tp.name) key = tp.name if tp.name else c_type if key in builtin_types: return "", "", key conv_expr = conversions_in.get(key) if conv_expr is not None: conv_expr = conv_expr.format(name) if not key in mapping_in: raise TypeError("Unknown type: %s" % (key)) conv_t = mapping_in.get(key) if conv_t is None: if key not in builtin_types: log.warn("Unknown in param %s (type=%s, c_type=%s)", tp.name, tp.type, c_type) conv_t = "" if not is_nonull: key = "<{0}>{1} if {1} is not None else NULL".format(c_type, name) return conv_expr, conv_t, key def convert_out_param(tp, name): if tp.type == eolian.TypeType.POINTER: tp = tp.base_type if tp.type == eolian.TypeType.CLASS: # TODO: set obj return tp.c_type, name key = tp.name if tp.name else tp.c_type conv = conversions_out.get(key) if not conv: if not key in builtin_types: log.warn("Unknown out param %s (type=%s, c_type=%s)", tp.name, tp.type, tp.c_type) return tp.c_type, name name = conv.format(name) return tp.c_type, name def conv_type_ret(tp): if not tp: return if tp.type == eolian.TypeType.POINTER: tp = tp.base_type c_type = tp.c_type key = tp.name if tp.name else c_type #c_t = remove_type_prefixes(tp) py_t = mapping_out.get(key) if py_t is None: if key not in builtin_types: log.warn("Unknown ret type: %s, %s", key, tp.type) return c_type, c_type py_ret_type = py_t[0] #c_ret_type = remove_type_prefixes(c_type) return py_ret_type, c_type