]> granicus.if.org Git - yasm/commitdiff
Raise SymbolTable redefinition errors in Python.
authorMichael Urman <mu@tortall.net>
Sun, 7 May 2006 03:22:03 +0000 (03:22 -0000)
committerMichael Urman <mu@tortall.net>
Sun, 7 May 2006 03:22:03 +0000 (03:22 -0000)
Fix a double-free problem encountered during this testing.
Redefine symtab.define_special() vis parameter to match symrec.visibility.

svn path=/trunk/yasm/; revision=1526

tools/python-yasm/symrec.pxi
tools/python-yasm/tests/test_symrec.py

index 500d93fe3cdd40b6a4d6744bc515c195fd72aa04..871a655e2ad5061003d62b25cb44d61fad39e17a 100644 (file)
@@ -147,6 +147,7 @@ __python_symrec_cb = __assoc_data_callback(
 
 cdef object __make_symbol(yasm_symrec *symrec):
     cdef void *data
+    __error_check()
     data = yasm_symrec_get_data(symrec,
                                 (<__assoc_data_callback>__python_symrec_cb).cb)
     if data != NULL:
@@ -217,6 +218,16 @@ cdef class SymbolTableItemIterator:
         self.iter = yasm_symtab_next(self.iter)
         return rv
 
+cdef yasm_sym_vis __parse_vis(vis) except -1:
+    if not vis or vis == 'local': return YASM_SYM_LOCAL
+    if vis == 'global': return YASM_SYM_GLOBAL
+    if vis == 'common': return YASM_SYM_COMMON
+    if vis == 'extern': return YASM_SYM_EXTERN
+    if vis == 'dlocal': return YASM_SYM_DLOCAL
+    msg = "bad visibility value %r" % vis
+    PyErr_SetString(ValueError, msg)
+    return -1
+
 cdef class SymbolTable:
     cdef yasm_symtab *symtab
 
@@ -233,7 +244,7 @@ cdef class SymbolTable:
         if not isinstance(expr, Expression):
             raise TypeError
         return __make_symbol(yasm_symtab_define_equ(self.symtab, name,
-                (<Expression>expr).expr, line))
+                yasm_expr_copy((<Expression>expr).expr), line))
 
     def define_label(self, name, precbc, in_table, line):
         if not isinstance(precbc, Bytecode):
@@ -243,17 +254,11 @@ cdef class SymbolTable:
 
     def define_special(self, name, vis):
         return __make_symbol(yasm_symtab_define_special(self.symtab, name,
-                                                        vis))
+                                                        __parse_vis(vis)))
 
     def declare(self, name, vis, line):
-        cdef yasm_sym_vis cvis
-        if not vis or vis == 'local': cvis = YASM_SYM_LOCAL
-        elif vis == 'global': cvis = YASM_SYM_GLOBAL
-        elif vis == 'common': cvis = YASM_SYM_COMMON
-        elif vis == 'extern': cvis = YASM_SYM_EXTERN
-        elif vis == 'dlocal': cvis = YASM_SYM_DLOCAL
-        else: raise ValueError("bad visibility value '%s'" % vis)
-        return __make_symbol(yasm_symtab_declare(self.symtab, name, cvis, line))
+        return __make_symbol(yasm_symtab_declare(self.symtab, name,
+                                                 __parse_vis(vis), line))
 
     #
     # Methods to make SymbolTable behave like a dictionary of Symbols.
index e61f4d9fa048282b951b42c22c2a45353f1b5627..e3eb371072c411b49031883a512506e06e0d7c9b 100644 (file)
@@ -1,16 +1,44 @@
 # $Id$
 from tests import TestCase, add
-from yasm import SymbolTable
+from yasm import SymbolTable, Expression, YasmError
 
 class TSymbolTable(TestCase):
     def setUp(self):
         self.symtab = SymbolTable()
+
     def test_keys(self):
         self.assertEquals(len(self.symtab.keys()), 0)
         self.symtab.declare("foo", None, 0)
         keys = self.symtab.keys()
         self.assertEquals(len(keys), 1)
         self.assertEquals(keys[0], "foo")
+
+    def test_contains(self):
+        self.assert_("foo" not in self.symtab)
+        self.symtab.declare("foo", None, 0)
+        self.assert_("foo" in self.symtab)
+
+    def test_exception(self):
+        from operator import add
+        expr = Expression(add, 1, 2)
+        self.symtab.define_equ("foo", expr, 0)
+        self.assertRaises(YasmError, self.symtab.define_equ, "foo", expr, 0)
+        self.symtab.define_equ("bar", expr, 0) # cleared
+        self.assertRaises(YasmError, self.symtab.define_special, "bar",
+                'global')
+
+    def test_iters(self):
+        tab = self.symtab
+        tab.declare("foo", None, 0)
+        tab.declare("bar", None, 0)
+        tab.declare("baz", None, 0)
+
+        # while ordering is not known, it must be consistent
+        self.assertEquals(list(tab.keys()), list(tab.iterkeys()))
+        self.assertEquals(list(tab.values()), list(tab.itervalues()))
+        self.assertEquals(list(tab.items()), list(tab.iteritems()))
+        self.assertEquals(list(tab.iteritems()), zip(tab.keys(), tab.values()))
+
 add(TSymbolTable)
 
 class TSymbolAttr(TestCase):