diff --git a/pywraps.hpp b/pywraps.hpp new file mode 100644 index 0000000..1bb5b43 --- /dev/null +++ b/pywraps.hpp @@ -0,0 +1,82 @@ +#ifndef __PYWRAPS_HPP__ +#define __PYWRAPS_HPP__ + +//------------------------------------------------------------------------ +// Types +#ifndef PYUL_DEFINED + #define PYUL_DEFINED + #ifdef __EA64__ + typedef unsigned PY_LONG_LONG pyul_t; + #else + typedef unsigned long pyul_t; + #endif +#endif + +#ifdef __EA64__ + #define PY_FMT64 "K" +#else + #define PY_FMT64 "k" +#endif + +// Vector of PyObject* +typedef qvector ppyobject_vec_t; + +//------------------------------------------------------------------------ +// PyIdc conversion object IDs +#define PY_ICID_INT64 0 +#define PY_ICID_BYREF 1 +#define PY_ICID_OPAQUE 2 + +//------------------------------------------------------------------------ +// Constants used by the pyvar_to_idcvar and idcvar_to_pyvar functions +#define CIP_FAILED -1 // Conversion error +#define CIP_IMMUTABLE 0 // Immutable object passed. Will not update the object but no error occured +#define CIP_OK 1 // Success +#define CIP_OK_NODECREF 2 // Success but do not decrement its reference + +//------------------------------------------------------------------------ +// All the exported functions from PyWraps are forward declared here + +// Tries to import a module and swallows the exception if it fails and returns NULL +PyObject *PyImport_TryImportModule(const char *name); + +// Tries to get an attribute and swallows the exception if it fails and returns NULL +PyObject *PyObject_TryGetAttrString(PyObject *py_var, const char *attr); + +// Converts a Python number (LONGLONG or normal integer) to an IDC variable (VT_LONG or VT_INT64) +bool PyGetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var); + +// Converts a Python number to an uint64 and indicates whether the number was a long number +bool PyGetNumber(PyObject *py_var, uint64 *num, bool *is_64 = NULL); + +// Checks if an Python object can be treated like a sequence +bool PyIsSequenceType(PyObject *obj); + +// Returns an error string from the last exception (and clears it) +bool PyGetError(qstring *out = NULL); + +// If an error occured (it calls PyGetError) it displays it and return TRUE +bool PyShowErr(const char *cb_name); + +// [De]Initializes PyWraps +bool init_pywraps(); +void deinit_pywraps(); + +// Returns the string representation of a PyObject +bool PyObjectToString(PyObject *obj, qstring *out); + +// Converts Python variable to IDC variable +// gvar_sn is used in case the Python object was a created from a call to idcvar_to_pyvar and the IDC object was a VT_REF +int pyvar_to_idcvar( + PyObject *py_var, + idc_value_t *idc_var, + int *gvar_sn = NULL); + +// Converts from IDC to Python +// We support converting VT_REF IDC variable types +int idcvar_to_pyvar( + const idc_value_t &idc_var, + PyObject **py_var); + + +#endif \ No newline at end of file diff --git a/swig/idaapi.i b/swig/idaapi.i index f04f734..08aed34 100644 --- a/swig/idaapi.i +++ b/swig/idaapi.i @@ -55,45 +55,82 @@ // -#ifndef PYUL_DEFINED -#define PYUL_DEFINED - typedef unsigned PY_LONG_LONG pyul_t; +#include "pywraps.hpp" + +//------------------------------------------------------------------------ +// String constants used +static const char PY_IDC_CLASS_NAME[] = "py_idc_object_class"; +static const char PY_IDC_GLOBAL_VAR_FMT[] = "__py_cvt_gvar_%d"; +static const char PY_IDCCVT_ID_ATTR[] = "__idc_cvt_id__"; +static const char PY_IDCCVT_VALUE_ATTR[] = "__idc_cvt_value__"; +static const char S_PY_IDC_OPAQUE_T[] = "py_idc_cvt_helper_t"; +static const char S_PROPS[] = "props"; +static const char S_NAME[] = "name"; +static const char S_ASM_KEYWORD[] = "asm_keyword"; +static const char S_MENU_NAME[] = "menu_name"; +static const char S_HOTKEY[] = "hotkey"; +static const char S_VALUE_SIZE[] = "value_size"; +static const char S_MAY_CREATE_AT[] = "may_create_at"; +static const char S_CALC_ITEM_SIZE[] = "calc_item_size"; +static const char S_ID[] = "id"; +static const char S_PRINTF[] = "printf"; +static const char S_TEXT_WIDTH[] = "text_width"; +static const char S_SCAN[] = "scan"; +static const char S_ANALYZE[] = "analyze"; +static const char S_CBSIZE[] = "cbsize"; +static const char S_ON_CLICK[] = "OnClick"; +static const char S_ON_CLOSE[] = "OnClose"; +static const char S_ON_DBL_CLICK[] = "OnDblClick"; +static const char S_ON_CURSOR_POS_CHANGED[] = "OnCursorPosChanged"; +static const char S_ON_KEYDOWN[] = "OnKeydown"; +static const char S_ON_POPUP[] = "OnPopup"; +static const char S_ON_HINT[] = "OnHint"; +static const char S_ON_POPUP_MENU[] = "OnPopupMenu"; +static const char S_ON_EDIT_LINE[] = "OnEditLine"; +static const char S_ON_INSERT_LINE[] = "OnInsertLine"; +static const char S_ON_GET_LINE[] = "OnGetLine"; +static const char S_ON_DELETE_LINE[] = "OnDeleteLine"; +static const char S_ON_REFRESH[] = "OnRefresh"; +static const char S_ON_SELECT_LINE[] = "OnSelectLine"; +static const char S_ON_COMMAND[] = "OnCommand"; +static const char S_ON_GET_ICON[] = "OnGetIcon"; +static const char S_ON_GET_LINE_ATTR[] = "OnGetLineAttr"; +static const char S_ON_GET_SIZE[] = "OnGetSize"; +static const char S_ON_GETTEXT[] = "OnGetText"; +static const char S_ON_ACTIVATE[] = "OnActivate"; +static const char S_ON_DEACTIVATE[] = "OnDeactivate"; +static const char S_ON_SELECT[] = "OnSelect"; +static const char S_M_EDGES[] = "_edges"; +static const char S_M_NODES[] = "_nodes"; +static const char S_M_THIS[] = "_this"; +static const char S_M_TITLE[] = "_title"; + +#ifdef __PYWRAPS__ +static const char S_PY_IDAAPI_MODNAME[] = "__main__"; +#else +static const char S_PY_IDAAPI_MODNAME[] = "idaapi"; #endif //------------------------------------------------------------------------ -static const char PY_IDC_CLASS_NAME[] = "py_idc_object_class"; -static const char PY_IDC_GLOBAL_VAR_FMT[] = "__py_cvt_gvar_%d"; -static const char PY_IDCCVT_ID_ATTR[] = "__idc_cvt_id__"; -static const char PY_IDCCVT_VALUE_ATTR[] = "__idc_cvt_value__"; -static const char S_PY_IDC_OPAQUE_T[] = "py_idc_cvt_helper_t"; - -#ifndef __PYWRAPS__ -static const char S_PY_IDAAPI_MODNAME[] = "idaapi"; -#else -static const char S_PY_IDAAPI_MODNAME[] = "__main__"; -#endif - +// Constants used by get_idaapi_class_reference() #define PY_CLSID_CVT_INT64 0 #define PY_CLSID_APPCALL_SKEL_OBJ 1 #define PY_CLSID_CVT_BYREF 2 #define PY_CLSID_LAST 3 //------------------------------------------------------------------------ -// PyIdc conversion object ids -#define PY_ICID_INT64 0 -#define PY_ICID_BYREF 1 -#define PY_ICID_OPAQUE 2 - static PyObject *py_cvt_helper_module = NULL; static bool pywraps_initialized = false; //------------------------------------------------------------------------ -idc_class_t *get_py_idc_cvt_opaque() +static idc_class_t *get_py_idc_cvt_opaque() { return find_idc_class(S_PY_IDC_OPAQUE_T); } //------------------------------------------------------------------------ +// IDC Opaque object destructor: when the IDC object dies we kill the +// opaque Python object along with it static const char py_idc_cvt_helper_dtor_args[] = { VT_OBJ, 0 }; static error_t idaapi py_idc_opaque_dtor( idc_value_t *argv, @@ -122,7 +159,7 @@ bool init_pywraps() if (py_cvt_helper_module == NULL) { // Take a reference to the module so we can create the needed class instances - py_cvt_helper_module = PyImport_ImportModule(S_PY_IDAAPI_MODNAME); + py_cvt_helper_module = PyImport_TryImportModule(S_PY_IDAAPI_MODNAME); if (py_cvt_helper_module == NULL) return false; } @@ -175,7 +212,6 @@ static PyObject *get_idaapi_class_reference(const int class_id) "Appcall_object__", "PyIdc_cvt_refclass__" }; - return PyObject_GetAttrString(py_cvt_helper_module, class_names[class_id]); } @@ -209,7 +245,7 @@ PyObject *PyImport_TryImportModule(const char *name) // converted to a VT_INT64 or not. For example: 2**32-1 = 0xffffffff which // can fit in a C long but Python creates a PyLong object for it. // And because of that we are confused as to whether to convert to 32 or 64 -bool PyGetNumber(PyObject *py_var, idc_value_t *idc_var) +bool PyGetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var) { if (!(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var))) return false; @@ -235,6 +271,49 @@ bool PyGetNumber(PyObject *py_var, idc_value_t *idc_var) return true; } +//------------------------------------------------------------------------- +// Parses a Python object as a long or long long +bool PyGetNumber(PyObject *py_var, uint64 *num, bool *is_64) +{ + if (!(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var))) + return false; + + // Can we convert to C long? + long l = PyInt_AsLong(py_var); + if (!PyErr_Occurred()) + { + if (num != NULL) + *num = uint64(l); + if (is_64 != NULL) + *is_64 = false; + return true; + } + // Clear last error + PyErr_Clear(); + // Can be fit into a C unsigned long? + unsigned long ul = PyLong_AsUnsignedLong(py_var); + if (!PyErr_Occurred()) + { + if (num != NULL) + *num = uint64(ul); + if (is_64 != NULL) + *is_64 = false; + return true; + } + PyErr_Clear(); + PY_LONG_LONG ll = PyLong_AsLongLong(py_var); + if (!PyErr_Occurred()) + { + if (num != NULL) + *num = uint64(ll); + if (is_64 != NULL) + *is_64 = true; + return true; + } + PyErr_Clear(); + return false; +} + //------------------------------------------------------------------------- // Checks if a given object is of sequence type bool PyIsSequenceType(PyObject *obj) @@ -271,10 +350,10 @@ bool PyObjectToString(PyObject *obj, qstring *out) //-------------------------------------------------------------------------- // Checks if a Python error occured and fills the out parameter with the // exception string -bool PyGetError(qstring *out = NULL) +bool PyGetError(qstring *out) { PyObject *py_err; - if ( (py_err = PyErr_Occurred()) == NULL) + if ((py_err = PyErr_Occurred()) == NULL) return false; PyObject *err_type, *err_value, *err_traceback; @@ -284,6 +363,17 @@ bool PyGetError(qstring *out = NULL) return true; } +//------------------------------------------------------------------------- +// A loud version of PyGetError() which gets the error and displays it +bool PyShowErr(const char *cb_name) +{ + static qstring err_str; + if (!PyGetError(&err_str)) + return false; + warning("IDAPython: Error while calling Python callback <%s>:\n%s", cb_name, err_str.c_str()); + return true; +} + //------------------------------------------------------------------------- // Checks if the given py_var is a special PyIdc_cvt_helper object. // It does that by examining the magic attribute and returns its numeric value. @@ -328,22 +418,19 @@ static bool create_py_idc_opaque_obj(PyObject *py_var, idc_value_t *idc_var) //------------------------------------------------------------------------- // Converts a Python variable into an IDC variable -// This function returns: -// 0 - failure -// 1 - success -// 2 - success but do not decrement the reference of the py_var (used by opaque values) +// This function returns on one CIP_XXXX int pyvar_to_idcvar( PyObject *py_var, idc_value_t *idc_var, - int *gvar_sn = NULL) + int *gvar_sn) { PyObject *attr; // None / NULL if (py_var == NULL || py_var == Py_None) idc_var->set_long(0); // Numbers? - else if (PyGetNumber(py_var, idc_var)) - return 1; + else if (PyGetNumberAsIDC(py_var, idc_var)) + return CIP_OK; // String else if (PyString_Check(py_var)) idc_var->_set_string(PyString_AsString(py_var), PyString_Size(py_var)); @@ -360,6 +447,7 @@ int pyvar_to_idcvar( // void* else if (PyCObject_Check(py_var)) idc_var->set_pvoid(PyCObject_AsVoidPtr(py_var)); + // Is it a Python list? else if (PyList_CheckExact(py_var) || PyIsSequenceType(py_var)) { // Create the object @@ -379,7 +467,7 @@ int pyvar_to_idcvar( // Convert the item into an IDC variable idc_value_t v; - ok = pyvar_to_idcvar(py_item, &v, gvar_sn) > 0; + ok = pyvar_to_idcvar(py_item, &v, gvar_sn) >= CIP_OK; if (ok) { // Form the attribute name @@ -397,7 +485,7 @@ int pyvar_to_idcvar( if (!ok) break; } - return ok ? 1 : 0; + return ok ? CIP_OK : CIP_FAILED; } // Dictionary: we convert to an IDC object else if (PyDict_Check(py_var)) @@ -426,7 +514,7 @@ int pyvar_to_idcvar( // Convert the attribute into an IDC value idc_value_t v; - ok = pyvar_to_idcvar(val, &v, gvar_sn) > 0; + ok = pyvar_to_idcvar(val, &v, gvar_sn) >= CIP_OK; if (ok) { // Store the attribute @@ -439,7 +527,15 @@ int pyvar_to_idcvar( } // Decrement attribute reference Py_DECREF(py_items); - return ok ? 1 : 0; + return ok ? CIP_OK : CIP_FAILED; + } + // Possible function? + else if (PyCallable_Check(py_var)) + { + idc_var->clear(); + idc_var->vtype = VT_FUNC; + idc_var->funcidx = -1; // Does not apply + return CIP_OK; } // Objects: // - pyidc_cvt objects: int64, byref, opaque @@ -460,7 +556,7 @@ int pyvar_to_idcvar( return false; idc_var->set_int64(PyLong_AsLongLong(attr)); Py_DECREF(attr); - return 1; + return CIP_OK; // // BYREF // @@ -468,19 +564,19 @@ int pyvar_to_idcvar( { // BYREF always require this parameter if (gvar_sn == NULL) - return 0; + return CIP_FAILED; // Get the value attribute attr = PyObject_TryGetAttrString(py_var, PY_IDCCVT_VALUE_ATTR); if (attr == NULL) - return 0; + return CIP_FAILED; // Create a global variable char buf[MAXSTR]; qsnprintf(buf, sizeof(buf), PY_IDC_GLOBAL_VAR_FMT, *gvar_sn); idc_value_t *gvar = add_idc_gvar(buf); // Convert the python value into the IDC global variable - bool ok = pyvar_to_idcvar(attr, gvar, gvar_sn) > 0; + bool ok = pyvar_to_idcvar(attr, gvar, gvar_sn) >= CIP_OK; if (ok) { (*gvar_sn)++; @@ -488,7 +584,7 @@ int pyvar_to_idcvar( VarRef(idc_var, gvar); } Py_DECREF(attr); - return ok ? 1 : 0; + return ok ? CIP_OK : CIP_FAILED; } // // OPAQUE @@ -496,8 +592,8 @@ int pyvar_to_idcvar( case PY_ICID_OPAQUE: { if (!create_py_idc_opaque_obj(py_var, idc_var)) - return 0; - return 2; // do not decrement the reference + return CIP_FAILED; + return CIP_OK_NODECREF; } // // Other objects @@ -509,7 +605,7 @@ int pyvar_to_idcvar( if (py_dir == NULL || !PyList_Check(py_dir) || size == 0) { Py_XDECREF(py_dir); - return 0; + return CIP_FAILED; } // Create the IDC object VarObject(idc_var); @@ -532,10 +628,10 @@ int pyvar_to_idcvar( attr = PyObject_GetAttrString(py_var, field_name); if (attr == NULL // Convert the attribute into an IDC value - || pyvar_to_idcvar(attr, &v, gvar_sn) <= 0) + || pyvar_to_idcvar(attr, &v, gvar_sn) < CIP_OK) { Py_XDECREF(attr); - return 0; + return CIP_FAILED; } // Store the attribute VarSetAttr(idc_var, field_name, &v); @@ -544,18 +640,14 @@ int pyvar_to_idcvar( } } } - return 1; + return CIP_OK; } //------------------------------------------------------------------------- // Converts an IDC variable to a Python variable // If py_var points to an existing object then the object will be updated // If py_var points to an existing immutable object then ZERO is returned -// Return codes: -#define CIP_FAILED -1 // Conversion error -#define CIP_IMMUTABLE 0 // Immutable object passed. Will not update the object but no error occured -#define CIP_OK 1 // Success -#define CIP_OK_NODECREF 2 // Success but do not decrement its reference +// Returns one of CIP_xxxx. Check pywraps.hpp int idcvar_to_pyvar( const idc_value_t &idc_var, PyObject **py_var) @@ -588,9 +680,11 @@ int idcvar_to_pyvar( Py_DECREF(py_cls); break; } +#if !defined(NO_OBSOLETE_FUNCS) || defined(__EXPR_SRC) case VT_STR: *py_var = PyString_FromString(idc_var.str); break; +#endif case VT_STR2: if (*py_var == NULL) { @@ -736,7 +830,7 @@ int idcvar_to_pyvar( %} // Do not create separate wrappers for default arguments -%feature("compactdefaultargs"); +%feature("compactdefaultargs"); #ifdef __EA64__ #ifdef __GNUC__ @@ -783,7 +877,7 @@ typedef int error_t; %binary_output_or_none(void *buf, size_t bufsize); %binary_output_with_size(void *buf, size_t *bufsize); -// Accept single Python string for const void * + size input arguments +// Accept single Python string for const void * + size input arguments // For example: put_many_bytes() and patch_many_bytes() %apply (char *STRING, int LENGTH) { (const void *buf, size_t size) }; %apply (char *STRING, int LENGTH) { (const void *buf, size_t len) }; @@ -858,7 +952,7 @@ idainfo *get_inf_structure(void) %pythoncode %{ # - +import struct # ----------------------------------------------------------------------- # Seek constants SEEK_SET = 0 # from the file start @@ -971,6 +1065,52 @@ def as_uint32(v): def as_int32(v): return -((~v & 0xffffffff)+1) +# ----------------------------------------------------------------------- +def as_signed(v, nbits = 32): + return -(( ~v & ((1 << nbits)-1) ) + 1) if v & (1 << nbits-1) else v + +# ---------------------------------------------------------------------- +# Copy bits from a value +def copy_bits(b, s, e=-1): + # end-bit not specified? use start bit (thus extract one bit) + if e == -1: + e = s + # swap start and end if start > end + if s > e: + e, s = s, e + + mask = 0 + for i in xrange(s, e+1): + mask |= 1 << i + + return (b & mask) >> s + +# ---------------------------------------------------------------------- +struct_unpack_table = { + 1: ('b', 'B'), + 2: ('h', 'H'), + 4: ('l', 'L'), + 8: ('q', 'Q') +} + +# ---------------------------------------------------------------------- +def struct_unpack(value, signed = False, offs = 0): + """ + Unpack a value given its length and offset using struct.unpack_from(). + This function will know how to unpack the given value by using the lookup table 'struct_unpack_table' + """ + # Supported length? + n = len(value) + if not n in struct_unpack_table: + return None + # Conver to number + signed = 1 if signed else 0 + + # Unpack + return struct.unpack_from(struct_unpack_table[n][signed], value, offs)[0] + + + # %} \ No newline at end of file diff --git a/swig/kernwin.i b/swig/kernwin.i index 2a7d94a..5e47153 100644 --- a/swig/kernwin.i +++ b/swig/kernwin.i @@ -163,29 +163,6 @@ uint32 choose_choose(PyObject *self, #define thisobj ((py_choose2_t *) obj) #define thisdecl py_choose2_t *_this = thisobj #define MENU_COMMAND_CB(id) static uint32 idaapi s_menu_command_##id(void *obj, uint32 n) { return thisobj->on_command(id, int(n)); } -#define DECL_MENU_COMMAND_CB(id) s_menu_command_##id -#define S_ON_EDIT_LINE "OnEditLine" -#define S_ON_INSERT_LINE "OnInsertLine" -#define S_ON_GET_LINE "OnGetLine" -#define S_ON_DELETE_LINE "OnDeleteLine" -#define S_ON_REFRESH "OnRefresh" -#define S_ON_SELECT_LINE "OnSelectLine" -#define S_ON_COMMAND "OnCommand" -#define S_ON_GET_ICON "OnGetIcon" -#ifdef CH_ATTRS - #define S_ON_GET_LINE_ATTR "OnGetLineAttr" -#endif -#define S_ON_GET_SIZE "OnGetSize" -#define S_ON_CLOSE "OnClose" -#define CHOOSE2_HAVE_DEL 0x0001 -#define CHOOSE2_HAVE_INS 0x0002 -#define CHOOSE2_HAVE_UPDATE 0x0004 -#define CHOOSE2_HAVE_EDIT 0x0008 -#define CHOOSE2_HAVE_ENTER 0x0010 -#define CHOOSE2_HAVE_GETICON 0x0020 -#define CHOOSE2_HAVE_GETATTR 0x0040 -#define CHOOSE2_HAVE_COMMAND 0x0080 -#define CHOOSE2_HAVE_ONCLOSE 0x0100 //------------------------------------------------------------------------ // Helper functions @@ -217,6 +194,18 @@ void choose2_del_instance(PyObject *self) class py_choose2_t { private: + enum + { + CHOOSE2_HAVE_DEL = 0x0001, + CHOOSE2_HAVE_INS = 0x0002, + CHOOSE2_HAVE_UPDATE = 0x0004, + CHOOSE2_HAVE_EDIT = 0x0008, + CHOOSE2_HAVE_ENTER = 0x0010, + CHOOSE2_HAVE_GETICON = 0x0020, + CHOOSE2_HAVE_GETATTR = 0x0040, + CHOOSE2_HAVE_COMMAND = 0x0080, + CHOOSE2_HAVE_ONCLOSE = 0x0100 + }; int flags; int cb_flags; qstring title; @@ -233,7 +222,6 @@ private: //------------------------------------------------------------------------ // Static methods to dispatch to member functions //------------------------------------------------------------------------ -#ifdef CH_ATTRS static int idaapi ui_cb(void *obj, int notification_code, va_list va) { if ( notification_code != ui_get_chooser_item_attrs ) @@ -244,7 +232,6 @@ private: thisobj->on_get_line_attr(n, attr); return 1; } -#endif static uint32 idaapi s_sizer(void *obj) { return (uint32)thisobj->on_get_size(); @@ -300,7 +287,7 @@ private: line_arr[i][0] = '\0'; // Call Python - PyObject *list = PyObject_CallMethod(self, S_ON_GET_LINE, "l", lineno - 1); + PyObject *list = PyObject_CallMethod(self, (char *)S_ON_GET_LINE, "i", lineno - 1); if (list == NULL) return; for (int i=ncols-1;i>=0;i--) @@ -317,7 +304,7 @@ private: size_t on_get_size() { - PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_SIZE, NULL); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_SIZE, NULL); if (pyres == NULL) return 0; size_t res = PyInt_AsLong(pyres); @@ -332,7 +319,7 @@ private: unhook_from_notification_point(HT_UI, ui_cb, this); #endif // Call Python - PyObject *pyres = PyObject_CallMethod(self, S_ON_CLOSE, NULL); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_CLOSE, NULL); Py_XDECREF(pyres); Py_XDECREF(self); @@ -346,7 +333,7 @@ private: int on_delete_line(int lineno) { - PyObject *pyres = PyObject_CallMethod(self, S_ON_DELETE_LINE, "l", lineno - 1); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_DELETE_LINE, "i", lineno - 1); if (pyres == NULL) return lineno; size_t res = PyInt_AsLong(pyres); @@ -356,7 +343,7 @@ private: int on_refresh(int lineno) { - PyObject *pyres = PyObject_CallMethod(self, S_ON_REFRESH, "l", lineno - 1); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_REFRESH, "i", lineno - 1); if (pyres == NULL) return lineno; size_t res = PyInt_AsLong(pyres); @@ -366,25 +353,25 @@ private: void on_insert_line() { - PyObject *pyres = PyObject_CallMethod(self, S_ON_INSERT_LINE, NULL); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_INSERT_LINE, NULL); Py_XDECREF(pyres); } void on_select_line(int lineno) { - PyObject *pyres = PyObject_CallMethod(self, S_ON_SELECT_LINE, "l", lineno - 1); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_SELECT_LINE, "i", lineno - 1); Py_XDECREF(pyres); } void on_edit_line(int lineno) { - PyObject *pyres = PyObject_CallMethod(self, S_ON_EDIT_LINE, "l", lineno - 1); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_EDIT_LINE, "i", lineno - 1); Py_XDECREF(pyres); } int on_command(int cmd_id, int lineno) { - PyObject *pyres = PyObject_CallMethod(self, S_ON_COMMAND, "ll", lineno - 1, cmd_id); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_COMMAND, "ii", lineno - 1, cmd_id); if (pyres==NULL) return lineno; size_t res = PyInt_AsLong(pyres); @@ -394,15 +381,14 @@ private: int on_get_icon(int lineno) { - PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_ICON, "l", lineno - 1); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_ICON, "i", lineno - 1); size_t res = PyInt_AsLong(pyres); Py_XDECREF(pyres); return res; } -#ifdef CH_ATTRS void on_get_line_attr(int lineno, chooser_item_attrs_t *attr) { - PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_LINE_ATTR, "l", lineno - 1); + PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_LINE_ATTR, "i", lineno - 1); if (pyres == NULL) return; @@ -416,7 +402,6 @@ private: } Py_XDECREF(pyres); } -#endif public: //------------------------------------------------------------------------ // Public methods @@ -428,12 +413,10 @@ public: menu_cb_idx = 0; self = NULL; } -#ifdef CH_ATTRS static py_choose2_t *find_chooser(const char *title) { return (py_choose2_t *) get_chooser_obj(title); } -#endif void close() { close_chooser(title.c_str()); @@ -459,13 +442,11 @@ public: int x1 = -1, int y1 = -1, int x2 = -1, int y2 = -1) { flags = fl; -#ifdef CH_ATTRS if ( (flags & CH_ATTRS) != 0 ) { if ( !hook_to_notification_point(HT_UI, ui_cb, this) ) flags &= ~CH_ATTRS; } -#endif this->title = title; return ::choose2( flags, @@ -595,9 +576,7 @@ public: {S_ON_REFRESH, CHOOSE2_HAVE_UPDATE}, {S_ON_SELECT_LINE, CHOOSE2_HAVE_ENTER}, {S_ON_COMMAND, CHOOSE2_HAVE_COMMAND}, -#ifdef CH_ATTRS {S_ON_GET_LINE_ATTR, CHOOSE2_HAVE_GETATTR}, -#endif {S_ON_GET_ICON, CHOOSE2_HAVE_GETICON} }; cb_flags = 0; @@ -631,11 +610,10 @@ public: } Py_XDECREF(attr); -#ifdef CH_ATTRS // Adjust flags (if needed) if ( (cb_flags & CHOOSE2_HAVE_GETATTR) != 0 ) flags |= CH_ATTRS; -#endif + // Increase object reference Py_INCREF(self); this->self = self; @@ -666,6 +644,7 @@ public: //------------------------------------------------------------------------ // Initialize the callback pointers +#define DECL_MENU_COMMAND_CB(id) s_menu_command_##id chooser_cb_t *py_choose2_t::menu_cbs[MAX_CHOOSER_MENU_COMMANDS] = { DECL_MENU_COMMAND_CB(0), DECL_MENU_COMMAND_CB(1), @@ -674,33 +653,13 @@ chooser_cb_t *py_choose2_t::menu_cbs[MAX_CHOOSER_MENU_COMMANDS] = DECL_MENU_COMMAND_CB(6), DECL_MENU_COMMAND_CB(7), DECL_MENU_COMMAND_CB(8), DECL_MENU_COMMAND_CB(9) }; +#undef DECL_MENU_COMMAND_CB #undef POPUP_NAMES_COUNT #undef MAX_CHOOSER_MENU_COMMANDS #undef thisobj #undef thisdecl #undef MENU_COMMAND_CB -#undef DECL_MENU_COMMAND_CB -#undef S_ON_EDIT_LINE -#undef S_ON_INSERT_LINE -#undef S_ON_GET_LINE -#undef S_ON_DELETE_LINE -#undef S_ON_REFRESH -#undef S_ON_SELECT_LINE -#undef S_ON_COMMAND -#undef S_ON_GET_ICON -#undef S_ON_GET_LINE_ATTR -#undef S_ON_GET_SIZE -#undef S_ON_CLOSE -#undef CHOOSE2_HAVE_DEL -#undef CHOOSE2_HAVE_INS -#undef CHOOSE2_HAVE_UPDATE -#undef CHOOSE2_HAVE_EDIT -#undef CHOOSE2_HAVE_ENTER -#undef CHOOSE2_HAVE_GETICON -#undef CHOOSE2_HAVE_GETATTR -#undef CHOOSE2_HAVE_COMMAND -#undef CHOOSE2_HAVE_ONCLOSE //------------------------------------------------------------------------ int choose2_show(PyObject *self)