@ -88,6 +88,7 @@ cmdpy_dont_repeat (PyObject *self, PyObject *args)
/* Called if the gdb cmd_list_element is destroyed. */
/* Called if the gdb cmd_list_element is destroyed. */
static void
static void
cmdpy_destroyer ( struct cmd_list_element * self , void * context )
cmdpy_destroyer ( struct cmd_list_element * self , void * context )
{
{
@ -111,6 +112,7 @@ cmdpy_destroyer (struct cmd_list_element *self, void *context)
}
}
/* Called by gdb to invoke the command. */
/* Called by gdb to invoke the command. */
static void
static void
cmdpy_function ( struct cmd_list_element * command , char * args , int from_tty )
cmdpy_function ( struct cmd_list_element * command , char * args , int from_tty )
{
{
@ -145,30 +147,51 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
ttyobj , NULL ) ;
ttyobj , NULL ) ;
Py_DECREF ( argobj ) ;
Py_DECREF ( argobj ) ;
Py_DECREF ( ttyobj ) ;
Py_DECREF ( ttyobj ) ;
if ( ! result )
if ( ! result )
{
{
PyObject * ptype , * pvalue , * ptraceback ;
PyObject * ptype , * pvalue , * ptraceback ;
char * msg ;
PyErr_Fetch ( & ptype , & pvalue , & ptraceback ) ;
PyErr_Fetch ( & ptype , & pvalue , & ptraceback ) ;
if ( pvalue & & PyString_Check ( pvalue ) )
/* Try to fetch an error message contained within ptype, pvalue.
{
When fetching the error message we need to make our own copy ,
/* Make a temporary copy of the string data. */
we no longer own ptype , pvalue after the call to PyErr_Restore . */
char * s = PyString_AsString ( pvalue ) ;
char * copy = alloca ( strlen ( s ) + 1 ) ;
strcpy ( copy , s ) ;
msg = gdbpy_exception_to_string ( ptype , pvalue ) ;
PyErr_Restore ( ptype , pvalue , ptraceback ) ;
make_cleanup ( xfree , msg ) ;
if ( msg = = NULL )
{
/* An error occurred computing the string representation of the
error message . This is rare , but we should inform the user . */
printf_filtered ( _ ( " An error occurred in a Python command \n "
" and then another occurred computing the error message. \n " ) ) ;
gdbpy_print_stack ( ) ;
gdbpy_print_stack ( ) ;
error ( _ ( " Error occurred in Python command: %s " ) , copy ) ;
}
}
else
/* Don't print the stack for gdb.GdbError exceptions.
It is generally used to flag user errors .
We also don ' t want to print " Error occurred in Python command "
for user errors . However , a missing message for gdb . GdbError
exceptions is arguably a bug , so we flag it as such . */
if ( ! PyErr_GivenExceptionMatches ( ptype , gdbpy_gdberror_exc )
| | msg = = NULL | | * msg = = ' \0 ' )
{
{
PyErr_Restore ( ptype , pvalue , ptraceback ) ;
PyErr_Restore ( ptype , pvalue , ptraceback ) ;
gdbpy_print_stack ( ) ;
gdbpy_print_stack ( ) ;
error ( _ ( " Error occurred in Python command. " ) ) ;
if ( msg ! = NULL & & * msg ! = ' \0 ' )
error ( _ ( " Error occurred in Python command: %s " ) , msg ) ;
else
error ( _ ( " Error occurred in Python command. " ) ) ;
}
}
else
error ( " %s " , msg ) ;
}
}
Py_DECREF ( result ) ;
Py_DECREF ( result ) ;
do_cleanups ( cleanup ) ;
do_cleanups ( cleanup ) ;
}
}
@ -589,3 +612,55 @@ static PyTypeObject cmdpy_object_type =
0 , /* tp_alloc */
0 , /* tp_alloc */
PyType_GenericNew /* tp_new */
PyType_GenericNew /* tp_new */
} ;
} ;
/* Utility to build a buildargv-like result from ARGS.
This intentionally parses arguments the way libiberty / argv . c : buildargv
does . It splits up arguments in a reasonable way , and we want a standard
way of parsing arguments . Several gdb commands use buildargv to parse their
arguments . Plus we want to be able to write compatible python
implementations of gdb commands . */
PyObject *
gdbpy_string_to_argv ( PyObject * self , PyObject * args )
{
PyObject * py_argv ;
char * input ;
if ( ! PyArg_ParseTuple ( args , " s " , & input ) )
return NULL ;
py_argv = PyList_New ( 0 ) ;
/* buildargv uses NULL to represent an empty argument list, but we can't use
that in Python . Instead , if ARGS is " " then return an empty list .
This undoes the NULL - > " " conversion that cmdpy_function does . */
if ( * input ! = ' \0 ' )
{
char * * c_argv = gdb_buildargv ( input ) ;
int i ;
for ( i = 0 ; c_argv [ i ] ! = NULL ; + + i )
{
PyObject * argp = PyString_FromString ( c_argv [ i ] ) ;
if ( argp = = NULL
| | PyList_Append ( py_argv , argp ) < 0 )
{
if ( argp ! = NULL )
{
Py_DECREF ( argp ) ;
}
Py_DECREF ( py_argv ) ;
freeargv ( c_argv ) ;
return NULL ;
}
}
freeargv ( c_argv ) ;
}
return py_argv ;
}