Skip to content

Commit 9a84512

Browse files
authored
Merge pull request #8884 from chelcassanova/cherrypick/add-commandoverridecallback-api-test
Reland "[lldb][api-test] Add API test for SBCommandInterpreter::Comm…
2 parents 6694ebd + 52b3708 commit 9a84512

File tree

6 files changed

+148
-3
lines changed

6 files changed

+148
-3
lines changed

lldb/bindings/python/python-typemaps.swig

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
427427
free($1);
428428
}
429429

430-
431430
// For Log::LogOutputCallback
432431
%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
433432
if (!($input == Py_None ||
@@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
476475
$1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
477476
}
478477

478+
%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
479+
if (!($input == Py_None ||
480+
PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
481+
PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
482+
SWIG_fail;
483+
}
484+
485+
// Don't lose the callback reference.
486+
Py_INCREF($input);
487+
$1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
488+
$2 = $input;
489+
}
490+
%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) {
491+
$1 = $input == Py_None;
492+
$1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
493+
}
494+
479495
%typemap(in) lldb::FileSP {
480496
PythonFile py_file(PyRefType::Borrowed, $input);
481497
if (!py_file) {

lldb/bindings/python/python-wrapper.swig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,28 @@ static void LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
11421142
}
11431143
}
11441144

1145+
static bool LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void *baton, const char **argv) {
1146+
bool ret_val = false;
1147+
if (baton != Py_None) {
1148+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
1149+
// Create a PyList of items since we're going to pass it to the callback as a tuple
1150+
// of arguments.
1151+
PyObject *py_argv = PyList_New(0);
1152+
for (const char **arg = argv; arg && *arg; arg++) {
1153+
std::string arg_string = *arg;
1154+
PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), arg_string.size());
1155+
PyList_Append(py_argv, py_string);
1156+
}
1157+
1158+
PyObject *result = PyObject_CallObject(
1159+
reinterpret_cast<PyObject *>(baton), PyList_AsTuple(py_argv));
1160+
ret_val = result ? PyObject_IsTrue(result) : false;
1161+
Py_XDECREF(result);
1162+
SWIG_PYTHON_THREAD_END_BLOCK;
1163+
}
1164+
return ret_val;
1165+
}
1166+
11451167
static SBError LLDBSwigPythonCallLocateModuleCallback(
11461168
void *callback_baton, const SBModuleSpec &module_spec_sb,
11471169
SBFileSpec &module_file_spec_sb, SBFileSpec &symbol_file_spec_sb) {

lldb/bindings/python/static-binding/LLDBWrapPython.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5947,6 +5947,28 @@ static void LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
59475947
}
59485948
}
59495949

