2125 lines
60 KiB
Cython
2125 lines
60 KiB
Cython
|
|
from libc.stdint cimport uintptr_t
|
|
from cpython cimport PyUnicode_AsUTF8String
|
|
from efl.eina cimport eina_inlist_count, EINA_LOG_DOM_DBG, \
|
|
EINA_LOG_DOM_INFO, EINA_LOG_DOM_WARN, EINA_LOG_DOM_ERR, \
|
|
EINA_LOG_DOM_CRIT, eina_iterator_next, eina_iterator_free, \
|
|
eina_stringshare_del
|
|
from efl.utils.conversions cimport _ctouni
|
|
from efl.utils.logger cimport add_logger
|
|
|
|
cdef int EOLIAN_DOM = add_logger("efl.eolian").eina_log_domain
|
|
|
|
from efl.utils.enum import IntEnum
|
|
|
|
class FunctionType(IntEnum):
|
|
"""Function Type"""
|
|
UNRESOLVED = EOLIAN_UNRESOLVED
|
|
PROPERTY = EOLIAN_PROPERTY
|
|
PROP_SET = EOLIAN_PROP_SET
|
|
PROP_GET = EOLIAN_PROP_GET
|
|
METHOD = EOLIAN_METHOD
|
|
|
|
class ParameterDir(IntEnum):
|
|
"""Parameter Direction"""
|
|
IN = EOLIAN_IN_PARAM
|
|
OUT = EOLIAN_OUT_PARAM
|
|
INOUT = EOLIAN_INOUT_PARAM
|
|
|
|
class ClassType(IntEnum):
|
|
"""Class Type"""
|
|
UNKNOWN = EOLIAN_CLASS_UNKNOWN_TYPE
|
|
REGULAR = EOLIAN_CLASS_REGULAR
|
|
ABSTRACT = EOLIAN_CLASS_ABSTRACT
|
|
MIXIN = EOLIAN_CLASS_MIXIN
|
|
INTERFACE = EOLIAN_CLASS_INTERFACE
|
|
|
|
class ObjectScope(IntEnum):
|
|
"""Object Scope"""
|
|
PUBLIC = EOLIAN_SCOPE_PUBLIC
|
|
PRIVATE = EOLIAN_SCOPE_PRIVATE
|
|
PROTECTED = EOLIAN_SCOPE_PROTECTED
|
|
|
|
class TypeType(IntEnum):
|
|
"""Type"""
|
|
UNKNOWN = EOLIAN_TYPE_UNKNOWN_TYPE
|
|
VOID = EOLIAN_TYPE_VOID
|
|
REGULAR = EOLIAN_TYPE_REGULAR
|
|
REGULAR_STRUCT = EOLIAN_TYPE_REGULAR_STRUCT
|
|
REGULAR_ENUM = EOLIAN_TYPE_REGULAR_ENUM
|
|
COMPLEX = EOLIAN_TYPE_COMPLEX
|
|
POINTER = EOLIAN_TYPE_POINTER
|
|
FUNCTION = EOLIAN_TYPE_FUNCTION
|
|
STRUCT = EOLIAN_TYPE_STRUCT
|
|
STRUCT_OPAQUE = EOLIAN_TYPE_STRUCT_OPAQUE
|
|
ENUM = EOLIAN_TYPE_ENUM
|
|
ALIAS = EOLIAN_TYPE_ALIAS
|
|
CLASS = EOLIAN_TYPE_CLASS
|
|
|
|
class ExpressionType(IntEnum):
|
|
UNKNOWN = EOLIAN_EXPR_UNKNOWN
|
|
INT = EOLIAN_EXPR_INT
|
|
UINT = EOLIAN_EXPR_UINT
|
|
LONG = EOLIAN_EXPR_LONG
|
|
ULONG = EOLIAN_EXPR_ULONG
|
|
LLONG = EOLIAN_EXPR_LLONG
|
|
ULLONG = EOLIAN_EXPR_ULLONG
|
|
FLOAT = EOLIAN_EXPR_FLOAT
|
|
DOUBLE = EOLIAN_EXPR_DOUBLE
|
|
STRING = EOLIAN_EXPR_STRING
|
|
CHAR = EOLIAN_EXPR_CHAR
|
|
NULL_ = EOLIAN_EXPR_NULL
|
|
BOOL = EOLIAN_EXPR_BOOL
|
|
NAME = EOLIAN_EXPR_NAME
|
|
ENUM = EOLIAN_EXPR_ENUM
|
|
UNARY = EOLIAN_EXPR_UNARY
|
|
BINARY = EOLIAN_EXPR_BINARY
|
|
|
|
class ExpressionMask(IntEnum):
|
|
SINT = EOLIAN_MASK_SINT
|
|
UINT = EOLIAN_MASK_UINT
|
|
INT = EOLIAN_MASK_INT
|
|
FLOAT = EOLIAN_MASK_FLOAT
|
|
BOOL = EOLIAN_MASK_BOOL
|
|
STRING = EOLIAN_MASK_STRING
|
|
CHAR = EOLIAN_MASK_CHAR
|
|
NULL_ = EOLIAN_MASK_NULL
|
|
NUMBER = EOLIAN_MASK_NUMBER
|
|
ALL = EOLIAN_MASK_ALL
|
|
|
|
class VariableType(IntEnum):
|
|
UNKNOWN = EOLIAN_VAR_UNKNOWN
|
|
CONSTANT = EOLIAN_VAR_CONSTANT
|
|
GLOBAL = EOLIAN_VAR_GLOBAL
|
|
|
|
class BinaryOperator(IntEnum):
|
|
INVALID = EOLIAN_BINOP_INVALID
|
|
|
|
ADD = EOLIAN_BINOP_ADD
|
|
SUB = EOLIAN_BINOP_SUB
|
|
MUL = EOLIAN_BINOP_MUL
|
|
DIV = EOLIAN_BINOP_DIV
|
|
MOD = EOLIAN_BINOP_MOD
|
|
|
|
EQ = EOLIAN_BINOP_EQ
|
|
NQ = EOLIAN_BINOP_NQ
|
|
GT = EOLIAN_BINOP_GT
|
|
LT = EOLIAN_BINOP_LT
|
|
GE = EOLIAN_BINOP_GE
|
|
LE = EOLIAN_BINOP_LE
|
|
|
|
AND = EOLIAN_BINOP_AND
|
|
OR = EOLIAN_BINOP_OR
|
|
|
|
BAND = EOLIAN_BINOP_BAND
|
|
BOR = EOLIAN_BINOP_BOR
|
|
BXOR = EOLIAN_BINOP_BXOR
|
|
LSH = EOLIAN_BINOP_LSH
|
|
RSH = EOLIAN_BINOP_RSH
|
|
|
|
class UnaryOperator(IntEnum):
|
|
INVALID = EOLIAN_UNOP_INVALID
|
|
|
|
UNM = EOLIAN_UNOP_UNM
|
|
UNP = EOLIAN_UNOP_UNP
|
|
|
|
NOT = EOLIAN_UNOP_NOT
|
|
BNOT = EOLIAN_UNOP_BNOT
|
|
|
|
|
|
|
|
cdef class EinaIterator(object):
|
|
|
|
cdef:
|
|
Eina_Iterator *itr
|
|
type cls
|
|
|
|
def __init__(self, type cls):
|
|
self.cls = cls
|
|
|
|
cdef object _set_obj(self, Eina_Iterator *itr):
|
|
self.itr = itr
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __nonzero__(self):
|
|
return self.itr is not NULL
|
|
|
|
def __next__(self):
|
|
cdef:
|
|
void *data
|
|
bint itr_ret
|
|
|
|
if self.itr is NULL:
|
|
raise StopIteration
|
|
itr_ret = eina_iterator_next(self.itr, &data)
|
|
if not itr_ret:
|
|
eina_iterator_free(self.itr)
|
|
self.itr = NULL
|
|
raise StopIteration
|
|
|
|
return void_ptr_to_python_obj(data, self.cls)
|
|
|
|
cdef object void_ptr_to_python_obj(void *data, type cls):
|
|
if data == NULL:
|
|
EINA_LOG_DOM_DBG(
|
|
EOLIAN_DOM, "struct pointer is NULL", NULL
|
|
)
|
|
return None
|
|
if cls is Class:
|
|
return eolian_class_to_python_obj(<const Eolian_Class *>data)
|
|
elif cls is Function:
|
|
return eolian_func_to_python_obj(<const Eolian_Function *>data)
|
|
elif cls is FunctionParameter:
|
|
return eolian_func_param_to_python_obj(<const Eolian_Function_Parameter *>data)
|
|
elif cls is Type:
|
|
return eolian_type_to_python_obj(<const Eolian_Type *>data)
|
|
elif cls is TypeStructField:
|
|
return eolian_type_struct_field_to_python_obj(<const Eolian_Struct_Type_Field *>data)
|
|
elif cls is TypeEnumField:
|
|
return eolian_type_enum_field_to_python_obj(<const Eolian_Enum_Type_Field *>data)
|
|
elif cls is Implement:
|
|
return eolian_implement_to_python_obj(<const Eolian_Implement *>data)
|
|
elif cls is Constructor:
|
|
return eolian_constructor_to_python_obj(<const Eolian_Constructor *>data)
|
|
elif cls is Event:
|
|
return eolian_event_to_python_obj(<const Eolian_Event *>data)
|
|
elif cls is Expression:
|
|
return eolian_expression_to_python_obj(<const Eolian_Expression *>data)
|
|
elif cls is Variable:
|
|
return eolian_variable_to_python_obj(<const Eolian_Variable *>data)
|
|
# elif cls is Value:
|
|
# return eolian_value_to_python_obj(<Eolian_Value>data)
|
|
elif cls is unicode:
|
|
return _ctouni(<const char *>data)
|
|
else:
|
|
EINA_LOG_DOM_WARN(
|
|
EOLIAN_DOM, "Unknown type for conversion", NULL
|
|
)
|
|
return
|
|
|
|
|
|
cdef Class eolian_class_to_python_obj(const Eolian_Class *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Class ret = Class.__new__(Class)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Function eolian_func_to_python_obj(const Eolian_Function *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Function ret = Function.__new__(Function)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef FunctionParameter eolian_func_param_to_python_obj(const Eolian_Function_Parameter *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef FunctionParameter ret = FunctionParameter.__new__(FunctionParameter)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Type eolian_type_to_python_obj(const Eolian_Type *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Type ret = Type.__new__(Type)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef TypeStructField eolian_type_struct_field_to_python_obj(const Eolian_Struct_Type_Field *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef TypeStructField ret = TypeStructField.__new__(TypeStructField)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef TypeEnumField eolian_type_enum_field_to_python_obj(const Eolian_Enum_Type_Field *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef TypeEnumField ret = TypeEnumField.__new__(TypeEnumField)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Implement eolian_implement_to_python_obj(const Eolian_Implement *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Implement ret = Implement.__new__(Implement)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Constructor eolian_constructor_to_python_obj(const Eolian_Constructor *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Constructor ret = Constructor.__new__(Constructor)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Event eolian_event_to_python_obj(const Eolian_Event *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Event ret = Event.__new__(Event)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Expression eolian_expression_to_python_obj(const Eolian_Expression *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Expression ret = Expression.__new__(Expression)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Value eolian_value_to_python_obj(Eolian_Value o):
|
|
cdef Value ret = Value.__new__(Value)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
cdef Variable eolian_variable_to_python_obj(const Eolian_Variable *o):
|
|
if o == NULL:
|
|
return None
|
|
cdef Variable ret = Variable.__new__(Variable)
|
|
ret._set_obj(o)
|
|
return ret
|
|
|
|
|
|
def eo_file_parse(filename):
|
|
"""Parse a given .eo file and fill the database.
|
|
|
|
During parsing, the class described into the .eo file is created with
|
|
all the information related to this class.
|
|
|
|
:param filename: Name of the file to parse.
|
|
|
|
"""
|
|
if isinstance(filename, unicode):
|
|
filename = PyUnicode_AsUTF8String(filename)
|
|
cdef bint ret = eolian_eo_file_parse(filename)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in eo_file_parse()", NULL)
|
|
return ret
|
|
|
|
def eot_file_parse(filename):
|
|
"""Parse a given .eot file and fill the database.
|
|
|
|
:param filename: Name of the file to parse.
|
|
:see: :func:`eolian_eo_file_parse`
|
|
|
|
"""
|
|
if isinstance(filename, unicode): filename = PyUnicode_AsUTF8String(filename)
|
|
cdef bint ret = eolian_eot_file_parse(filename)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in eot_file_parse()", NULL)
|
|
return ret
|
|
|
|
def init():
|
|
"""Init Eolian.
|
|
|
|
:rtype: int
|
|
|
|
"""
|
|
EINA_LOG_DOM_INFO(EOLIAN_DOM, "Initializing efl.eolian", NULL)
|
|
return eolian_init()
|
|
|
|
def shutdown():
|
|
"""Shutdown Eolian.
|
|
|
|
:rtype: int
|
|
|
|
"""
|
|
EINA_LOG_DOM_INFO(EOLIAN_DOM, "Shutting down efl.eolian", NULL)
|
|
return eolian_shutdown()
|
|
|
|
def directory_scan(directory):
|
|
"""Scan the given directory and search for .eo files.
|
|
|
|
The found files are just open to extract the class name.
|
|
|
|
:param dir: the directory to scan
|
|
:return: True on success, False otherwise.
|
|
|
|
"""
|
|
if isinstance(directory, unicode): directory = PyUnicode_AsUTF8String(directory)
|
|
cdef bint ret = eolian_directory_scan(directory)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in directory_scan()", NULL)
|
|
return ret
|
|
|
|
def system_directory_scan():
|
|
"""Scan the system directory (recursively) and search for .eo and
|
|
.eot files.
|
|
|
|
:return: True on success, False otherwise.
|
|
|
|
"""
|
|
cdef bint ret = eolian_system_directory_scan()
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in system_directory_scan()", NULL)
|
|
return ret
|
|
|
|
def all_eo_files_parse():
|
|
"""Force parsing of all the files located in the directories
|
|
given in eolian_directory_scan.
|
|
|
|
:return: True on success, False otherwise.
|
|
|
|
:see: :py:func:`directory_scan`
|
|
|
|
"""
|
|
cdef bint ret = eolian_all_eo_files_parse()
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in all_eo_files_parse()", NULL)
|
|
return ret
|
|
|
|
def all_eot_files_parse():
|
|
"""Force parsing of all the .eot files located in the directories
|
|
given in eolian_directory_scan.
|
|
|
|
:return: True on success, False otherwise.
|
|
|
|
:see: :py:func:`directory_scan`
|
|
|
|
"""
|
|
cdef bint ret = eolian_all_eot_files_parse()
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in all_eot_files_parse()", NULL)
|
|
return ret
|
|
|
|
def database_validate():
|
|
"""Validates the database, printing errors and warnings.
|
|
|
|
Useful to catch type errors etc. early on.
|
|
|
|
:return: True on success, False otherwise.
|
|
|
|
"""
|
|
return bool(eolian_database_validate())
|
|
|
|
def show_class(Class klass=None):
|
|
"""Show information about a given class.
|
|
|
|
If ``klass`` is None, this function will print information of
|
|
all the classes stored into the database.
|
|
|
|
:param klass: the class to show
|
|
|
|
:return: True on success, False otherwise (when class is not found).
|
|
|
|
"""
|
|
cdef bint ret = eolian_show_class(
|
|
klass.klass if klass is not None else NULL
|
|
)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in show_class()", NULL)
|
|
return ret
|
|
|
|
def show_typedef(alias):
|
|
"""Show information about a given typedef.
|
|
|
|
If ``alias`` is None, this function will print information of
|
|
all the typedefs.
|
|
|
|
:return: True on success, False otherwise (when typedef is not found).
|
|
|
|
"""
|
|
if isinstance(alias, unicode): alias = PyUnicode_AsUTF8String(alias)
|
|
cdef bint ret = eolian_show_typedef(
|
|
<const char *>alias if alias is not None else NULL
|
|
)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in show_typedef()", NULL)
|
|
return ret
|
|
|
|
def show_struct(name):
|
|
"""Show information about a given struct.
|
|
|
|
If ``name`` is None, this function will print information of
|
|
all the named global structs.
|
|
|
|
:return: True on success, False otherwise (when struct is not found).
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
cdef bint ret = eolian_show_struct(
|
|
<const char *>name if name is not None else NULL
|
|
)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in show_struct()", NULL)
|
|
return ret
|
|
|
|
def show_enum(name):
|
|
"""Show information about a given enum.
|
|
|
|
If @c name is NULL, this function will print information of
|
|
all the enums.
|
|
|
|
:param name: the enum to show.
|
|
|
|
:return: True on success, False otherwise (when enum is not
|
|
found).
|
|
|
|
@see eolian_show_class
|
|
@see eolian_show_typedef
|
|
@see eolian_show_struct
|
|
@see eolian_show_global
|
|
@see eolian_show_constant
|
|
@see eolian_show_all
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
cdef bint ret = eolian_show_enum(
|
|
<const char *>name if name is not None else NULL
|
|
)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in show_enum()", NULL)
|
|
return ret
|
|
|
|
def show_global(name):
|
|
"""Show information about a given global.
|
|
|
|
If @c name is NULL, this function will print information of
|
|
all the globals.
|
|
|
|
:param name: the global to show.
|
|
|
|
:return: True on success, False otherwise (when global is not
|
|
found).
|
|
|
|
@see eolian_show_class
|
|
@see eolian_show_typedef
|
|
@see eolian_show_struct
|
|
@see eolian_show_enum
|
|
@see eolian_show_constant
|
|
@see eolian_show_all
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
cdef bint ret = eolian_show_global(
|
|
<const char *>name if name is not None else NULL
|
|
)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in show_global()", NULL)
|
|
return ret
|
|
|
|
def show_constant(name):
|
|
"""Show information about a given constant.
|
|
|
|
If @c name is NULL, this function will print information of
|
|
all the constants.
|
|
|
|
:param name: the constant to show.
|
|
|
|
:return: True on success, False otherwise (when constant is not
|
|
found).
|
|
|
|
@see eolian_show_class
|
|
@see eolian_show_typedef
|
|
@see eolian_show_struct
|
|
@see eolian_show_enum
|
|
@see eolian_show_global
|
|
@see eolian_show_all
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
cdef bint ret = eolian_show_constant(
|
|
<const char *>name if name is not None else NULL
|
|
)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in show_constant()", NULL)
|
|
return ret
|
|
|
|
def show_all():
|
|
"""Show information about everything.
|
|
|
|
This will print a complete dump of all information stored in the Eolian
|
|
database.
|
|
|
|
"""
|
|
eolian_show_all()
|
|
|
|
def all_classes_get():
|
|
"""Returns an iterator to all the classes stored into the database.
|
|
|
|
:return: the iterator
|
|
|
|
"""
|
|
cdef EinaIterator ret = EinaIterator(Class)
|
|
ret._set_obj(eolian_all_classes_get())
|
|
return ret
|
|
|
|
def type_enum_get_by_name(name):
|
|
"""Get an enum by name. Supports namespaces.
|
|
|
|
@param[in] name the name of the struct
|
|
:return: the struct or NULL
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
cdef const Eolian_Type *ret
|
|
|
|
ret = eolian_type_enum_get_by_name(
|
|
<const char *>name if name is not None else NULL
|
|
)
|
|
if not ret:
|
|
EINA_LOG_DOM_WARN(EOLIAN_DOM, "Failure in type_enum_get_by_name()", NULL)
|
|
|
|
return eolian_type_to_python_obj(ret)
|
|
|
|
def type_aliases_get_by_file(file_name):
|
|
"""Get an iterator to all aliases contained in a file.
|
|
|
|
:param fname: the file name without full path
|
|
:return: the iterator or NULL
|
|
|
|
Thanks to internal caching, this is an O(1) operation.
|
|
|
|
"""
|
|
if isinstance(file_name, unicode):
|
|
file_name = PyUnicode_AsUTF8String(file_name)
|
|
cdef EinaIterator ret = EinaIterator(Type)
|
|
ret._set_obj(eolian_type_aliases_get_by_file(file_name))
|
|
return ret
|
|
|
|
def type_structs_get_by_file(file_name):
|
|
"""Get an iterator to all named structs contained in a file.
|
|
|
|
:param fname: the file name without full path
|
|
:return: the iterator or None
|
|
|
|
Thanks to internal caching, this is an O(1) operation.
|
|
|
|
"""
|
|
if isinstance(file_name, unicode):
|
|
file_name = PyUnicode_AsUTF8String(file_name)
|
|
cdef EinaIterator ret = EinaIterator(Type)
|
|
ret._set_obj(eolian_type_structs_get_by_file(file_name))
|
|
return ret
|
|
|
|
def type_enums_get_by_file(file_name):
|
|
"""Get an iterator to all enums contained in a file.
|
|
|
|
@param[in] fname the file name without full path
|
|
:return: the iterator or NULL
|
|
|
|
Thanks to internal caching, this is an O(1) operation.
|
|
|
|
"""
|
|
if isinstance(file_name, unicode):
|
|
file_name = PyUnicode_AsUTF8String(file_name)
|
|
cdef EinaIterator ret = EinaIterator(Type)
|
|
ret._set_obj(eolian_type_enums_get_by_file(file_name))
|
|
return ret
|
|
|
|
def variable_global_get_by_name(name):
|
|
"""Get a global variable by name. Supports namespaces.
|
|
|
|
@param[in] name the name of the variable
|
|
:return: the variable handle or NULL
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
return eolian_variable_to_python_obj(eolian_variable_global_get_by_name(<const char *>name))
|
|
|
|
def variable_constant_get_by_name(name):
|
|
"""Get a constant variable by name. Supports namespaces.
|
|
|
|
@param[in] name the name of the variable
|
|
:return: the variable handle or NULL
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
return eolian_variable_to_python_obj(eolian_variable_constant_get_by_name(<const char *>name))
|
|
|
|
def variable_globals_get_by_file(fname):
|
|
"""Get an iterator to all global variables contained in a file.
|
|
|
|
@param[in] fname the file name without full path
|
|
:return: the iterator or NULL
|
|
|
|
Thanks to internal caching, this is an O(1) operation.
|
|
|
|
"""
|
|
if isinstance(fname, unicode): fname = PyUnicode_AsUTF8String(fname)
|
|
cdef EinaIterator ret = EinaIterator(Variable)
|
|
ret._set_obj(eolian_variable_globals_get_by_file(<const char *>fname))
|
|
return ret
|
|
|
|
def variable_constants_get_by_file(fname):
|
|
"""Get an iterator to all constant variables contained in a file.
|
|
|
|
@param[in] fname the file name without full path
|
|
:return: the iterator or NULL
|
|
|
|
Thanks to internal caching, this is an O(1) operation.
|
|
|
|
"""
|
|
if isinstance(fname, unicode): fname = PyUnicode_AsUTF8String(fname)
|
|
cdef EinaIterator ret = EinaIterator(Variable)
|
|
ret._set_obj(eolian_variable_constants_get_by_file(<const char *>fname))
|
|
return ret
|
|
|
|
|
|
cdef class Class(object):
|
|
|
|
cdef const Eolian_Class *klass
|
|
|
|
cdef _set_obj(self, const Eolian_Class *obj):
|
|
if obj == NULL:
|
|
raise ValueError("obj is NULL!")
|
|
self.klass = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return (
|
|
"<%s (full_name=%s, filename=%s, namespaces=%r, type=%s, inherits=%s, "
|
|
"description=%s)>" % (
|
|
self.name, self.full_name, self.filename, list(self.namespaces),
|
|
self.type, list(self.inherits),
|
|
self.description.replace('\n', ' ') if self.description else \
|
|
None
|
|
))
|
|
|
|
@classmethod
|
|
def get_by_name(cls, class_name):
|
|
"""Gets a class by its name
|
|
|
|
:param class_name: name of the class to get.
|
|
:return: the class
|
|
|
|
"""
|
|
cdef:
|
|
const Eolian_Class *klass
|
|
Class ret
|
|
if isinstance(class_name, unicode): class_name = PyUnicode_AsUTF8String(class_name)
|
|
klass = eolian_class_get_by_name(class_name)
|
|
if klass is NULL:
|
|
return
|
|
ret = Class.__new__(Class)
|
|
ret._set_obj(klass)
|
|
return ret
|
|
|
|
@classmethod
|
|
def get_by_file(cls, file_name):
|
|
"""Gets a class by its filename (name.eo)
|
|
|
|
:param file_name: the filename
|
|
:return: the class stored in the file
|
|
|
|
"""
|
|
cdef:
|
|
const Eolian_Class *klass
|
|
Class ret
|
|
if isinstance(file_name, unicode): file_name = PyUnicode_AsUTF8String(file_name)
|
|
klass = eolian_class_get_by_file(file_name)
|
|
if klass is NULL:
|
|
return
|
|
ret = Class.__new__(Class)
|
|
ret._set_obj(klass)
|
|
return ret
|
|
|
|
property filename:
|
|
"""Returns the name of the file containing the given class.
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_class_file_get(self.klass))
|
|
|
|
property full_name:
|
|
"""Returns the full name of the given class.
|
|
|
|
:type: string
|
|
|
|
The full name and the name of a class will be different if namespaces
|
|
are used.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_class_full_name_get(self.klass))
|
|
|
|
property name:
|
|
"""Returns the name of the given class.
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_class_name_get(self.klass))
|
|
|
|
property namespaces:
|
|
"""Returns an iterator to the namespaces of the given class.
|
|
|
|
:return: the iterator on success or None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(unicode)
|
|
ret._set_obj(eolian_class_namespaces_get(self.klass))
|
|
return ret
|
|
|
|
property type:
|
|
"""Returns the class type of the given class
|
|
|
|
:type: :class:`ClassType`
|
|
|
|
"""
|
|
def __get__(self):
|
|
return ClassType(eolian_class_type_get(self.klass))
|
|
|
|
def function_get_by_name(self, func_name, Eolian_Function_Type f_type):
|
|
"""Get a function in a class by its name and type
|
|
|
|
:param func_name: name of the function
|
|
:param f_type: type of the function
|
|
:return: the function id if found, None otherwise.
|
|
|
|
"""
|
|
if isinstance(func_name, unicode):
|
|
func_name = PyUnicode_AsUTF8String(func_name)
|
|
return eolian_func_to_python_obj(
|
|
eolian_class_function_get_by_name(self.klass, func_name, f_type)
|
|
)
|
|
|
|
property description:
|
|
"""Returns the description of a class.
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_class_description_get(self.klass))
|
|
|
|
property legacy_prefix:
|
|
"""Returns the legacy prefix of a class
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_class_legacy_prefix_get(self.klass))
|
|
|
|
property eo_prefix:
|
|
"""Returns the eo prefix of a class
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_class_eo_prefix_get(self.klass))
|
|
|
|
property data_type:
|
|
"""Returns the data type of a class
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_class_data_type_get(self.klass))
|
|
|
|
property inherits:
|
|
"""Returns an iterator to the names of inherit classes of a class
|
|
|
|
:return: the iterator
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(unicode)
|
|
ret._set_obj(eolian_class_inherits_get(self.klass))
|
|
return ret
|
|
|
|
def functions_get(self, Eolian_Function_Type func_type):
|
|
"""Returns an iterator to functions of a class.
|
|
|
|
:param func_type: type of the functions to insert into the list.
|
|
:return: the iterator
|
|
|
|
"""
|
|
cdef EinaIterator ret = EinaIterator(Function)
|
|
ret._set_obj(eolian_class_functions_get(self.klass, func_type))
|
|
return ret
|
|
|
|
property implements:
|
|
"""Get an iterator to the overriding functions defined in a class.
|
|
|
|
:return: the iterator
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(Implement)
|
|
ret._set_obj(eolian_class_implements_get(self.klass))
|
|
return ret
|
|
|
|
property constructors:
|
|
"""Get an iterator to the constructing functions defined in a class.
|
|
|
|
@param[in] klass the class.
|
|
:return: the iterator
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(Constructor)
|
|
ret._set_obj(eolian_class_constructors_get(self.klass))
|
|
return ret
|
|
|
|
property events:
|
|
"""Get an iterator to the events defined in a class.
|
|
|
|
:return: the iterator
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(Event)
|
|
ret._set_obj(eolian_class_events_get(self.klass))
|
|
return ret
|
|
|
|
property constructor_enabled:
|
|
"""Indicates if the class constructor has to invoke
|
|
a non-generated class constructor function.
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_class_ctor_enable_get(self.klass))
|
|
|
|
property destructor_enabled:
|
|
"""Indicates if the class destructor has to invoke
|
|
a non-generated class destructor function.
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_class_dtor_enable_get(self.klass))
|
|
|
|
def function_get_by_name(self, func_name, Eolian_Function_Type f_type):
|
|
"""Find a function in a class by its name and type
|
|
|
|
:param func_name: name of the function
|
|
:type func_name: string
|
|
:param f_type: type of the function
|
|
:type ftype: :class:`FunctionType`
|
|
:return: the function id if found, None otherwise.
|
|
|
|
"""
|
|
if isinstance(func_name, unicode):
|
|
func_name = PyUnicode_AsUTF8String(func_name)
|
|
return eolian_func_to_python_obj(
|
|
eolian_class_function_get_by_name(
|
|
self.klass, func_name, f_type
|
|
)
|
|
)
|
|
|
|
|
|
cdef class Function(object):
|
|
|
|
cdef const Eolian_Function *function_id
|
|
|
|
cdef _set_obj(self, const Eolian_Function *obj):
|
|
if obj == NULL:
|
|
raise ValueError("obj is NULL!")
|
|
self.function_id = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return (
|
|
"<%s (type=%s, scope=%s, object_is_const=%r, is_class=%s, parameters=%r)>" % (
|
|
self.name, self.type, self.scope, self.object_is_const,
|
|
self.is_class, list(self.parameters)
|
|
))
|
|
|
|
property type:
|
|
"""Returns the type of a function
|
|
|
|
:type: :class:`FunctionType`
|
|
|
|
"""
|
|
def __get__(self):
|
|
return FunctionType(eolian_function_type_get(self.function_id))
|
|
|
|
property scope:
|
|
"""Returns the scope of a function
|
|
|
|
:type: :class:`ObjectScope`
|
|
|
|
"""
|
|
def __get__(self):
|
|
return ObjectScope(eolian_function_scope_get(self.function_id))
|
|
|
|
property name:
|
|
"""Returns the name of a function
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_function_name_get(self.function_id))
|
|
|
|
property full_c_name:
|
|
"""Returns the full C name of a function. It's here
|
|
because the C API names are deduplicated (prefix of function and suffix
|
|
of prefix merge if applicable) and this helps generators not write the
|
|
same code over and over.
|
|
|
|
:param prefix: function prefix
|
|
:type prefix: string
|
|
:return: the function name
|
|
:rtype: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef Eina_Stringshare *ret1
|
|
ret1 = eolian_function_full_c_name_get(self.function_id)
|
|
ret2 = _ctouni(ret1)
|
|
eina_stringshare_del(ret1)
|
|
return ret2
|
|
|
|
def legacy_get(self, Eolian_Function_Type f_type):
|
|
"""Returns a legacy name for a function.
|
|
|
|
@param[in] function_id Id of the function
|
|
@param[in] f_type The function type, for property get/set distinction.
|
|
:return: the legacy name or NULL.
|
|
|
|
"""
|
|
return _ctouni(eolian_function_legacy_get(self.function_id, f_type))
|
|
|
|
def description_get(self, Eolian_Function_Type f_type):
|
|
"""Returns a description for a function.
|
|
|
|
@param[in] function_id Id of the function
|
|
@param[in] f_type The function type, for property get/set distinction.
|
|
:return: the description or NULL.
|
|
|
|
"""
|
|
return _ctouni(eolian_function_description_get(self.function_id, f_type))
|
|
|
|
def is_virtual_pure_get(self, Eolian_Function_Type f_type):
|
|
"""Indicates if a function is virtual pure.
|
|
|
|
:param ftype: type of the function
|
|
:type ftype: :class:`FunctionType`
|
|
:return: True if virtual pure, False otherwise.
|
|
:rtype: bool
|
|
|
|
"""
|
|
return bool(eolian_function_is_virtual_pure(self.function_id, f_type))
|
|
|
|
def is_auto_get(self, Eolian_Function_Type f_type):
|
|
"""Indicates if a function is auto.
|
|
|
|
@param[in] function_id Id of the function
|
|
@param[in] f_type The function type, for property get/set distinction.
|
|
:return: True if auto, False othrewise.
|
|
|
|
"""
|
|
return bool(eolian_function_is_auto(self.function_id, f_type))
|
|
|
|
def is_empty_get(self, Eolian_Function_Type f_type):
|
|
"""Indicates if a function is empty.
|
|
|
|
@param[in] function_id Id of the function
|
|
@param[in] f_type The function type, for property get/set distinction.
|
|
:return: True if empty, False othrewise.
|
|
|
|
"""
|
|
return bool(eolian_function_is_empty(self.function_id, f_type))
|
|
|
|
def is_legacy_only_get(self, Eolian_Function_Type f_type):
|
|
"""Indicates if a function is legacy only.
|
|
|
|
@param[in] function_id Id of the function
|
|
@param[in] f_type The function type, for property get/set distinction.
|
|
:return: True if legacy only, False otherwise.
|
|
|
|
"""
|
|
return bool(eolian_function_is_legacy_only(self.function_id, f_type))
|
|
|
|
property is_class:
|
|
"""Get whether a function is a class method/property.
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_function_is_class(self.function_id))
|
|
|
|
def parameter_get_by_name(self, param_name):
|
|
"""Returns a parameter of a function pointed by its id.
|
|
|
|
:param param_name: Name of the parameter
|
|
:type param_name: string
|
|
:return: a handle to this parameter.
|
|
:rtype: :class:`FunctionParameter`
|
|
|
|
"""
|
|
if isinstance(param_name, unicode):
|
|
param_name = PyUnicode_AsUTF8String(param_name)
|
|
return eolian_func_param_to_python_obj(
|
|
eolian_function_parameter_get_by_name(
|
|
self.function_id, param_name
|
|
)
|
|
)
|
|
|
|
property property_keys:
|
|
"""Returns an iterator to the keys params of a given function.
|
|
|
|
:type: iterator of :class:`FunctionParameter`
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(FunctionParameter)
|
|
ret._set_obj(eolian_property_keys_get(self.function_id))
|
|
return ret
|
|
|
|
property property_values:
|
|
"""Returns an iterator to the values params of a given function.
|
|
|
|
:type: iterator of :class:`FunctionParameter`
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(FunctionParameter)
|
|
ret._set_obj(eolian_property_values_get(self.function_id))
|
|
return ret
|
|
|
|
property parameters:
|
|
"""Returns an iterator to the parameter handles for a method/ctor/dtor.
|
|
|
|
:return: the iterator
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(FunctionParameter)
|
|
ret._set_obj(eolian_function_parameters_get(self.function_id))
|
|
return ret
|
|
|
|
def return_type_get(self, Eolian_Function_Type ftype):
|
|
"""Get the return type of a function.
|
|
|
|
:param ftype: Function Type
|
|
:type ftype: :class:`FunctionType`
|
|
:return: the types of the function return
|
|
:rtype: :class:`Type`
|
|
|
|
"""
|
|
return eolian_type_to_python_obj(
|
|
eolian_function_return_type_get(
|
|
self.function_id, ftype
|
|
)
|
|
)
|
|
|
|
def return_default_value_get(self, Eolian_Function_Type ftype):
|
|
"""Get the return default value of a function.
|
|
|
|
:param ftype: type of the function
|
|
:type ftype: :class:`FunctionType`
|
|
:return: the return default value of the function
|
|
:rtype: string
|
|
|
|
The return default value is needed to return an appropriate
|
|
value if an error occurs (eo_do failure...).
|
|
The default value is not mandatory, so None can be returned.
|
|
|
|
"""
|
|
return eolian_expression_to_python_obj(eolian_function_return_default_value_get(
|
|
self.function_id, ftype
|
|
))
|
|
|
|
def return_comment_get(self, Eolian_Function_Type ftype):
|
|
"""Get the return comment of a function.
|
|
|
|
:param ftype: type of the function
|
|
:type ftype: :class:`FunctionType`
|
|
:return: the return comment of the function
|
|
:rtype: string
|
|
|
|
The type of the function is needed because a given function can
|
|
represent a property, that can be set and get functions.
|
|
|
|
"""
|
|
return _ctouni(eolian_function_return_comment_get(
|
|
self.function_id, ftype
|
|
))
|
|
|
|
def return_is_warn_unused_get(self, Eolian_Function_Type ftype):
|
|
"""Indicates if a function return is warn-unused.
|
|
|
|
:param ftype: type of the function
|
|
:type ftype: :class:`FunctionType`
|
|
:return: True is warn-unused, False otherwise.
|
|
:rtype: bool
|
|
|
|
The type of the function is needed because a given function can
|
|
represent a property, that can be set and get functions.
|
|
|
|
"""
|
|
return bool(eolian_function_return_is_warn_unused(
|
|
self.function_id, ftype
|
|
))
|
|
|
|
property object_is_const:
|
|
"""Indicates if a function object is const.
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_function_object_is_const(self.function_id))
|
|
|
|
|
|
cdef class FunctionParameter(object):
|
|
|
|
cdef const Eolian_Function_Parameter *param
|
|
|
|
cdef _set_obj(self, const Eolian_Function_Parameter *obj):
|
|
if obj == NULL:
|
|
raise ValueError("obj is NULL!")
|
|
self.param = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return (
|
|
"<%s (type=%s, direction=%s, is_nonull=%r, description=%s)>" % (
|
|
self.name, self.type, self.direction, self.is_nonull,
|
|
self.description.replace('\n', ' ') if self.description else None
|
|
))
|
|
|
|
property direction:
|
|
"""Get direction of a parameter
|
|
|
|
:return: the direction of the parameter
|
|
|
|
"""
|
|
def __get__(self):
|
|
return ParameterDir(eolian_parameter_direction_get(self.param))
|
|
|
|
|
|
property type:
|
|
"""Get type of a parameter
|
|
|
|
:type: :py:class:`Type`
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_type_to_python_obj(
|
|
eolian_parameter_type_get(self.param)
|
|
)
|
|
|
|
property default_value:
|
|
"""Get the default value of a parameter
|
|
|
|
:return: the value or NULL
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_expression_to_python_obj(eolian_parameter_default_value_get(self.param))
|
|
|
|
property name:
|
|
"""Get name of a parameter
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_parameter_name_get(self.param))
|
|
|
|
property description:
|
|
"""Get description of a parameter
|
|
|
|
:return: the description of the parameter or NULL
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_parameter_description_get(self.param))
|
|
|
|
def const_attribute_get(self, bint is_get):
|
|
"""Indicates if a parameter has a const attribute.
|
|
|
|
This function is relevant for properties, to know if a parameter is a
|
|
const parameter in the get operation.
|
|
|
|
:param bool is_get: indicates if the information needed is for get or
|
|
set.
|
|
:return: True if const in get, False otherwise
|
|
|
|
"""
|
|
return bool(eolian_parameter_const_attribute_get(self.param, is_get))
|
|
|
|
property is_nonull:
|
|
"""Indicates if a parameter cannot be None.
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_parameter_is_nonull(self.param))
|
|
|
|
|
|
cdef class Implement(object):
|
|
|
|
cdef const Eolian_Implement *impl
|
|
|
|
cdef _set_obj(self, const Eolian_Implement *obj):
|
|
if obj == NULL:
|
|
raise ValueError("obj is NULL!")
|
|
self.impl = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return (
|
|
"<%s (class=%r, function=%r)>" % (
|
|
self.full_name, self.klass, self.function
|
|
))
|
|
|
|
property full_name:
|
|
"""Get full string of an overriding function (implement).
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_implement_full_name_get(self.impl))
|
|
|
|
property klass:
|
|
"""Get the class of an overriding function (implement).
|
|
|
|
:return: the class handle or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_class_to_python_obj(eolian_implement_class_get(self.impl))
|
|
|
|
property function:
|
|
"""Get the function of an implement.
|
|
|
|
@param[out] func_type the function type.
|
|
:return: the function handle or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef:
|
|
const Eolian_Function *ret
|
|
Eolian_Function_Type func_type
|
|
ret = eolian_implement_function_get(self.impl, &func_type)
|
|
return (FunctionType(func_type), eolian_func_to_python_obj(ret))
|
|
|
|
property is_auto:
|
|
"""Get whether an implement is tagged with @auto.
|
|
|
|
:return: True when it is, False when it's not.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_implement_is_auto(self.impl))
|
|
|
|
property is_empty:
|
|
"""Get whether an implement is tagged with @empty.
|
|
|
|
:return: True when it is, False when it's not.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_implement_is_empty(self.impl))
|
|
|
|
property is_virtual:
|
|
"""Get whether an implement is tagged with @virtual.
|
|
|
|
:return: True when it is, False when it's not.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_implement_is_virtual(self.impl))
|
|
|
|
property is_prop_get:
|
|
"""Get whether an implement references a property getter.
|
|
|
|
:return: True when it does, False when it's not.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_implement_is_prop_get(self.impl))
|
|
|
|
property is_prop_set:
|
|
"""Get whether an implement references a property setter.
|
|
|
|
:return: True when it does, False when it's not.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_implement_is_prop_set(self.impl))
|
|
|
|
|
|
cdef class Constructor(object):
|
|
|
|
cdef const Eolian_Constructor *ctor
|
|
|
|
cdef _set_obj(self, const Eolian_Constructor *obj):
|
|
if obj == NULL:
|
|
raise ValueError("obj is NULL")
|
|
self.ctor = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return (
|
|
"<%s (class=%r, function=%r)>" % (
|
|
self.full_name, self.klass, self.function
|
|
))
|
|
|
|
property full_name:
|
|
"""Get full string of a constructing function.
|
|
|
|
:return: the full string.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_constructor_full_name_get(self.ctor))
|
|
|
|
property klass:
|
|
"""Get the class of a constructing function.
|
|
|
|
:return: the class handle or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_class_to_python_obj(eolian_constructor_class_get(self.ctor))
|
|
|
|
property function:
|
|
"""Get the function of a constructing function.
|
|
|
|
:return: the function handle or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_func_to_python_obj(eolian_constructor_function_get(self.ctor))
|
|
|
|
|
|
cdef class Event(object):
|
|
|
|
cdef const Eolian_Event *event
|
|
|
|
cdef _set_obj(self, const Eolian_Event *obj):
|
|
if obj == NULL:
|
|
raise ValueError("obj is NULL!")
|
|
self.event = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return (
|
|
"<%s (type=%s, description=%s, scope=%s, c_name=%s)>" % (
|
|
self.name, self.type, self.description, self.scope,
|
|
self.c_name
|
|
))
|
|
|
|
property name:
|
|
"""Get the name of an event.
|
|
|
|
:return: the name or NULL
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_event_name_get(self.event))
|
|
|
|
property type:
|
|
"""Get the type of an event.
|
|
|
|
:return: the type or NULL
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_type_to_python_obj(eolian_event_type_get(self.event))
|
|
|
|
property description:
|
|
"""Get the description of an event.
|
|
|
|
:return: the description or NULL
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_event_description_get(self.event))
|
|
|
|
property scope:
|
|
"""Returns the scope of an event
|
|
|
|
:return: the event scope
|
|
|
|
"""
|
|
def __get__(self):
|
|
return ObjectScope(eolian_event_scope_get(self.event))
|
|
|
|
property c_name:
|
|
"""Returns the C name of an event
|
|
|
|
:return: the event C name
|
|
|
|
You're responsible for deleting the stringshare.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef Eina_Stringshare *ret1
|
|
ret1 = eolian_event_c_name_get(self.event)
|
|
ret2 = _ctouni(ret1)
|
|
eina_stringshare_del(ret1)
|
|
return ret2
|
|
|
|
|
|
cdef class Type(object):
|
|
|
|
"""Parameter/return type."""
|
|
|
|
cdef const Eolian_Type *tp
|
|
|
|
cdef _set_obj(self, const Eolian_Type *obj):
|
|
if obj == NULL:
|
|
raise ValueError("obj is NULL!")
|
|
self.tp = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return "<%s(type=%s, description=%s)>" % (
|
|
self.name,
|
|
self.type, self.description
|
|
)
|
|
|
|
@classmethod
|
|
def alias_get_by_name(cls, name):
|
|
"""Get an alias type by name. Supports namespaces.
|
|
|
|
:param name: the name of the alias
|
|
:return: the alias type or None
|
|
|
|
"""
|
|
cdef:
|
|
Type ret = cls.__new__(cls)
|
|
Eolian_Type *obj
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
obj = eolian_type_alias_get_by_name(name)
|
|
if obj == NULL:
|
|
return None
|
|
ret._set_obj(obj)
|
|
return ret
|
|
|
|
@classmethod
|
|
def struct_get_by_name(cls, name):
|
|
"""Get a struct by name. Supports namespaces.
|
|
|
|
:param name: the name of the struct
|
|
:return: the struct or None
|
|
|
|
"""
|
|
cdef:
|
|
Type ret = cls.__new__(cls)
|
|
Eolian_Type *obj
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
obj = eolian_type_struct_get_by_name(name)
|
|
if obj == NULL:
|
|
return None
|
|
ret._set_obj(obj)
|
|
return ret
|
|
|
|
property type:
|
|
"""Get the type of a type (regular, function, pointer)
|
|
|
|
:return: EOLIAN_TYPE_UNKNOWN_TYPE when ``tp`` is None, otherwise
|
|
EOLIAN_TYPE_REGULAR, EOLIAN_TYPE_POINTER or EOLIAN_TYPE_FUNCTION.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return TypeType(eolian_type_type_get(self.tp))
|
|
|
|
property arguments:
|
|
"""Get an iterator to all arguments of a function type.
|
|
|
|
:return: the iterator when ``tp`` is an EOLIAN_TYPE_FUNCTION, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(Type)
|
|
ret._set_obj(eolian_type_arguments_get(self.tp))
|
|
return ret
|
|
|
|
property subtypes:
|
|
"""Get an iterator to all subtypes of a type.
|
|
|
|
:return: the iterator when ``tp`` is an EOLIAN_TYPE_REGULAR or
|
|
EOLIAN_TYPE_POINTER and has subtypes, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(Type)
|
|
ret._set_obj(eolian_type_subtypes_get(self.tp))
|
|
return ret
|
|
|
|
property struct_fields:
|
|
"""Get an iterator to all fields of a struct type.
|
|
|
|
:return: the iterator when ``tp`` is EOLIAN_TYPE_STRUCT, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(TypeStructField)
|
|
ret._set_obj(eolian_type_struct_fields_get(self.tp))
|
|
return ret
|
|
|
|
def struct_field_get(self, field):
|
|
"""Get a field of a struct type.
|
|
|
|
:param field: the field name.
|
|
:return: the field when ``tp`` is EOLIAN_TYPE_STRUCT, ``field`` is not None
|
|
and the field exists, None otherwise.
|
|
|
|
"""
|
|
if isinstance(field, unicode): field = PyUnicode_AsUTF8String(field)
|
|
return eolian_type_struct_field_to_python_obj(eolian_type_struct_field_get(self.tp, field))
|
|
|
|
property enum_fields:
|
|
"""Get an iterator to all fields of an enum type.
|
|
|
|
:return: the iterator when @c tp is EOLIAN_TYPE_ENUM, NULL otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(TypeEnumField)
|
|
ret._set_obj(eolian_type_enum_fields_get(self.tp))
|
|
return ret
|
|
|
|
def enum_field_get(self, field):
|
|
"""Get a field of an enum type.
|
|
|
|
@param[in] field the field name.
|
|
:return: the field when @c tp is EOLIAN_TYPE_ENUM, @c field is not NULL,
|
|
field exists and has a value set, NULL otherwise.
|
|
|
|
Keep in mind that this can return NULL for an existing field, particularly
|
|
when the field has no value set (i.e. increments by 1 over previous value).
|
|
|
|
"""
|
|
if isinstance(field, unicode): field = PyUnicode_AsUTF8String(field)
|
|
return eolian_type_enum_field_to_python_obj(eolian_type_enum_field_get(
|
|
self.tp,
|
|
<const char *>field if field is not None else NULL
|
|
))
|
|
|
|
|
|
property enum_legacy_prefix:
|
|
"""Get the legacy prefix of enum field names. When not specified,
|
|
enum name is used.
|
|
|
|
:return: the legacy prefix or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_enum_legacy_prefix_get(self.tp))
|
|
|
|
property description:
|
|
"""Get the description of a struct/alias type.
|
|
|
|
:return: the description when ``tp`` is EOLIAN_TYPE_STRUCT, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_description_get(self.tp))
|
|
|
|
property filename:
|
|
"""Get the filename of a struct/alias type.
|
|
|
|
:return: the filename when ``tp`` is EOLIAN_TYPE_STRUCT, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_file_get(self.tp))
|
|
|
|
property return_type:
|
|
"""Get the return type of a function type.
|
|
|
|
:return: the return type when ``tp`` is an EOLIAN_TYPE_FUNCTION, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_type_to_python_obj(eolian_type_return_type_get(self.tp))
|
|
|
|
property base_type:
|
|
"""Get the base type of a pointer or alias type.
|
|
|
|
:return: the base type when ``tp`` is a pointer or alias, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_type_to_python_obj(eolian_type_base_type_get(self.tp))
|
|
|
|
property klass:
|
|
"""Get the class associated with an EOLIAN_TYPE_CLASS type.
|
|
|
|
:return: the class or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_class_to_python_obj(eolian_type_class_get(self.tp))
|
|
|
|
property is_own:
|
|
"""Get whether the given type is @own.
|
|
|
|
:return: True when ``tp`` is a non-function type and not None,
|
|
False otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_type_is_own(self.tp))
|
|
|
|
property is_const:
|
|
"""Get whether the given type is const.
|
|
|
|
:return: True when ``tp`` is a non-function type and not None,
|
|
False otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_type_is_const(self.tp))
|
|
|
|
property is_extern:
|
|
"""Check if a struct or alias type is extern.
|
|
|
|
:return: True if it's extern, False otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_type_is_extern(self.tp))
|
|
|
|
def c_type_named_get(self, name):
|
|
"""Get the full C type name of the given type with a name.
|
|
|
|
:param name: the name.
|
|
:return: The C type name assuming ``tp`` is not None.
|
|
|
|
Providing the name is useful for function types, as in C a function
|
|
pointer type alone is not valid syntax. For non-function types, the
|
|
name is simply appended to the type (with a space). C type names do
|
|
not include subtypes as C doesn't support them. Name is ignored for
|
|
alias types. Alias types are turned into C typedefs.
|
|
|
|
Keep in mind that if ``name`` is None, the name won't be included.
|
|
|
|
"""
|
|
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
|
cdef Eina_Stringshare *ret1
|
|
ret1 = eolian_type_c_type_named_get(self.tp, name)
|
|
ret2 = _ctouni(ret1)
|
|
eina_stringshare_del(ret1)
|
|
return ret2
|
|
|
|
property c_type:
|
|
"""Get the full C type name of the given type without a name.
|
|
|
|
:return: The C type name assuming ``tp`` is not None.
|
|
|
|
This behaves exactly like eolian_type_c_type_named_get when name is None.
|
|
Keep in mind that this is not useful for function types as a function
|
|
pointer type in C cannot be used without a name.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef Eina_Stringshare *ret1
|
|
ret1 = eolian_type_c_type_get(self.tp)
|
|
ret2 = _ctouni(ret1)
|
|
eina_stringshare_del(ret1)
|
|
return ret2
|
|
|
|
property name:
|
|
"""Get the name of the given type. For EOLIAN_TYPE_REGULAR and
|
|
EOLIAN_TYPE_REGULAR_STRUCT, this is for example "int". For
|
|
EOLIAN_TYPE_STRUCT and EOLIAN_TYPE_ALIAS, this is the name of the alias
|
|
or of the struct. Keep in mind that the name doesn't include namespaces
|
|
for structs and aliases.
|
|
|
|
:return: the name.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_name_get(self.tp))
|
|
|
|
property full_name:
|
|
"""Get the full (namespaced) name of a function. Only works on named
|
|
types (not pointers, not functions, not void).
|
|
|
|
:return: the name.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_full_name_get(self.tp))
|
|
|
|
property namespaces:
|
|
"""Get an iterator to the list of namespaces of the given type. Only
|
|
works on named types (not pointers, not functions, not void).
|
|
|
|
:return: the iterator.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(unicode)
|
|
ret._set_obj(eolian_type_namespaces_get(self.tp))
|
|
return ret
|
|
|
|
property free_func:
|
|
"""Get the name of the function used to free this type.
|
|
|
|
:return: the free func name.
|
|
|
|
For pointer types, this returns name of the func used to free the pointer.
|
|
For struct and alias types, this returns name of the func used to free a
|
|
pointer to that type. For other types, this returns NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_free_func_get(self.tp))
|
|
|
|
|
|
cdef class TypeStructField:
|
|
|
|
cdef const Eolian_Struct_Type_Field *fl
|
|
|
|
cdef _set_obj(self, const Eolian_Struct_Type_Field *obj):
|
|
self.fl = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
property name:
|
|
"""Get the name of a field of a struct type.
|
|
|
|
:return: the name.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_struct_field_name_get(self.fl))
|
|
|
|
property description:
|
|
"""Get the description of a field of a struct type.
|
|
|
|
:return: the description when ``tp`` is EOLIAN_TYPE_STRUCT, ``field`` is not None
|
|
and the field exists, None otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_struct_field_description_get(self.fl))
|
|
|
|
property type:
|
|
"""Get the type of a field of a struct type.
|
|
|
|
:return: the type.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_type_to_python_obj(eolian_type_struct_field_type_get(self.fl))
|
|
|
|
|
|
cdef class TypeEnumField:
|
|
|
|
cdef const Eolian_Enum_Type_Field *fl
|
|
|
|
cdef _set_obj(self, const Eolian_Enum_Type_Field *obj):
|
|
self.fl = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
property name:
|
|
"""Get the name of a field of an enum type.
|
|
|
|
:return: the name.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_enum_field_name_get(self.fl))
|
|
|
|
property description:
|
|
"""Get the description of a field of an enum type.
|
|
|
|
:return: the description.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_type_enum_field_description_get(self.fl))
|
|
|
|
property value:
|
|
"""Get the value of a field of an enum type.
|
|
|
|
:return: the description.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_expression_to_python_obj(eolian_type_enum_field_value_get(self.fl))
|
|
|
|
|
|
cdef class Expression(object):
|
|
|
|
cdef const Eolian_Expression *expr
|
|
|
|
cdef _set_obj(self, const Eolian_Expression *obj):
|
|
self.expr = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def eval(self, Eolian_Expression_Mask mask):
|
|
"""Evaluate an Eolian expression.
|
|
|
|
@param[in] mask the mask of allowed values (can combine with bitwise OR).
|
|
:return: the value, its type is set to EOLIAN_EXPR_UNKNOWN on error.
|
|
|
|
Represents value types from Eolian_Expression_Type. Booleans
|
|
are represented as unsigned char, strings as a stringshare.
|
|
|
|
"""
|
|
return eolian_value_to_python_obj(eolian_expression_eval(self.expr, mask))
|
|
|
|
def eval_type(self, Type tp):
|
|
"""Evaluate an Eolian expression given a type instead of a mask.
|
|
|
|
@param[in] type the type the expression is assigned to.
|
|
:return: the value, its type is set to EOLIAN_EXPR_UNKNOWN on error.
|
|
|
|
The mask is automatically decided from the given type, allowing only values
|
|
that can be assigned to that type.
|
|
|
|
"""
|
|
return eolian_value_to_python_obj(eolian_expression_eval_type(self.expr, tp.tp))
|
|
|
|
def serialize(self):
|
|
"""Serialize an expression.
|
|
|
|
:return: the serialized expression or NULL.
|
|
|
|
This serializes the expression into the original form as written in the .eo
|
|
file (but with parens on binary operators explicitly specifying precedence).
|
|
Keep in mind that it cannot be used alone pasted into C code as it doesn't
|
|
resolve namespaces and enum field names.
|
|
|
|
"""
|
|
cdef Eina_Stringshare *ret1
|
|
ret1 = eolian_expression_serialize(self.expr)
|
|
ret2 = _ctouni(ret1)
|
|
eina_stringshare_del(ret1)
|
|
return ret2
|
|
|
|
property type:
|
|
"""Get the type of an expression.
|
|
|
|
:return: the expression type.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return ExpressionType(eolian_expression_type_get(self.expr))
|
|
|
|
property binary_operator:
|
|
"""Get the binary operator of an expression.
|
|
|
|
:return: the binary operator, EOLIAN_BINOP_INVALID on failure.
|
|
|
|
This only works on binary expressions, otherwise it returns
|
|
EOLIAN_BINOP_INVALID.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return BinaryOperator(eolian_expression_binary_operator_get(self.expr))
|
|
|
|
property binary_lhs:
|
|
"""Get the lhs (left hand side) of a binary expression.
|
|
|
|
:return: the expression or NULL.
|
|
|
|
This only works on binary expressions, otherwise it returns NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_expression_to_python_obj(eolian_expression_binary_lhs_get(self.expr))
|
|
|
|
property binary_rhs:
|
|
"""Get the rhs (right hand side) of a binary expression.
|
|
|
|
:return: the expression or NULL.
|
|
|
|
This only works on binary expressions, otherwise it returns NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_expression_to_python_obj(eolian_expression_binary_rhs_get(self.expr))
|
|
|
|
property unary_operator:
|
|
"""Get the unary operator of an expression.
|
|
|
|
:return: the unary operator, EOLIAN_UNOP_INVALID on failure.
|
|
|
|
This only works on unary expressions, otherwise it returns
|
|
EOLIAN_UNOP_INVALID.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return UnaryOperator(eolian_expression_unary_operator_get(self.expr))
|
|
|
|
property unary_expression:
|
|
"""Get the expression of an unary expression.
|
|
|
|
:return: the expression or NULL.
|
|
|
|
This only works on unary expressions, otherwise it returns NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_expression_to_python_obj(eolian_expression_unary_expression_get(self.expr))
|
|
|
|
property value:
|
|
"""Get the value of an expression.
|
|
|
|
:return: the value.
|
|
|
|
Keep in mind that this doesn't evaluate anything. That's why it only works
|
|
on expressions that actually hold values (not unknown, not binary, not
|
|
unary). For some types of expressions (enum, name), this stores the actual
|
|
name (in the value.s field). Resources for this are held by the database.
|
|
Don't attempt to free the string or anything like that.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_value_to_python_obj(eolian_expression_value_get(self.expr))
|
|
|
|
|
|
cdef class Value(object):
|
|
|
|
cdef Eolian_Value v
|
|
|
|
cdef _set_obj(self, Eolian_Value obj):
|
|
self.expr = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def value_to_literal(self):
|
|
"""Convert the result of expression evaluation to a literal as in how
|
|
it would appear in C (e.g. strings are quoted and escaped).
|
|
|
|
@param[in] v the value.
|
|
@param[in] etp the eolian type of the value.
|
|
:return: a stringshare containing the literal (quoted and escaped as needed)
|
|
or NULL.
|
|
|
|
For e.g. strings this only uses a subset of regular C escape sequences
|
|
so that interoperability is wider than just C (no octal escapes). For
|
|
languages that differ too much, you can write an equivalent function
|
|
yourself.
|
|
|
|
"""
|
|
cdef Eina_Stringshare *ret1
|
|
ret1 = eolian_expression_value_to_literal(<const Eolian_Value *>&self.v)
|
|
ret2 = _ctouni(ret1)
|
|
eina_stringshare_del(ret1)
|
|
return ret2
|
|
|
|
|
|
cdef class Variable(object):
|
|
|
|
cdef const Eolian_Variable *var
|
|
|
|
cdef _set_obj(self, const Eolian_Variable *obj):
|
|
self.var = obj
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
property type:
|
|
"""Get the type of a variable (global, constant)
|
|
|
|
:return: an Eolian_Type_Type.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return VariableType(eolian_variable_type_get(self.var))
|
|
|
|
property description:
|
|
"""Get the description of a variable.
|
|
|
|
:return: the description or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_variable_description_get(self.var))
|
|
|
|
property filename:
|
|
"""Get the filename of a variable.
|
|
|
|
:return: the filename or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_variable_file_get(self.var))
|
|
|
|
property base_type:
|
|
"""Get the base type of a variable.
|
|
|
|
:return: the base type or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_type_to_python_obj(eolian_variable_base_type_get(self.var))
|
|
|
|
property value:
|
|
"""Get the value of a variable.
|
|
|
|
:return: the value or NULL.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return eolian_expression_to_python_obj(eolian_variable_value_get(self.var))
|
|
|
|
property name:
|
|
"""Get the name of the given variable (without namespaces).
|
|
|
|
:return: the name.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_variable_name_get(self.var))
|
|
|
|
property full_name:
|
|
"""Get the name of the given variable (with namespaces).
|
|
|
|
:return: the name.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(eolian_variable_full_name_get(self.var))
|
|
|
|
property namespaces:
|
|
"""Get an iterator to the list of namespaces of the given variable.
|
|
|
|
:return: the iterator.
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef EinaIterator ret = EinaIterator(Type)
|
|
ret._set_obj(eolian_variable_namespaces_get(self.var))
|
|
return ret
|
|
|
|
property is_extern:
|
|
"""Check if a variable is extern.
|
|
|
|
:return: True if it's extern, False otherwise.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(eolian_variable_is_extern(self.var))
|