2008-04-29 Thiago Jung Bauermann * Makefile.in (SUBDIR_PYTHON_OBS): Add python-symtab.o. (SUBDIR_PYTHON_SRCS): Add python/symtab.c. (python-symtab.o): New target. * python/frame.c (frame_object_methods): Add find_sal and read_var_value Python methods. (frapy_find_sal, frapy_read_var_value): New functions. * python/python-internal.h (gdbpy_lookup_symbol, symtab_and_line_to_sal_object, symtab_to_symtab_object, gdbpy_initialize_symtabs): Declare. * python/python.c (demand_python): Add lookup_symbol and decode_line Python functions. Call gdb_initialize_symtabs. (gdbpy_decode_line): New function. Include linespec.h, symtab.h and source.c. * python/symbol.c (symtab_object_methods): Add get_symtab Python method. (sympy_get_symtab, gdbpy_lookup_symbol): New functions. * python/symtab.c: New file. Index: python-tromey.git/gdb/Makefile.in =================================================================== --- python-tromey.git.orig/gdb/Makefile.in 2008-04-29 11:47:49.000000000 -0300 +++ python-tromey.git/gdb/Makefile.in 2008-04-29 11:49:51.000000000 -0300 @@ -267,6 +267,7 @@ SUBDIR_PYTHON_OBS = \ python-cmd.o \ python-frame.o \ python-hooks.o \ + python-symtab.o \ python-symbol.o \ python-value.o SUBDIR_PYTHON_SRCS = \ @@ -276,6 +277,7 @@ SUBDIR_PYTHON_SRCS = \ python/cmd.c \ python/frame.c \ python/hooks.c \ + python/symtab.c \ python/symbol.c \ python/value.c SUBDIR_PYTHON_DEPS = @@ -3423,7 +3425,8 @@ PYTHON_CFLAGS=-fno-strict-aliasing python.o: $(srcdir)/python/python.c $(defs_h) $(python_h) \ $(command_h) $(libiberty_h) $(cli_decode_h) $(charset_h) $(top_h) \ - $(exceptions_h) $(python_internal_h) $(version_h) $(solib_h) + $(exceptions_h) $(python_internal_h) $(version_h) $(solib_h) \ + $(linespec_h) $(symtab_h) $(source_h) $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) $(srcdir)/python/python.c python-block.o: $(srcdir)/python/block.c $(defs_h) $(block_h) $(dictionary_h) \ $(symtab_h) $(python_h) $(python_internal_h) @@ -3452,6 +3455,10 @@ python-symbol.o: $(srcdir)/python/symbol $(python_internal_h) $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \ $(srcdir)/python/symbol.c -o python-symbol.o +python-symtab.o: $(srcdir)/python/symtab.c $(defs_h) $(charset_h) $(source_h) \ + $(symtab_h) $(python_h) $(python_internal_h) + $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \ + $(srcdir)/python/symtab.c -o python-symtab.o python-value.o: $(srcdir)/python/value.c $(defs_h) $(exceptions_h) \ $(python_internal_h) $(value_h) $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \ Index: python-tromey.git/gdb/python/frame.c =================================================================== --- python-tromey.git.orig/gdb/python/frame.c 2008-04-29 11:47:49.000000000 -0300 +++ python-tromey.git/gdb/python/frame.c 2008-04-29 11:47:56.000000000 -0300 @@ -56,6 +56,8 @@ static PyObject *frapy_get_pc (PyObject static PyObject *frapy_get_address_in_block (PyObject *self, PyObject *args); static PyObject *frapy_get_prev (PyObject *self, PyObject *args); static PyObject *frapy_get_next (PyObject *self, PyObject *args); +static PyObject *frapy_find_sal (PyObject *self, PyObject *args); +static PyObject *frapy_read_var_value (PyObject *self, PyObject *args); #define FRAPY_REQUIRE_VALID(frame_obj, frame) \ do { \ @@ -84,6 +86,10 @@ static PyMethodDef frame_object_methods[ { "get_prev", frapy_get_prev, METH_NOARGS, "Return the previous (outer) frame." }, { "get_next", frapy_get_next, METH_NOARGS, "Return the next (inner) frame." }, + { "find_sal", frapy_find_sal, METH_NOARGS, + "Return the frame's symtab and line." }, + { "read_var_value", frapy_read_var_value, METH_VARARGS, + "Return the value of the variable in this frame." }, {NULL} /* Sentinel */ }; @@ -403,6 +409,54 @@ frapy_get_next (PyObject *self, PyObject return next_obj; } +static PyObject * +frapy_find_sal (PyObject *self, PyObject *args) +{ + struct frame_info *frame; + struct symtab_and_line sal; + volatile struct gdb_exception except; + PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */ + + TRY_CATCH (except, RETURN_MASK_ALL) + { + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); + + find_frame_sal (frame, &sal); + sal_obj = symtab_and_line_to_sal_object (sal); + } + GDB_PY_HANDLE_EXCEPTION (except); + + return sal_obj; +} + +static PyObject * +frapy_read_var_value (PyObject *self, PyObject *args) +{ + struct frame_info *frame; + PyObject *sym_obj; + struct symbol *var; + struct value *val = NULL; + volatile struct gdb_exception except; + + if (!PyArg_ParseTuple (args, "O!", &symbol_object_type, &sym_obj)) + return NULL; + + var = symbol_object_to_symbol (sym_obj); + + TRY_CATCH (except, RETURN_MASK_ALL) + { + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); + + val = read_var_value (var, frame); + } + GDB_PY_HANDLE_EXCEPTION (except); + + if (val) + return value_to_value_object (val); + + Py_RETURN_NONE; +} + PyObject * gdbpy_get_frames (PyObject *self, PyObject *args) { Index: python-tromey.git/gdb/python/python-internal.h =================================================================== --- python-tromey.git.orig/gdb/python/python-internal.h 2008-04-29 11:47:49.000000000 -0300 +++ python-tromey.git/gdb/python/python-internal.h 2008-04-29 11:47:56.000000000 -0300 @@ -37,9 +37,12 @@ PyObject *gdbpy_get_breakpoints (PyObjec PyObject *gdbpy_get_frames (PyObject *, PyObject *); PyObject *gdbpy_get_current_frame (PyObject *, PyObject *); PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *); +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args); PyObject *gdbpy_get_selected_frame (PyObject *self, PyObject *args); PyObject *variable_to_python (struct cmd_list_element *); +PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal); +PyObject *symtab_to_symtab_object (struct symtab *symtab); PyObject *symbol_to_symbol_object (struct symbol *sym); PyObject *block_to_block_object (struct block *block); PyObject *value_to_value_object (struct value *v); @@ -55,6 +58,7 @@ void gdbpy_initialize_values (void); void gdbpy_initialize_hooks (void); void gdbpy_initialize_breakpoints (void); void gdbpy_initialize_frames (void); +void gdbpy_initialize_symtabs (void); void gdbpy_initialize_commands (void); void gdbpy_initialize_symbols (void); void gdbpy_initialize_blocks (void); Index: python-tromey.git/gdb/python/python.c =================================================================== --- python-tromey.git.orig/gdb/python/python.c 2008-04-29 11:47:49.000000000 -0300 +++ python-tromey.git/gdb/python/python.c 2008-04-29 11:47:56.000000000 -0300 @@ -27,6 +27,9 @@ #include "solib.h" #include "exceptions.h" #include "python-internal.h" +#include "linespec.h" +#include "symtab.h" +#include "source.h" #include "version.h" #include @@ -36,6 +39,7 @@ PyObject *gdb_module; static PyObject *get_show_variable (PyObject *, PyObject *); static PyObject *execute_gdb_command (PyObject *, PyObject *); static PyObject *gdbpy_solib_address (PyObject *, PyObject *); +static PyObject *gdbpy_decode_line (PyObject *, PyObject *); static PyObject *gdbpy_find_pc_function (PyObject *, PyObject *); @@ -68,12 +72,19 @@ demand_python () { "frame_stop_reason_string", gdbpy_frame_stop_reason_string, METH_VARARGS, "Return a string explaining unwind stop reason" }, + { "lookup_symbol", gdbpy_lookup_symbol, METH_VARARGS, + "Return the symbol corresponding to the given name, or None." }, { "solib_address", gdbpy_solib_address, METH_VARARGS, "Return shared library holding a given address, or None." }, { "find_pc_function", gdbpy_find_pc_function, METH_VARARGS, "Return the function containing the given pc value, or None." }, + { "decode_line", gdbpy_decode_line, METH_VARARGS, + "Decode a string argument the way that 'break' or 'edit' does.\n\ +Return a tuple holding the file name (or None) and line number (or None).\n\ +Note: may later change to return an object." }, + {NULL, NULL, 0, NULL} }; @@ -89,6 +100,7 @@ demand_python () gdbpy_initialize_values (); gdbpy_initialize_breakpoints (); gdbpy_initialize_frames (); + gdbpy_initialize_symtabs (); gdbpy_initialize_commands (); gdbpy_initialize_symbols (); gdbpy_initialize_blocks (); @@ -388,6 +400,78 @@ gdbpy_find_pc_function (PyObject *self, Py_RETURN_NONE; } +PyObject * +gdbpy_decode_line (PyObject *self, PyObject *args) +{ + struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to appease gcc. */ + struct symtab_and_line sal; + char *arg = NULL; + int free_sals = 0, i; + PyObject *result = NULL; + volatile struct gdb_exception except; + + if (! PyArg_ParseTuple (args, "|s", &arg)) + return NULL; + + TRY_CATCH (except, RETURN_MASK_ALL) + { + if (arg) + { + char *copy; + + arg = strdup (arg); + copy = arg; + + sals = decode_line_1 (©, 0, 0, 0, 0, 0); + free_sals = 1; + } + else + { + set_default_source_symtab_and_line (); + sal = get_current_source_symtab_and_line (); + sals.sals = &sal; + sals.nelts = 1; + } + } + if (arg) + xfree (arg); + + if (except.reason < 0) + { + if (free_sals) + xfree (sals.sals); + /* We know this will always throw. */ + GDB_PY_HANDLE_EXCEPTION (except); + } + + if (sals.nelts) + { + result = PyTuple_New (sals.nelts); + for (i = 0; i < sals.nelts; ++i) + { + PyObject *obj; + char *str; + + obj = symtab_and_line_to_sal_object (sals.sals[i]); + if (! obj) + { + Py_DECREF (result); + result = NULL; + break; + } + + PyTuple_SetItem (result, i, obj); + } + } + + if (free_sals) + xfree (sals.sals); + + if (result) + return result; + Py_RETURN_NONE; +} + void Index: python-tromey.git/gdb/python/symbol.c =================================================================== --- python-tromey.git.orig/gdb/python/symbol.c 2008-04-29 11:47:49.000000000 -0300 +++ python-tromey.git/gdb/python/symbol.c 2008-04-29 11:47:56.000000000 -0300 @@ -28,6 +28,7 @@ typedef struct { static PyObject *sympy_str (PyObject *self); static PyObject *sympy_get_value (PyObject *self, PyObject *args); +static PyObject *sympy_get_symtab (PyObject *self, PyObject *args); static PyObject *sympy_get_natural_name (PyObject *self, PyObject *args); static PyObject *sympy_get_linkage_name (PyObject *self, PyObject *args); static PyObject *sympy_get_print_name (PyObject *self, PyObject *args); @@ -36,6 +37,8 @@ static PyObject *sympy_get_class (PyObje static PyMethodDef symbol_object_methods[] = { { "get_value", sympy_get_value, METH_NOARGS, "Return the value of the symbol." }, + { "get_symtab", sympy_get_symtab, METH_NOARGS, + "Return the value of the symbol." }, { "get_natural_name", sympy_get_natural_name, METH_NOARGS, "Return the \"natural\" name of the symbol." }, { "get_linkage_name", sympy_get_linkage_name, METH_NOARGS, @@ -115,6 +118,14 @@ sympy_get_value (PyObject *self, PyObjec } static PyObject * +sympy_get_symtab (PyObject *self, PyObject *args) +{ + symbol_object *self_sym = (symbol_object *) self; + + return symtab_to_symtab_object (SYMBOL_SYMTAB (self_sym->symbol)); +} + +static PyObject * sympy_get_natural_name (PyObject *self, PyObject *args) { symbol_object *self_sym = (symbol_object *) self; @@ -169,6 +180,73 @@ symbol_object_to_symbol (PyObject *obj) return ((symbol_object *) obj)->symbol; } +/* This function has less arguments than its C counterpart, to simplify the + Python interface: name, block and domain. The other two arguments are always + assumed to be set, and a tuple with 3 elements is always returned. The first + is the symbol object or None, the second is a boolean with the value of + is_a_field_of_this, and the third is the symbol object or None. */ +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args) +{ + int domain, is_a_field_of_this = 0; + const char *name; + struct symbol *symbol; + struct symtab *symtab; + PyObject *block_obj, *ret_tuple, *sym_obj, *symtab_obj, *bool_obj; + + PyArg_ParseTuple (args, "sO!i", &name, &block_object_type, &block_obj, + &domain); + + symbol = lookup_symbol (name, block_object_to_block (block_obj), domain, + &is_a_field_of_this, &symtab); + + ret_tuple = PyTuple_New (3); + if (!ret_tuple) + { + PyErr_SetString (PyExc_MemoryError, "Could not allocate tuple object."); + return NULL; + } + + if (symbol) + { + sym_obj = symbol_to_symbol_object (symbol); + if (!sym_obj) + { + Py_DECREF (ret_tuple); + return NULL; + } + } + else + { + sym_obj = Py_None; + Py_INCREF (Py_None); + } + PyTuple_SET_ITEM (ret_tuple, 0, sym_obj); + + bool_obj = is_a_field_of_this? Py_True : Py_False; + Py_INCREF (bool_obj); + PyTuple_SET_ITEM (ret_tuple, 1, bool_obj); + + if (symtab) + { + symtab_obj = symtab_to_symtab_object (symtab); + if (!symtab_obj) + { + /* I *think* this will take care of decref'ing sym_obj and + bool_obj. */ + Py_DECREF (ret_tuple); + return NULL; + } + } + else + { + symtab_obj = Py_None; + Py_INCREF (Py_None); + } + PyTuple_SET_ITEM (ret_tuple, 2, symtab_obj); + + return ret_tuple; +} + void gdbpy_initialize_symbols (void) { Index: python-tromey.git/gdb/python/symtab.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ python-tromey.git/gdb/python/symtab.c 2008-04-29 11:47:56.000000000 -0300 @@ -0,0 +1,325 @@ +/* Python interface to symbol tables. + + Copyright (C) 2008 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "charset.h" +#include "symtab.h" +#include "source.h" +#include "python-internal.h" + +typedef struct { + PyObject_HEAD + struct symtab *symtab; +} symtab_object; + +static PyObject *stpy_str (PyObject *self); +static PyObject *stpy_filename (PyObject *self, PyObject *args); +static PyObject *stpy_to_fullname (PyObject *self, PyObject *args); + +static PyMethodDef symtab_object_methods[] = { + { "get_filename", stpy_filename, METH_NOARGS, + "Return the symtab's source filename." }, + { "to_fullname", stpy_to_fullname, METH_NOARGS, + "Return the symtab's full source filename." }, + {NULL} /* Sentinel */ +}; + +static PyTypeObject symtab_object_type = { + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ + "gdb.Symtab", /*tp_name*/ + sizeof (symtab_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + stpy_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "GDB symtab object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + symtab_object_methods /* tp_methods */ +}; + +typedef struct { + PyObject_HEAD + symtab_object *symtab; + struct symtab_and_line *sal; +} sal_object; + +static void salpy_dealloc (PyObject *self); +static int salpy_setsymtab (PyObject *self, PyObject *value, void *closure); +static PyObject *salpy_str (PyObject *self); +static PyObject *salpy_getsymtab (PyObject *self, void *closure); +static PyObject *salpy_pc (PyObject *self, PyObject *args); +static PyObject *salpy_line (PyObject *self, PyObject *args); + +static PyGetSetDef sal_object_getseters[] = { + { "symtab", salpy_getsymtab, salpy_setsymtab, "Symtab object.", NULL }, + {NULL} /* Sentinel */ +}; + +static PyMethodDef sal_object_methods[] = { + { "get_pc", salpy_pc, METH_NOARGS, + "Return the symtab_and_line's pc." }, + { "get_line", salpy_line, METH_NOARGS, + "Return the symtab_and_line's line." }, + {NULL} /* Sentinel */ +}; + +static PyTypeObject sal_object_type = { + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ + "gdb.Symtab_and_line", /*tp_name*/ + sizeof (sal_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + salpy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + salpy_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "GDB symtab_and_line object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + sal_object_methods, /* tp_methods */ + 0, /* tp_members */ + sal_object_getseters /* tp_getset */ +}; + + +static PyObject * +stpy_str (PyObject *self) +{ + int ret; + char *s; + PyObject *result; + + ret = asprintf (&s, "symbol table for %s", + ((symtab_object *) self)->symtab->filename); + if (ret < 0) + Py_RETURN_NONE; + + result = PyString_FromString (s); + xfree (s); + + return result; +} + +/* FIXME: maybe this should be an attribute instead of a method? */ +static PyObject * +stpy_filename (PyObject *self, PyObject *args) +{ + symtab_object *self_symtab = (symtab_object *) self; + PyObject *str_obj; + + /* FIXME: Can symtab->filename really be NULL? */ + if (self_symtab->symtab->filename) + str_obj = PyString_Decode (self_symtab->symtab->filename, + strlen (self_symtab->symtab->filename), + host_charset (), NULL /* FIXME */); + else + { + str_obj = Py_None; + Py_INCREF (Py_None); + } + + return str_obj; +} + +static PyObject * +stpy_to_fullname (PyObject *self, PyObject *args) +{ + char *fullname; + + fullname = symtab_to_fullname (((symtab_object *) self)->symtab); + if (fullname) + return PyString_Decode (fullname, strlen (fullname), host_charset (), + NULL /* FIXME */); + + Py_RETURN_NONE; +} + +static PyObject * +salpy_str (PyObject *self) +{ + int ret; + char *s, *filename; + sal_object *sal_obj; + PyObject *result; + + sal_obj = (sal_object *) self; + filename = (sal_obj->symtab == (symtab_object *) Py_None)? "" : + sal_obj->symtab->symtab->filename; + ret = asprintf (&s, "symbol and line for %s, line %d", filename, + sal_obj->sal->line); + if (ret < 0) + Py_RETURN_NONE; + + result = PyString_FromString (s); + xfree (s); + + return result; +} + +static PyObject * +salpy_pc (PyObject *self, PyObject *args) +{ + return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->pc); +} + +static PyObject * +salpy_line (PyObject *self, PyObject *args) +{ + return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->line); +} + +static PyObject * +salpy_getsymtab (PyObject *self, void *closure) +{ + sal_object *self_sal = (sal_object *) self; + + Py_INCREF (self_sal->symtab); + + return (PyObject *) self_sal->symtab; +} + +static int +salpy_setsymtab (PyObject *self, PyObject *value, void *closure) +{ + PyErr_SetString (PyExc_TypeError, "The symtab attribute can't be modified."); + + return -1; +} + +static void +salpy_dealloc (PyObject *self) +{ + sal_object *self_sal = (sal_object *) self; + + Py_DECREF (self_sal->symtab); + xfree (self_sal->sal); + self_sal->ob_type->tp_free (self); +} + +PyObject * +symtab_and_line_to_sal_object (struct symtab_and_line sal) +{ + sal_object *sal_obj; + symtab_object *symtab_obj; + + sal_obj = PyObject_New (sal_object, &sal_object_type); + if (sal_obj == NULL) + { + PyErr_SetString (PyExc_MemoryError, + "Could not allocate Symtab_and_line object."); + return NULL; + } + + if (sal.symtab) + { + symtab_obj = (symtab_object *) symtab_to_symtab_object (sal.symtab); + if (symtab_obj == NULL) + { + Py_DECREF (sal_obj); + return NULL; + } + + symtab_obj->symtab = sal.symtab; + } + else + { + symtab_obj = (symtab_object *) Py_None; + Py_INCREF (Py_None); + } + + sal_obj->sal = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + *(sal_obj->sal) = sal; + sal_obj->symtab = symtab_obj; + + return (PyObject *) sal_obj; +} + +PyObject * +symtab_to_symtab_object (struct symtab *symtab) +{ + symtab_object *symtab_obj; + + symtab_obj = PyObject_New (symtab_object, &symtab_object_type); + if (symtab_obj == NULL) + { + PyErr_SetString (PyExc_MemoryError, + "Could not allocate Symtab object."); + + return NULL; + } + + symtab_obj->symtab = symtab; + + return (PyObject *) symtab_obj; +} + +void +gdbpy_initialize_symtabs (void) +{ + symtab_object_type.tp_new = PyType_GenericNew; + if (PyType_Ready (&symtab_object_type) < 0) + return; + + sal_object_type.tp_new = PyType_GenericNew; + if (PyType_Ready (&sal_object_type) < 0) + return; + + Py_INCREF (&symtab_object_type); + PyModule_AddObject (gdb_module, "Symtab", (PyObject *) &symtab_object_type); + + Py_INCREF (&sal_object_type); + PyModule_AddObject (gdb_module, "Symtab_and_line", + (PyObject *) &sal_object_type); +} -- -- []'s Thiago Jung Bauermann Software Engineer IBM Linux Technology Center