From 2bb8f231957e2beecfb689a896252b8d9fb67e23 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 12 Jan 2017 08:59:26 -0700 Subject: [PATCH] Remove some gotos from Python This patch slightly refactors a couple of spots in the Python code to avoid some gotos. gdb/ChangeLog 2017-02-10 Tom Tromey * python/python.c (do_start_initialization): New function, from _initialize_python. (_initialize_python): Call do_start_initialization. * python/py-linetable.c (ltpy_iternext): Use explicit returns, not goto. --- gdb/ChangeLog | 8 + gdb/python/py-linetable.c | 14 +- gdb/python/python.c | 326 +++++++++++++++++++------------------- 3 files changed, 182 insertions(+), 166 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6b449f0d83..ddf4de0116 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2017-02-10 Tom Tromey + + * python/python.c (do_start_initialization): New function, from + _initialize_python. + (_initialize_python): Call do_start_initialization. + * python/py-linetable.c (ltpy_iternext): Use explicit returns, not + goto. + 2017-02-10 Tom Tromey * python/py-prettyprint.c (pretty_print_one_value): Use diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c index d8597e47aa..a5e57b0d36 100644 --- a/gdb/python/py-linetable.c +++ b/gdb/python/py-linetable.c @@ -407,7 +407,10 @@ ltpy_iternext (PyObject *self) LTPY_REQUIRE_VALID (iter_obj->source, symtab); if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems) - goto stop_iteration; + { + PyErr_SetNone (PyExc_StopIteration); + return NULL; + } item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]); @@ -419,7 +422,10 @@ ltpy_iternext (PyObject *self) /* Exit if the internal value is the last item in the line table. */ if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems) - goto stop_iteration; + { + PyErr_SetNone (PyExc_StopIteration); + return NULL; + } item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]); } @@ -427,10 +433,6 @@ ltpy_iternext (PyObject *self) iter_obj->current_index++; return obj; - - stop_iteration: - PyErr_SetNone (PyExc_StopIteration); - return NULL; } /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean. diff --git a/gdb/python/python.c b/gdb/python/python.c index 74a6f427c2..1f5ab4230e 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1525,8 +1525,10 @@ finalize_python (void *ignore) /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_python; -void -_initialize_python (void) +#ifdef HAVE_PYTHON + +static bool +do_start_initialization () { char *progname; #ifdef IS_PY3K @@ -1536,6 +1538,166 @@ _initialize_python (void) wchar_t *progname_copy; #endif +#ifdef WITH_PYTHON_PATH + /* Work around problem where python gets confused about where it is, + and then can't find its libraries, etc. + NOTE: Python assumes the following layout: + /foo/bin/python + /foo/lib/pythonX.Y/... + This must be done before calling Py_Initialize. */ + progname = concat (ldirname (python_libdir), SLASH_STRING, "bin", + SLASH_STRING, "python", (char *) NULL); +#ifdef IS_PY3K + oldloc = xstrdup (setlocale (LC_ALL, NULL)); + setlocale (LC_ALL, ""); + progsize = strlen (progname); + progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t)); + if (!progname_copy) + { + xfree (oldloc); + fprintf (stderr, "out of memory\n"); + return false; + } + count = mbstowcs (progname_copy, progname, progsize + 1); + if (count == (size_t) -1) + { + xfree (oldloc); + fprintf (stderr, "Could not convert python path to string\n"); + return false; + } + setlocale (LC_ALL, oldloc); + xfree (oldloc); + + /* Note that Py_SetProgramName expects the string it is passed to + remain alive for the duration of the program's execution, so + it is not freed after this call. */ + Py_SetProgramName (progname_copy); +#else + Py_SetProgramName (progname); +#endif +#endif + + Py_Initialize (); + PyEval_InitThreads (); + +#ifdef IS_PY3K + gdb_module = PyModule_Create (&python_GdbModuleDef); + /* Add _gdb module to the list of known built-in modules. */ + _PyImport_FixupBuiltin (gdb_module, "_gdb"); +#else + gdb_module = Py_InitModule ("_gdb", python_GdbMethods); +#endif + if (gdb_module == NULL) + return false; + + /* The casts to (char*) are for python 2.4. */ + if (PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version) < 0 + || PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", + (char*) host_name) < 0 + || PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", + (char*) target_name) < 0) + return false; + + /* Add stream constants. */ + if (PyModule_AddIntConstant (gdb_module, "STDOUT", 0) < 0 + || PyModule_AddIntConstant (gdb_module, "STDERR", 1) < 0 + || PyModule_AddIntConstant (gdb_module, "STDLOG", 2) < 0) + return false; + + gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL); + if (gdbpy_gdb_error == NULL + || gdb_pymodule_addobject (gdb_module, "error", gdbpy_gdb_error) < 0) + return false; + + gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError", + gdbpy_gdb_error, NULL); + if (gdbpy_gdb_memory_error == NULL + || gdb_pymodule_addobject (gdb_module, "MemoryError", + gdbpy_gdb_memory_error) < 0) + return false; + + gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL); + if (gdbpy_gdberror_exc == NULL + || gdb_pymodule_addobject (gdb_module, "GdbError", + gdbpy_gdberror_exc) < 0) + return false; + + gdbpy_initialize_gdb_readline (); + + if (gdbpy_initialize_auto_load () < 0 + || gdbpy_initialize_values () < 0 + || gdbpy_initialize_frames () < 0 + || gdbpy_initialize_commands () < 0 + || gdbpy_initialize_symbols () < 0 + || gdbpy_initialize_symtabs () < 0 + || gdbpy_initialize_blocks () < 0 + || gdbpy_initialize_functions () < 0 + || gdbpy_initialize_parameters () < 0 + || gdbpy_initialize_types () < 0 + || gdbpy_initialize_pspace () < 0 + || gdbpy_initialize_objfile () < 0 + || gdbpy_initialize_breakpoints () < 0 + || gdbpy_initialize_finishbreakpoints () < 0 + || gdbpy_initialize_lazy_string () < 0 + || gdbpy_initialize_linetable () < 0 + || gdbpy_initialize_thread () < 0 + || gdbpy_initialize_inferior () < 0 + || gdbpy_initialize_events () < 0 + || gdbpy_initialize_eventregistry () < 0 + || gdbpy_initialize_py_events () < 0 + || gdbpy_initialize_event () < 0 + || gdbpy_initialize_stop_event () < 0 + || gdbpy_initialize_signal_event () < 0 + || gdbpy_initialize_breakpoint_event () < 0 + || gdbpy_initialize_continue_event () < 0 + || gdbpy_initialize_inferior_call_pre_event () < 0 + || gdbpy_initialize_inferior_call_post_event () < 0 + || gdbpy_initialize_register_changed_event () < 0 + || gdbpy_initialize_memory_changed_event () < 0 + || gdbpy_initialize_exited_event () < 0 + || gdbpy_initialize_thread_event () < 0 + || gdbpy_initialize_new_objfile_event () < 0 + || gdbpy_initialize_clear_objfiles_event () < 0 + || gdbpy_initialize_arch () < 0 + || gdbpy_initialize_xmethods () < 0 + || gdbpy_initialize_unwind () < 0) + return false; + + gdbpy_to_string_cst = PyString_FromString ("to_string"); + if (gdbpy_to_string_cst == NULL) + return false; + gdbpy_children_cst = PyString_FromString ("children"); + if (gdbpy_children_cst == NULL) + return false; + gdbpy_display_hint_cst = PyString_FromString ("display_hint"); + if (gdbpy_display_hint_cst == NULL) + return false; + gdbpy_doc_cst = PyString_FromString ("__doc__"); + if (gdbpy_doc_cst == NULL) + return false; + gdbpy_enabled_cst = PyString_FromString ("enabled"); + if (gdbpy_enabled_cst == NULL) + return false; + gdbpy_value_cst = PyString_FromString ("value"); + if (gdbpy_value_cst == NULL) + return false; + + /* Release the GIL while gdb runs. */ + PyThreadState_Swap (NULL); + PyEval_ReleaseLock (); + + make_final_cleanup (finalize_python, NULL); + + /* Only set this when initialization has succeeded. */ + gdb_python_initialized = 1; + return true; +} + +#endif /* HAVE_PYTHON */ + +void +_initialize_python (void) +{ add_com ("python-interactive", class_obscure, python_interactive_command, #ifdef HAVE_PYTHON @@ -1607,164 +1769,8 @@ message == an error message without a stack will be printed."), &user_show_python_list); #ifdef HAVE_PYTHON -#ifdef WITH_PYTHON_PATH - /* Work around problem where python gets confused about where it is, - and then can't find its libraries, etc. - NOTE: Python assumes the following layout: - /foo/bin/python - /foo/lib/pythonX.Y/... - This must be done before calling Py_Initialize. */ - progname = concat (ldirname (python_libdir), SLASH_STRING, "bin", - SLASH_STRING, "python", (char *) NULL); -#ifdef IS_PY3K - oldloc = xstrdup (setlocale (LC_ALL, NULL)); - setlocale (LC_ALL, ""); - progsize = strlen (progname); - progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t)); - if (!progname_copy) - { - xfree (oldloc); - fprintf (stderr, "out of memory\n"); - return; - } - count = mbstowcs (progname_copy, progname, progsize + 1); - if (count == (size_t) -1) - { - xfree (oldloc); - fprintf (stderr, "Could not convert python path to string\n"); - return; - } - setlocale (LC_ALL, oldloc); - xfree (oldloc); - - /* Note that Py_SetProgramName expects the string it is passed to - remain alive for the duration of the program's execution, so - it is not freed after this call. */ - Py_SetProgramName (progname_copy); -#else - Py_SetProgramName (progname); -#endif -#endif - - Py_Initialize (); - PyEval_InitThreads (); - -#ifdef IS_PY3K - gdb_module = PyModule_Create (&python_GdbModuleDef); - /* Add _gdb module to the list of known built-in modules. */ - _PyImport_FixupBuiltin (gdb_module, "_gdb"); -#else - gdb_module = Py_InitModule ("_gdb", python_GdbMethods); -#endif - if (gdb_module == NULL) - goto fail; - - /* The casts to (char*) are for python 2.4. */ - if (PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version) < 0 - || PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", - (char*) host_name) < 0 - || PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", - (char*) target_name) < 0) - goto fail; - - /* Add stream constants. */ - if (PyModule_AddIntConstant (gdb_module, "STDOUT", 0) < 0 - || PyModule_AddIntConstant (gdb_module, "STDERR", 1) < 0 - || PyModule_AddIntConstant (gdb_module, "STDLOG", 2) < 0) - goto fail; - - gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL); - if (gdbpy_gdb_error == NULL - || gdb_pymodule_addobject (gdb_module, "error", gdbpy_gdb_error) < 0) - goto fail; - - gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError", - gdbpy_gdb_error, NULL); - if (gdbpy_gdb_memory_error == NULL - || gdb_pymodule_addobject (gdb_module, "MemoryError", - gdbpy_gdb_memory_error) < 0) - goto fail; - - gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL); - if (gdbpy_gdberror_exc == NULL - || gdb_pymodule_addobject (gdb_module, "GdbError", - gdbpy_gdberror_exc) < 0) - goto fail; - - gdbpy_initialize_gdb_readline (); - - if (gdbpy_initialize_auto_load () < 0 - || gdbpy_initialize_values () < 0 - || gdbpy_initialize_frames () < 0 - || gdbpy_initialize_commands () < 0 - || gdbpy_initialize_symbols () < 0 - || gdbpy_initialize_symtabs () < 0 - || gdbpy_initialize_blocks () < 0 - || gdbpy_initialize_functions () < 0 - || gdbpy_initialize_parameters () < 0 - || gdbpy_initialize_types () < 0 - || gdbpy_initialize_pspace () < 0 - || gdbpy_initialize_objfile () < 0 - || gdbpy_initialize_breakpoints () < 0 - || gdbpy_initialize_finishbreakpoints () < 0 - || gdbpy_initialize_lazy_string () < 0 - || gdbpy_initialize_linetable () < 0 - || gdbpy_initialize_thread () < 0 - || gdbpy_initialize_inferior () < 0 - || gdbpy_initialize_events () < 0 - || gdbpy_initialize_eventregistry () < 0 - || gdbpy_initialize_py_events () < 0 - || gdbpy_initialize_event () < 0 - || gdbpy_initialize_stop_event () < 0 - || gdbpy_initialize_signal_event () < 0 - || gdbpy_initialize_breakpoint_event () < 0 - || gdbpy_initialize_continue_event () < 0 - || gdbpy_initialize_inferior_call_pre_event () < 0 - || gdbpy_initialize_inferior_call_post_event () < 0 - || gdbpy_initialize_register_changed_event () < 0 - || gdbpy_initialize_memory_changed_event () < 0 - || gdbpy_initialize_exited_event () < 0 - || gdbpy_initialize_thread_event () < 0 - || gdbpy_initialize_new_objfile_event () < 0 - || gdbpy_initialize_clear_objfiles_event () < 0 - || gdbpy_initialize_arch () < 0 - || gdbpy_initialize_xmethods () < 0 - || gdbpy_initialize_unwind () < 0) - goto fail; - - gdbpy_to_string_cst = PyString_FromString ("to_string"); - if (gdbpy_to_string_cst == NULL) - goto fail; - gdbpy_children_cst = PyString_FromString ("children"); - if (gdbpy_children_cst == NULL) - goto fail; - gdbpy_display_hint_cst = PyString_FromString ("display_hint"); - if (gdbpy_display_hint_cst == NULL) - goto fail; - gdbpy_doc_cst = PyString_FromString ("__doc__"); - if (gdbpy_doc_cst == NULL) - goto fail; - gdbpy_enabled_cst = PyString_FromString ("enabled"); - if (gdbpy_enabled_cst == NULL) - goto fail; - gdbpy_value_cst = PyString_FromString ("value"); - if (gdbpy_value_cst == NULL) - goto fail; - - /* Release the GIL while gdb runs. */ - PyThreadState_Swap (NULL); - PyEval_ReleaseLock (); - - make_final_cleanup (finalize_python, NULL); - - gdb_python_initialized = 1; - return; - - fail: - gdbpy_print_stack (); - /* Do not set 'gdb_python_initialized'. */ - return; - + if (!do_start_initialization () && PyErr_Occurred ()) + gdbpy_print_stack (); #endif /* HAVE_PYTHON */ }