/* #<pydoc> def add_hotkey(hotkey, pyfunc): """ Associates a function call with a hotkey. Callable pyfunc will be called each time the hotkey is pressed @param hotkey: The hotkey @param pyfunc: Callable @return: Context object on success or None on failure. """ pass #</pydoc> */ PyObject *py_add_hotkey(const char *hotkey, PyObject *pyfunc) { PYW_GIL_CHECK_LOCKED_SCOPE(); // Make sure a callable was passed if ( !PyCallable_Check(pyfunc) ) return NULL; // Form the function name qstring idc_func_name; idc_func_name.sprnt("py_hotkeycb_%p", pyfunc); // Can add the hotkey? if ( add_idc_hotkey(hotkey, idc_func_name.c_str()) == IDCHK_OK ) do { // Generate global variable name qstring idc_gvarname; idc_gvarname.sprnt("_g_pyhotkey_ref_%p", pyfunc); // Now add the global variable idc_value_t *gvar = add_idc_gvar(idc_gvarname.c_str()); if ( gvar == NULL ) break; // The function body will call a registered IDC function that // will take a global variable that wraps a PyCallable as a pvoid qstring idc_func; idc_func.sprnt("static %s() { %s(%s); }", idc_func_name.c_str(), S_PYINVOKE0, idc_gvarname.c_str()); // Compile the IDC condition char errbuf[MAXSTR]; if ( !CompileLineEx(idc_func.c_str(), errbuf, sizeof(errbuf)) ) break; // Create new context // Define context py_idchotkey_ctx_t *ctx = new py_idchotkey_ctx_t(); // Remember the hotkey ctx->hotkey = hotkey; // Take reference to the callable ctx->pyfunc = pyfunc; Py_INCREF(pyfunc); // Bind IDC variable w/ the PyCallable gvar->set_pvoid(pyfunc); // Return the context return PyCObject_FromVoidPtr(ctx, NULL); } while (false); // Cleanup del_idc_hotkey(hotkey); Py_RETURN_NONE; }
//-------------------------------------------------------------------------- // return lowcnd_t if its condition is not satisfied lowcnd_t *debmod_t::get_failed_lowcnd(thid_t tid, ea_t ea) { #ifndef ENABLE_LOWCNDS qnotused(tid); qnotused(ea); #else lowcnds_t::iterator p = cndmap.find(ea); if ( p != cndmap.end() ) { bool ok = true; idc_value_t rv; char name[32]; ::qsnprintf(name, sizeof(name), "__lc%a", ea); lowcnd_t &lc = p->second; lock_begin(); { idc_debmod = this; // is required by compiler/interpreter idc_thread = tid; // is required by interpreter if ( !lc.compiled ) { qstring func; func.sprnt("static %s() { return %s; }", name, lc.cndbody.begin()); ok = CompileLineEx(func.begin(), NULL, 0, NULL, true); if ( ok ) lc.compiled = true; } if ( ok ) ok = Run(name, 0, NULL, &rv, NULL, 0); } lock_end(); if ( !ok ) { report_idc_error(ea, get_qerrno(), get_error_data(0), get_error_string(0)); return NULL; } VarInt64(&rv); if ( rv.i64 == 0 ) return &lc; // condition is not satisfied, resume } #endif return NULL; }