示例#1
0
/*
#<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;
}
示例#2
0
文件: debmod.cpp 项目: nealey/vera
//--------------------------------------------------------------------------
// 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;
}