an explicit Label class

This commit is contained in:
Bryan Bishop 2012-04-02 12:36:08 -05:00
parent 1a3aebf191
commit 29a3fbf75b
1 changed files with 58 additions and 10 deletions

View File

@ -4,6 +4,7 @@ import sys, os, inspect, md5, json
from copy import copy, deepcopy from copy import copy, deepcopy
import subprocess import subprocess
from new import classobj from new import classobj
import random
#for IntervalMap #for IntervalMap
from bisect import bisect_left, bisect_right from bisect import bisect_left, bisect_right
@ -446,23 +447,23 @@ class RomStr(str):
def __repr__(self): def __repr__(self):
return "RomStr(too long)" return "RomStr(too long)"
rom = RomStr(None) rom = RomStr(None)
def load_rom(filename="../baserom.gbc"): def direct_load_rom(filename="../baserom.gbc"):
"""loads bytes into memory""" """loads bytes into memory"""
global rom global rom
file_handler = open(filename, "r") file_handler = open(filename, "r")
rom = RomStr(file_handler.read()) rom = RomStr(file_handler.read())
file_handler.close() file_handler.close()
return rom return rom
def maybe_load_rom(filename="../baserom.gbc"): def load_rom(filename="../baserom.gbc"):
"""checks that the loaded rom matches the path """checks that the loaded rom matches the path
and then loads the rom if necessary.""" and then loads the rom if necessary."""
global rom global rom
if rom != RomStr(None) and rom != None: if rom != RomStr(None) and rom != None:
return rom return rom
if not isinstance(rom, RomStr): if not isinstance(rom, RomStr):
return load_rom(filename=filename) return direct_load_rom(filename=filename)
elif os.lstat(filename).st_size != len(rom): elif os.lstat(filename).st_size != len(rom):
return load_rom(filename) return direct_load_rom(filename)
class AsmList(list): class AsmList(list):
"""simple wrapper to prevent all asm lines from being shown on screen""" """simple wrapper to prevent all asm lines from being shown on screen"""
@ -695,7 +696,7 @@ class TextScript():
""" """
global rom, text_count, max_texts, texts global rom, text_count, max_texts, texts
if rom == None: if rom == None:
load_rom() direct_load_rom()
if address == None: if address == None:
return "not a script" return "not a script"
commands = {} commands = {}
@ -2692,7 +2693,7 @@ class Script():
global rom global rom
if rom == None: if rom == None:
load_rom() direct_load_rom()
#max number of commands in a 'recursive' script #max number of commands in a 'recursive' script
max_cmds = 150 max_cmds = 150
@ -5869,6 +5870,13 @@ def remove_quoted_text(line):
line = line[0:first] + line[second+1:] line = line[0:first] + line[second+1:]
return line return line
class Label:
def __init__(self, name=None, address=None, line_number=None):
assert name!=None, "need a name"
assert address!=None, "need an address"
assert line_number!=None, "need a line number"
self.name, self.address, self.line_number = str(name), int(address), int(line_number)
def line_has_comment_address(line, returnable={}, bank=None): def line_has_comment_address(line, returnable={}, bank=None):
"""checks that a given line has a comment """checks that a given line has a comment
with a valid address, and returns the address in the object. with a valid address, and returns the address in the object.
@ -6116,7 +6124,7 @@ class TestCram(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
global rom global rom
cls.rom = load_rom() cls.rom = direct_load_rom()
rom = cls.rom rom = cls.rom
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
@ -6143,10 +6151,18 @@ class TestCram(unittest.TestCase):
self.assertEquals(len(groups), 10) self.assertEquals(len(groups), 10)
self.assertNotEqual(data, groups) self.assertNotEqual(data, groups)
self.assertNotEqual(len(data), len(groups)) self.assertNotEqual(len(data), len(groups))
def test_load_rom(self): def test_direct_load_rom(self):
rom = self.rom rom = self.rom
self.assertEqual(len(rom), 2097152) self.assertEqual(len(rom), 2097152)
self.failUnless(isinstance(rom, RomStr)) self.failUnless(isinstance(rom, RomStr))
def test_load_rom(self):
global rom
rom = None
load_rom()
self.failIf(rom == None)
rom = RomStr(None)
load_rom()
self.failIf(rom == RomStr(None))
def test_load_asm(self): def test_load_asm(self):
asm = load_asm() asm = load_asm()
joined_lines = "\n".join(asm) joined_lines = "\n".join(asm)
@ -6277,6 +6293,22 @@ class TestCram(unittest.TestCase):
}] }]
self.assertEqual(get_label_for(5), "poop") self.assertEqual(get_label_for(5), "poop")
all_labels = temp all_labels = temp
def test_generate_map_constant_labels(self):
ids = generate_map_constant_labels()
self.assertEqual(ids[0]["label"], "OLIVINE_POKECENTER_1F")
self.assertEqual(ids[1]["label"], "OLIVINE_GYM")
def test_is_valid_address(self):
self.assertTrue(is_valid_address(0))
self.assertTrue(is_valid_address(1))
self.assertTrue(is_valid_address(10))
self.assertTrue(is_valid_address(100))
self.assertTrue(is_valid_address(1000))
self.assertTrue(is_valid_address(10000))
self.assertFalse(is_valid_address(2097153))
self.assertFalse(is_valid_address(2098000))
addresses = [random.randrange(0,2097153) for i in range(0, 9+1)]
for address in addresses:
self.assertTrue(is_valid_address(address))
class TestIntervalMap(unittest.TestCase): class TestIntervalMap(unittest.TestCase):
def test_intervals(self): def test_intervals(self):
i = IntervalMap() i = IntervalMap()
@ -6616,10 +6648,25 @@ class TestScript(unittest.TestCase):
r = find_all_text_pointers_in_script_engine_script(script, bank=bank, debug=False) r = find_all_text_pointers_in_script_engine_script(script, bank=bank, debug=False)
results = list(r) results = list(r)
self.assertIn(0x197661, results) self.assertIn(0x197661, results)
class TestLabel(unittest.TestCase):
def test_label_making(self):
line_number = 2
address = 0xf0c0
label_name = "poop"
l = Label(name=label_name, address=address, line_number=line_number)
self.failUnless(hasattr(l, "name"))
self.failUnless(hasattr(l, "address"))
self.failUnless(hasattr(l, "line_number"))
self.failIf(isinstance(l.address, str))
self.failIf(isinstance(l.line_number, str))
self.failUnless(isinstance(l.name, str))
self.assertEqual(l.line_number, line_number)
self.assertEqual(l.name, label_name)
self.assertEqual(l.address, address)
class TestByteParams(unittest.TestCase): class TestByteParams(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
maybe_load_rom() load_rom()
cls.address = 10 cls.address = 10
cls.sbp = SingleByteParam(address=cls.address) cls.sbp = SingleByteParam(address=cls.address)
@classmethod @classmethod
@ -6668,6 +6715,7 @@ class TestMultiByteParam(unittest.TestCase):
#assuming no label at this location.. #assuming no label at this location..
self.assertEqual(self.cls.to_asm(), "$f0c0") self.assertEqual(self.cls.to_asm(), "$f0c0")
global all_labels global all_labels
#hm.. maybe all_labels should be using a class?
all_labels = [{"label": "poop", "address": 0xf0c0, all_labels = [{"label": "poop", "address": 0xf0c0,
"offset": 0xf0c0, "bank": 0, "offset": 0xf0c0, "bank": 0,
"line_number": 2 "line_number": 2
@ -6816,7 +6864,7 @@ def run_tests(): #rather than unittest.main()
print report_untested() print report_untested()
def run_main(): def run_main():
#read the rom and figure out the offsets for maps #read the rom and figure out the offsets for maps
load_rom() direct_load_rom()
load_map_group_offsets() load_map_group_offsets()
#add the offsets into our map structure, why not (johto maps only) #add the offsets into our map structure, why not (johto maps only)
[map_names[map_group_id+1].update({"offset": offset}) for map_group_id, offset in enumerate(map_group_offsets)] [map_names[map_group_id+1].update({"offset": offset}) for map_group_id, offset in enumerate(map_group_offsets)]