mirror of
https://github.com/cemu-project/idapython.git
synced 2024-11-28 12:04:19 +01:00
156 lines
3.8 KiB
C++
156 lines
3.8 KiB
C++
#ifndef __PY_EXPR__
|
|
#define __PY_EXPR__
|
|
|
|
//<code(py_expr)>
|
|
struct py_idcfunc_ctx_t
|
|
{
|
|
PyObject *py_func;
|
|
qstring name;
|
|
int nargs;
|
|
py_idcfunc_ctx_t(PyObject *py_func, const char *name, int nargs): py_func(py_func), name(name), nargs(nargs)
|
|
{
|
|
Py_INCREF(py_func);
|
|
}
|
|
~py_idcfunc_ctx_t()
|
|
{
|
|
Py_DECREF(py_func);
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
static error_t py_call_idc_func(
|
|
void *_ctx,
|
|
idc_value_t *argv,
|
|
idc_value_t *r)
|
|
{
|
|
// Convert IDC arguments to Python list
|
|
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)_ctx;
|
|
int cvt;
|
|
ppyobject_vec_t pargs;
|
|
char errbuf[MAXSTR];
|
|
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, NULL, errbuf, sizeof(errbuf)) )
|
|
{
|
|
// Error during conversion? Create an IDC exception
|
|
return PyW_CreateIdcException(r, errbuf);
|
|
}
|
|
|
|
// Call the Python function
|
|
PYW_GIL_ENSURE;
|
|
PyObject *py_result = PyObject_CallObject(
|
|
ctx->py_func,
|
|
pargs.empty() ? NULL : pargs[0]);
|
|
|
|
error_t err;
|
|
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
|
|
{
|
|
err = PyW_CreateIdcException(r, errbuf);
|
|
Py_XDECREF(py_result);
|
|
}
|
|
else
|
|
{
|
|
// Convert the result to IDC
|
|
r->clear();
|
|
cvt = pyvar_to_idcvar(py_result, r);
|
|
if ( cvt < CIP_OK )
|
|
err = PyW_CreateIdcException(r, "ERROR: bad return value");
|
|
else
|
|
err = eOk;
|
|
if ( cvt != CIP_OK_NODECREF )
|
|
Py_XDECREF(py_result);
|
|
}
|
|
PYW_GIL_RELEASE;
|
|
|
|
// Free the converted args
|
|
pyw_free_idc_args(pargs);
|
|
|
|
return err;
|
|
}
|
|
|
|
//</code(py_expr)>
|
|
|
|
//<inline(py_expr)>
|
|
|
|
//---------------------------------------------------------------------------
|
|
static size_t py_get_call_idc_func()
|
|
{
|
|
return (size_t)py_call_idc_func;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Internal function:
|
|
// - capture the python callable
|
|
// - return a C context as a numeric value
|
|
static size_t pyw_register_idc_func(
|
|
const char *name,
|
|
const char *args,
|
|
PyObject *py_fp)
|
|
{
|
|
return (size_t)new py_idcfunc_ctx_t(py_fp, name, strlen(args));
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Internal function:
|
|
// - free the C context
|
|
static bool pyw_unregister_idc_func(size_t ctxptr)
|
|
{
|
|
// Unregister the function
|
|
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)ctxptr;
|
|
bool ok = set_idc_func_ex(ctx->name.c_str(), NULL, NULL, 0);
|
|
|
|
// Delete the context
|
|
delete ctx;
|
|
|
|
return ok;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
static bool py_set_idc_func_ex(
|
|
const char *name,
|
|
size_t fp_ptr,
|
|
const char *args,
|
|
int flags)
|
|
{
|
|
return set_idc_func_ex(name, (idc_func_t *)fp_ptr, args, flags);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Compile* functions return false when error so the return
|
|
// value must be negated for the error string to be returned
|
|
bool CompileEx_wrap(
|
|
const char *file,
|
|
bool del_macros,
|
|
char *errbuf, size_t errbufsize)
|
|
{
|
|
return !CompileEx(file, del_macros, errbuf, errbufsize);
|
|
}
|
|
|
|
bool Compile_wrap(const char *file, char *errbuf, size_t errbufsize)
|
|
{
|
|
return !Compile(file, errbuf, errbufsize);
|
|
}
|
|
|
|
bool calcexpr_wrap(
|
|
ea_t where,
|
|
const char *line,
|
|
idc_value_t *rv,
|
|
char *errbuf, size_t errbufsize)
|
|
{
|
|
return !calcexpr(where, line, rv, errbuf, errbufsize);
|
|
}
|
|
|
|
bool calc_idc_expr_wrap(
|
|
ea_t where,
|
|
const char *line,
|
|
idc_value_t *rv,
|
|
char *errbuf, size_t errbufsize)
|
|
{
|
|
return !calc_idc_expr(where, line, rv, errbuf, errbufsize);
|
|
}
|
|
|
|
bool CompileLine_wrap(const char *line, char *errbuf, size_t errbufsize)
|
|
{
|
|
return !CompileLineEx(line, errbuf, errbufsize);
|
|
}
|
|
|
|
//</inline(py_expr)>
|
|
#endif |