//------------------------------------------------------------------------- Py_ssize_t pyvar_walk_list( PyObject *py_list, int (*cb)(PyObject *py_item, Py_ssize_t index, void *ud), void *ud) { if ( !PyList_CheckExact(py_list) && !PyW_IsSequenceType(py_list) ) return CIP_FAILED; bool is_seq = !PyList_CheckExact(py_list); Py_ssize_t size = is_seq ? PySequence_Size(py_list) : PyList_Size(py_list); if ( cb == NULL ) return size; Py_ssize_t i; for ( i=0; i<size; i++ ) { // Get the item PyObject *py_item = is_seq ? PySequence_GetItem(py_list, i) : PyList_GetItem(py_list, i); if ( py_item == NULL ) break; int r = cb(py_item, i, ud); // Decrement reference (if needed) if ( r != CIP_OK_NODECREF && is_seq ) Py_DECREF(py_item); // Only sequences require us to decrement the reference if ( r < CIP_OK ) break; } return i; }
//------------------------------------------------------------------------- Py_ssize_t pyvar_walk_list( const ref_t &py_list, int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud), void *ud) { PYW_GIL_CHECK_LOCKED_SCOPE(); Py_ssize_t size = CIP_FAILED; do { PyObject *o = py_list.o; if ( !PyList_CheckExact(o) && !PyW_IsSequenceType(o) ) break; bool is_seq = !PyList_CheckExact(o); size = is_seq ? PySequence_Size(o) : PyList_Size(o); if ( cb == NULL ) break; Py_ssize_t i; for ( i=0; i<size; i++ ) { // Get the item ref_t py_item; if ( is_seq ) py_item = newref_t(PySequence_GetItem(o, i)); else py_item = borref_t(PyList_GetItem(o, i)); if ( py_item == NULL || cb(py_item, i, ud) < CIP_OK ) break; } size = i; } while ( false ); return size; }
//------------------------------------------------------------------------- // Converts a Python variable into an IDC variable // This function returns on one CIP_XXXX int pyvar_to_idcvar( const ref_t &py_var, idc_value_t *idc_var, int *gvar_sn) { PYW_GIL_CHECK_LOCKED_SCOPE(); // None / NULL if ( py_var == NULL || py_var.o == Py_None ) { idc_var->set_long(0); } // Numbers? else if ( PyW_GetNumberAsIDC(py_var.o, idc_var) ) { return CIP_OK; } // String else if ( PyString_Check(py_var.o) ) { idc_var->_set_string(PyString_AsString(py_var.o), PyString_Size(py_var.o)); } // Boolean else if ( PyBool_Check(py_var.o) ) { idc_var->set_long(py_var.o == Py_True ? 1 : 0); } // Float else if ( PyFloat_Check(py_var.o) ) { double dresult = PyFloat_AsDouble(py_var.o); ieee_realcvt((void *)&dresult, idc_var->e, 3); idc_var->vtype = VT_FLOAT; } // void* else if ( PyCObject_Check(py_var.o) ) { idc_var->set_pvoid(PyCObject_AsVoidPtr(py_var.o)); } // Python list? else if ( PyList_CheckExact(py_var.o) || PyW_IsSequenceType(py_var.o) ) { // Create the object VarObject(idc_var); // Determine list size and type bool is_seq = !PyList_CheckExact(py_var.o); Py_ssize_t size = is_seq ? PySequence_Size(py_var.o) : PyList_Size(py_var.o); bool ok = true; qstring attr_name; // Convert each item for ( Py_ssize_t i=0; i<size; i++ ) { // Get the item ref_t py_item; if ( is_seq ) py_item = newref_t(PySequence_GetItem(py_var.o, i)); else py_item = borref_t(PyList_GetItem(py_var.o, i)); // Convert the item into an IDC variable idc_value_t v; ok = pyvar_to_idcvar(py_item, &v, gvar_sn) >= CIP_OK; if ( ok ) { // Form the attribute name newref_t py_int(PyInt_FromSsize_t(i)); ok = PyW_ObjectToString(py_int.o, &attr_name); if ( !ok ) break; // Store the attribute VarSetAttr(idc_var, attr_name.c_str(), &v); } if ( !ok ) break; } return ok ? CIP_OK : CIP_FAILED; } // Dictionary: we convert to an IDC object else if ( PyDict_Check(py_var.o) ) { // Create an empty IDC object VarObject(idc_var); // Get the dict.items() list newref_t py_items(PyDict_Items(py_var.o)); // Get the size of the list qstring key_name; bool ok = true; Py_ssize_t size = PySequence_Size(py_items.o); for ( Py_ssize_t i=0; i<size; i++ ) { // Get item[i] -> (key, value) PyObject *py_item = PyList_GetItem(py_items.o, i); // Extract key/value newref_t key(PySequence_GetItem(py_item, 0)); newref_t val(PySequence_GetItem(py_item, 1)); // Get key's string representation PyW_ObjectToString(key.o, &key_name); // Convert the attribute into an IDC value idc_value_t v; ok = pyvar_to_idcvar(val, &v, gvar_sn) >= CIP_OK; if ( ok ) { // Store the attribute VarSetAttr(idc_var, key_name.c_str(), &v); } if ( !ok ) break; } return ok ? CIP_OK : CIP_FAILED; } // Possible function? else if ( PyCallable_Check(py_var.o) ) { 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 // - other python objects else { // Get the type int cvt_id = get_pyidc_cvt_type(py_var.o); switch ( cvt_id ) { // // INT64 // case PY_ICID_INT64: { // Get the value attribute ref_t attr(PyW_TryGetAttrString(py_var.o, S_PY_IDCCVT_VALUE_ATTR)); if ( attr == NULL ) return false; idc_var->set_int64(PyLong_AsLongLong(attr.o)); return CIP_OK; } // // BYREF // case PY_ICID_BYREF: { // BYREF always require this parameter if ( gvar_sn == NULL ) return CIP_FAILED; // Get the value attribute ref_t attr(PyW_TryGetAttrString(py_var.o, S_PY_IDCCVT_VALUE_ATTR)); if ( attr == NULL ) return CIP_FAILED; // Create a global variable char buf[MAXSTR]; qsnprintf(buf, sizeof(buf), S_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) >= CIP_OK; if ( ok ) { (*gvar_sn)++; // Create a reference to this global variable VarRef(idc_var, gvar); } return ok ? CIP_OK : CIP_FAILED; } // // OPAQUE // case PY_ICID_OPAQUE: { if ( !wrap_PyObject_ptr(py_var, idc_var) ) return CIP_FAILED; return CIP_OK_OPAQUE; } // // Other objects // default: // A normal object? newref_t py_dir(PyObject_Dir(py_var.o)); Py_ssize_t size = PyList_Size(py_dir.o); if ( py_dir == NULL || !PyList_Check(py_dir.o) || size == 0 ) return CIP_FAILED; // Create the IDC object VarObject(idc_var); for ( Py_ssize_t i=0; i<size; i++ ) { borref_t item(PyList_GetItem(py_dir.o, i)); const char *field_name = PyString_AsString(item.o); if ( field_name == NULL ) continue; size_t len = strlen(field_name); // Skip private attributes if ( (len > 2 ) && (strncmp(field_name, "__", 2) == 0 ) && (strncmp(field_name+len-2, "__", 2) == 0) ) { continue; } idc_value_t v; // Get the non-private attribute from the object newref_t attr(PyObject_GetAttrString(py_var.o, field_name)); if (attr == NULL // Convert the attribute into an IDC value || pyvar_to_idcvar(attr, &v, gvar_sn) < CIP_OK) { return CIP_FAILED; } // Store the attribute VarSetAttr(idc_var, field_name, &v); } } } return CIP_OK; }