5950+
static bool LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void *baton, const char **argv) {
5951+
bool ret_val = false;
5952+
if (baton != Py_None) {
5953+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
5954+
// Create a PyList of items since we're going to pass it to the callback as a tuple
5955+
// of arguments.
5956+
PyObject *py_argv = PyList_New(0);
5957+
for (const char **arg = argv; arg && *arg; arg++) {
5958+
std::string arg_string = *arg;
5959+
PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), arg_string.size());
5960+
PyList_Append(py_argv, py_string);
5961+
}
5962+
5963+
PyObject *result = PyObject_CallObject(
5964+
reinterpret_cast<PyObject *>(baton), PyList_AsTuple(py_argv));
5965+
ret_val = result ? PyObject_IsTrue(result) : false;
5966+
Py_XDECREF(result);
5967+
SWIG_PYTHON_THREAD_END_BLOCK;
5968+
}
5969+
return ret_val;
5970+
}
5971+
59505972
static SBError LLDBSwigPythonCallLocateModuleCallback(
59515973
void *callback_baton, const SBModuleSpec &module_spec_sb,
59525974
SBFileSpec &module_file_spec_sb, SBFileSpec &symbol_file_spec_sb) {
@@ -16511,6 +16533,58 @@ SWIGINTERN PyObject *_wrap_SBCommandInterpreter_InterruptCommand(PyObject *self,
1651116533
}
1651216534

1651316535

16536+
SWIGINTERN PyObject *_wrap_SBCommandInterpreter_SetCommandOverrideCallback(PyObject *self, PyObject *args) {
16537+
PyObject *resultobj = 0;
16538+
lldb::SBCommandInterpreter *arg1 = (lldb::SBCommandInterpreter *) 0 ;
16539+
char *arg2 = (char *) 0 ;
16540+
lldb::CommandOverrideCallback arg3 = (lldb::CommandOverrideCallback) 0 ;
16541+
void *arg4 = (void *) 0 ;
16542+
void *argp1 = 0 ;
16543+
int res1 = 0 ;
16544+
int res2 ;
16545+
char *buf2 = 0 ;
16546+
int alloc2 = 0 ;
16547+
PyObject *swig_obj[3] ;
16548+
bool result;
16549+
16550+
(void)self;
16551+
if (!SWIG_Python_UnpackTuple(args, "SBCommandInterpreter_SetCommandOverrideCallback", 3, 3, swig_obj)) SWIG_fail;
16552+
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBCommandInterpreter, 0 | 0 );
16553+
if (!SWIG_IsOK(res1)) {
16554+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBCommandInterpreter_SetCommandOverrideCallback" "', argument " "1"" of type '" "lldb::SBCommandInterpreter *""'");
16555+
}
16556+
arg1 = reinterpret_cast< lldb::SBCommandInterpreter * >(argp1);
16557+
res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2);
16558+
if (!SWIG_IsOK(res2)) {
16559+
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SBCommandInterpreter_SetCommandOverrideCallback" "', argument " "2"" of type '" "char const *""'");
16560+
}
16561+
arg2 = reinterpret_cast< char * >(buf2);
16562+
{
16563+
if (!(swig_obj[2] == Py_None ||
16564+
PyCallable_Check(reinterpret_cast<PyObject *>(swig_obj[2])))) {
16565+
PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
16566+
SWIG_fail;
16567+
}
16568+
16569+
// Don't lose the callback reference.
16570+
Py_INCREF(swig_obj[2]);
16571+
arg3 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
16572+
arg4 = swig_obj[2];
16573+
}
16574+
{
16575+
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
16576+
result = (bool)(arg1)->SetCommandOverrideCallback((char const *)arg2,arg3,arg4);
16577+
SWIG_PYTHON_THREAD_END_ALLOW;
16578+
}
16579+
resultobj = SWIG_From_bool(static_cast< bool >(result));
16580+
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
16581+
return resultobj;
16582+
fail:
16583+
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
16584+
return NULL;
16585+
}
16586+
16587+
1651416588
SWIGINTERN PyObject *_wrap_SBCommandInterpreter_IsActive(PyObject *self, PyObject *args) {
1651516589
PyObject *resultobj = 0;
1651616590
lldb::SBCommandInterpreter *arg1 = (lldb::SBCommandInterpreter *) 0 ;
@@ -92259,6 +92333,7 @@ static PyMethodDef SwigMethods[] = {
9225992333
{ "SBCommandInterpreter_HandleCompletionWithDescriptions", _wrap_SBCommandInterpreter_HandleCompletionWithDescriptions, METH_VARARGS, "SBCommandInterpreter_HandleCompletionWithDescriptions(SBCommandInterpreter self, char const * current_line, uint32_t cursor_pos, int match_start_point, int max_return_elements, SBStringList matches, SBStringList descriptions) -> int"},
9226092334
{ "SBCommandInterpreter_WasInterrupted", _wrap_SBCommandInterpreter_WasInterrupted, METH_O, "SBCommandInterpreter_WasInterrupted(SBCommandInterpreter self) -> bool"},
9226192335
{ "SBCommandInterpreter_InterruptCommand", _wrap_SBCommandInterpreter_InterruptCommand, METH_O, "SBCommandInterpreter_InterruptCommand(SBCommandInterpreter self) -> bool"},
92336+
{ "SBCommandInterpreter_SetCommandOverrideCallback", _wrap_SBCommandInterpreter_SetCommandOverrideCallback, METH_VARARGS, "SBCommandInterpreter_SetCommandOverrideCallback(SBCommandInterpreter self, char const * command_name, lldb::CommandOverrideCallback callback) -> bool"},
9226292337
{ "SBCommandInterpreter_IsActive", _wrap_SBCommandInterpreter_IsActive, METH_O, "SBCommandInterpreter_IsActive(SBCommandInterpreter self) -> bool"},
9226392338
{ "SBCommandInterpreter_GetIOHandlerControlSequence", _wrap_SBCommandInterpreter_GetIOHandlerControlSequence, METH_VARARGS, "SBCommandInterpreter_GetIOHandlerControlSequence(SBCommandInterpreter self, char ch) -> char const *"},
9226492339
{ "SBCommandInterpreter_GetPromptOnQuit", _wrap_SBCommandInterpreter_GetPromptOnQuit, METH_O, "SBCommandInterpreter_GetPromptOnQuit(SBCommandInterpreter self) -> bool"},

lldb/bindings/python/static-binding/lldb.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3392,6 +3392,10 @@ def InterruptCommand(self):
33923392
r"""InterruptCommand(SBCommandInterpreter self) -> bool"""
33933393
return _lldb.SBCommandInterpreter_InterruptCommand(self)
33943394

3395+
def SetCommandOverrideCallback(self, command_name, callback):
3396+
r"""SetCommandOverrideCallback(SBCommandInterpreter self, char const * command_name, lldb::CommandOverrideCallback callback) -> bool"""
3397+
return _lldb.SBCommandInterpreter_SetCommandOverrideCallback(self, command_name, callback)
3398+
33953399
def IsActive(self):
33963400
r"""IsActive(SBCommandInterpreter self) -> bool"""
33973401
return _lldb.SBCommandInterpreter_IsActive(self)

lldb/include/lldb/API/SBCommandInterpreter.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,9 @@ class SBCommandInterpreter {
264264
// Catch commands before they execute by registering a callback that will get
265265
// called when the command gets executed. This allows GUI or command line
266266
// interfaces to intercept a command and stop it from happening
267-
#ifndef SWIG
268267
bool SetCommandOverrideCallback(const char *command_name,
269268
lldb::CommandOverrideCallback callback,
270269
void *baton);
271-
#endif
272270

273271
/// Return true if the command interpreter is the active IO handler.
274272
///
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class CommandOverrideCallback(TestBase):
8+
def setUp(self):
9+
TestBase.setUp(self)
10+
self.line = line_number("main.c", "Hello world.")
11+
12+
def test_command_override_callback(self):
13+
self.build()
14+
exe = self.getBuildArtifact("a.out")
15+
16+
target = self.dbg.CreateTarget(exe)
17+
self.assertTrue(target, VALID_TARGET)
18+
19+
ci = self.dbg.GetCommandInterpreter()
20+
self.assertTrue(ci, VALID_COMMAND_INTERPRETER)
21+
22+
command_arg = ""
23+
24+
def foo(*command_args):
25+
nonlocal command_arg
26+
command_arg = command_args[0]
27+
28+
self.assertTrue(ci.SetCommandOverrideCallback("breakpoint set", foo))
29+
self.expect("breakpoint set -n main")
30+
self.assertTrue(command_arg == "breakpoint")

0 commit comments

Comments
 (0)