[gobject-introspection] scanner: Fix get_symbols/comments to maintain the scanner lists



commit e6249ad007adeec2010ef8a8f8f7907b4d60fdfd
Author: Simon Feltman <sfeltman src gnome org>
Date:   Tue Dec 17 22:56:22 2013 -0800

    scanner: Fix get_symbols/comments to maintain the scanner lists
    
    Use g_slist_copy prior to returning the lists run through g_slist_reverse.
    This preserves the source scanners internally held lists where previously
    they would only point to a single element after a call, leaking memory and
    breaking subsequent calls. Note the functions as (transfer container) and
    use g_slist_free after calls in the Python bindings.
    Add new unittest file: test_sourcescanner.py for isolated unittesting of the
    SourceScanner.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=581525

 giscanner/giscannermodule.c         |    2 +
 giscanner/sourcescanner.c           |   18 +++++++++++++-
 tests/scanner/Makefile.am           |    6 ++++-
 tests/scanner/test_sourcescanner.py |   41 +++++++++++++++++++++++++++++++++++
 4 files changed, 64 insertions(+), 3 deletions(-)
---
diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c
index 925b3e0..b951227 100644
--- a/giscanner/giscannermodule.c
+++ b/giscanner/giscannermodule.c
@@ -575,6 +575,7 @@ pygi_source_scanner_get_symbols (PyGISourceScanner *self)
       PyList_SetItem (list, i++, item);
     }
 
+  g_slist_free (symbols);
   Py_INCREF (list);
   return list;
 }
@@ -598,6 +599,7 @@ pygi_source_scanner_get_comments (PyGISourceScanner *self)
       PyList_SetItem (list, i++, item);
     }
 
+  g_slist_free (comments);
   Py_INCREF (list);
   return list;
 }
diff --git a/giscanner/sourcescanner.c b/giscanner/sourcescanner.c
index 070397b..7de891f 100644
--- a/giscanner/sourcescanner.c
+++ b/giscanner/sourcescanner.c
@@ -309,14 +309,28 @@ gi_source_scanner_take_comment (GISourceScanner *scanner,
                                        comment);
 }
 
+/**
+ * gi_source_scanner_get_symbols:
+ * @scanner: scanner instance
+ *
+ * Returns: (transfer container): List of GISourceSymbol.
+ *   Free resulting list with g_slist_free().
+ */
 GSList *
 gi_source_scanner_get_symbols (GISourceScanner  *scanner)
 {
-  return g_slist_reverse (scanner->symbols);
+  return g_slist_reverse (g_slist_copy (scanner->symbols));
 }
 
+/**
+ * gi_source_scanner_get_comments:
+ * @scanner: scanner instance
+ *
+ * Returns: (transfer container): List of GISourceComment.
+ *   Free resulting list with g_slist_free().
+ */
 GSList *
 gi_source_scanner_get_comments(GISourceScanner  *scanner)
 {
-  return g_slist_reverse (scanner->comments);
+  return g_slist_reverse (g_slist_copy (scanner->comments));
 }
diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am
index d72d255..e3fd432 100644
--- a/tests/scanner/Makefile.am
+++ b/tests/scanner/Makefile.am
@@ -192,12 +192,16 @@ else
 CHECKDOCS =
 endif
 
+PYTESTS = test_sourcescanner.py
+
 XFAIL_TESTS = Typedefs-1.0.gir
-TESTS = Headeronly-1.0.gir $(CHECKGIRS) $(CHECKDOCS) $(TYPELIBS)
+TESTS = Headeronly-1.0.gir $(CHECKGIRS) $(CHECKDOCS) $(TYPELIBS) $(PYTESTS)
 TESTS_ENVIRONMENT = srcdir=$(srcdir) top_srcdir=$(top_srcdir) builddir=$(builddir) 
top_builddir=$(top_builddir) \
+       PYTHON=$(PYTHON) UNINSTALLED_INTROSPECTION_SRCDIR=$(top_srcdir) \
        $(top_srcdir)/tests/gi-tester
 
 EXTRA_DIST += \
+       $(PYTESTS) \
        Regress-1.0-C-expected                                  \
        Regress-1.0-Gjs-expected                                \
        Regress-1.0-Python-expected                             \
diff --git a/tests/scanner/test_sourcescanner.py b/tests/scanner/test_sourcescanner.py
new file mode 100644
index 0000000..3963683
--- /dev/null
+++ b/tests/scanner/test_sourcescanner.py
@@ -0,0 +1,41 @@
+import unittest
+import tempfile
+import os
+
+from giscanner.sourcescanner import SourceScanner
+
+
+two_typedefs_source = """
+/**
+ * Spam:
+ */
+typedef struct _spam Spam;
+
+/**
+ * Eggs:
+ */
+typedef struct _eggs Eggs;
+"""
+
+
+class Test(unittest.TestCase):
+    def setUp(self):
+        self.ss = SourceScanner()
+        tmp_fd, tmp_name = tempfile.mkstemp()
+        file = os.fdopen(tmp_fd, 'wt')
+        file.write(two_typedefs_source)
+        file.close()
+
+        self.ss.parse_files([tmp_name])
+
+    def test_get_symbols_length_consistency(self):
+        self.assertEqual(len(list(self.ss.get_symbols())), 2)
+        self.assertEqual(len(list(self.ss.get_symbols())), 2)
+
+    def test_get_comments_length_consistency(self):
+        self.assertEqual(len(list(self.ss.get_comments())), 2)
+        self.assertEqual(len(list(self.ss.get_comments())), 2)
+
+
+if __name__ == '__main__':
+    unittest.main()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]