fix docstring formatting everywhere

This commit is contained in:
Bryan Bishop 2013-03-21 15:15:42 -05:00
parent 1abb020335
commit 4332a25bd5
8 changed files with 161 additions and 96 deletions

View File

@ -17,12 +17,14 @@ from romstr import (
)
def load_rom(path):
""" Loads a ROM file into an abbreviated RomStr object.
"""
Loads a ROM file into an abbreviated RomStr object.
"""
return direct_load_rom(filename=path)
def load_asm(path):
""" Loads source ASM into an abbreviated AsmList object.
"""
Loads source ASM into an abbreviated AsmList object.
"""
return direct_load_asm(filename=path)
@ -38,7 +40,8 @@ def findall_iter(sub, string):
return iter(next_index(len(sub)).next, -1)
class Address(int):
""" A simple int wrapper to take 0xFFFF and $FFFF addresses.
"""
A simple int wrapper to take 0xFFFF and $FFFF addresses.
"""
def __new__(cls, x=None, *args, **kwargs):
@ -59,8 +62,9 @@ class Address(int):
found_blobs = []
class BinaryBlob(object):
""" Stores a label, line number, and addresses of a function from Pokémon
Red. These details can be used to determine whether or not the function was
"""
Stores a label, line number, and addresses of a function from Pokémon Red.
These details can be used to determine whether or not the function was
copied into Pokémon Crystal.
"""
@ -100,7 +104,8 @@ class BinaryBlob(object):
self.find_by_first_bytes()
def __repr__(self):
""" A beautiful poem.
"""
A beautiful poem.
"""
r = "BinaryBlob("
@ -122,13 +127,15 @@ class BinaryBlob(object):
return self.__repr__()
def parse_from_red(self):
""" Reads bytes from Pokémon Red and stores them.
"""
Reads bytes from Pokémon Red and stores them.
"""
self.bytes = redrom[self.start_address : self.end_address + 1]
def pretty_bytes(self):
""" Returns a better looking range of bytes.
"""
Returns a better looking range of bytes.
"""
bytes = redrom.interval(self.start_address, \
@ -138,7 +145,8 @@ class BinaryBlob(object):
return bytes
def find_in_crystal(self):
""" Checks whether or not the bytes appear in Pokémon Crystal.
"""
Checks whether or not the bytes appear in Pokémon Crystal.
"""
finditer = findall_iter(self.bytes, cryrom)
@ -151,7 +159,8 @@ class BinaryBlob(object):
print self.label + ": found " + str(len(self.locations)) + " matches."
def find_by_first_bytes(self):
""" Finds this blob in Crystal based on the first n bytes.
"""
Finds this blob in Crystal based on the first n bytes.
"""
# how many bytes to match
@ -184,7 +193,8 @@ redrom = load_rom(pokered_rom_path)
redsrc = load_asm(pokered_src_path)
def scan_red_asm(bank_stop=3, debug=True):
""" Scans the ASM from Pokémon Red. Finds labels and objects. Does things.
"""
Scans the ASM from Pokémon Red. Finds labels and objects. Does things.
Uses get_label_from_line and get_address_from_line_comment.
"""

View File

@ -275,10 +275,11 @@ def command_debug_information(command_byte=None, map_group=None, map_id=None, ad
all_texts = []
class TextScript:
""" A text is a sequence of bytes (and sometimes commands). It's not the
same thing as a Script. The bytes are translated into characters based
on the lookup table (see chars.py). The in-text commands are for including
values from RAM, playing sound, etc.
"""
A text is a sequence of bytes (and sometimes commands). It's not the same
thing as a Script. The bytes are translated into characters based on the
lookup table (see chars.py). The in-text commands are for including values
from RAM, playing sound, etc.
see: http://hax.iimarck.us/files/scriptingcodes_eng.htm#InText
"""
@ -1157,7 +1158,8 @@ def generate_map_constants():
print maps
def generate_map_constants_dimensions():
""" Generate _WIDTH and _HEIGHT properties.
"""
Generate _WIDTH and _HEIGHT properties.
"""
global map_internal_ids
output = ""
@ -1172,8 +1174,10 @@ def generate_map_constants_dimensions():
return output
def transform_wildmons(asm):
""" Converts a wildmons section to use map constants.
input: wildmons text. """
"""
Converts a wildmons section to use map constants.
input: wildmons text.
"""
asmlines = asm.split("\n")
returnlines = []
for line in asmlines:
@ -1899,7 +1903,8 @@ class GivePoke(Command):
return True
class DataByteWordMacro(Command):
""" Only used by the preprocessor.
"""
Only used by the preprocessor.
"""
id = None
@ -2000,9 +2005,9 @@ movement_command_bases = {
# create MovementCommands from movement_command_bases
def create_movement_commands(debug=False):
""" Creates MovementCommands from movement_command_bases.
This is just a cheap trick instead of manually defining
all of those classes.
"""
Creates MovementCommands from movement_command_bases. This is just a cheap
trick instead of manually defining all of those classes.
"""
#movement_command_classes = inspect.getmembers(sys.modules[__name__], \
# lambda obj: inspect.isclass(obj) and \
@ -3561,7 +3566,8 @@ class TrainerFragmentParam(PointerLabelParam):
trainer_group_table = None
class TrainerGroupTable:
""" A list of pointers.
"""
A list of pointers.
This should probably be called TrainerGroupPointerTable.
"""
@ -3639,7 +3645,8 @@ class TrainerGroupHeader:
script_parse_table[address : self.last_address] = self
def get_dependencies(self, recompute=False, global_dependencies=set()):
""" TrainerGroupHeader has no dependencies.
"""
TrainerGroupHeader has no dependencies.
"""
# TODO: possibly include self.individual_trainer_headers
if recompute or self.dependencies == None:
@ -3725,7 +3732,8 @@ class TrainerHeader:
# TrainerGroupHeader covers its address range
def make_name(self):
""" Must occur after parse() is called.
"""
Must occur after parse() is called.
Constructs a name based on self.parent.group_name and self.name.
"""
if self.trainer_group_id in [0x14, 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x41]:
@ -3806,7 +3814,8 @@ class TrainerHeader:
return output
class TrainerPartyMonParser:
""" Just a generic trainer party mon parser.
"""
Just a generic trainer party mon parser.
Don't use this directly. Only use the child classes.
"""
id = None
@ -3863,7 +3872,9 @@ class TrainerPartyMonParser:
return output
class TrainerPartyMonParser0(TrainerPartyMonParser):
""" Data type <0x00>: Pokémon Data is <Level> <Species>. Used by most trainers. """
"""
Data type <0x00>: Pokémon Data is <Level> <Species>. Used by most trainers.
"""
id = 0
size = 2 + 1
param_types = {
@ -3871,7 +3882,10 @@ class TrainerPartyMonParser0(TrainerPartyMonParser):
1: {"name": "species", "class": PokemonParam},
}
class TrainerPartyMonParser1(TrainerPartyMonParser):
""" Data type <0x01>: Pokémon Data is <Level> <Pokémon> <Move1> <Move2> <Move3> <Move4>. Used often for Gym Leaders."""
"""
Data type <0x01>: Pokémon Data is <Level> <Pokémon> <Move1> <Move2> <Move3>
<Move4>. Used often for Gym Leaders.
"""
id = 1
size = 6 + 1
param_types = {
@ -3883,7 +3897,9 @@ class TrainerPartyMonParser1(TrainerPartyMonParser):
5: {"name": "move4", "class": MoveParam},
}
class TrainerPartyMonParser2(TrainerPartyMonParser):
""" Data type <0x02>: Pokémon Data is <Level> <Pokémon> <Held Item>. Used mainly by Pokéfans. """
"""
Data type <0x02>: Pokémon Data is <Level> <Pokémon> <Held Item>. Used mainly by Pokéfans.
"""
id = 2
size = 3 + 1
param_types = {
@ -3892,8 +3908,11 @@ class TrainerPartyMonParser2(TrainerPartyMonParser):
2: {"name": "item", "class": ItemLabelByte},
}
class TrainerPartyMonParser3(TrainerPartyMonParser):
""" Data type <0x03>: Pokémon Data is <Level> <Pokémon> <Held Item> <Move1> <Move2> <Move3> <Move4>.
Used by a few Cooltrainers. """
"""
Data type <0x03>: Pokémon Data is <Level> <Pokémon> <Held Item> <Move1>
<Move2> <Move3> <Move4>.
Used by a few Cooltrainers.
"""
id = 3
size = 7 + 1
param_types = {
@ -3909,7 +3928,8 @@ class TrainerPartyMonParser3(TrainerPartyMonParser):
trainer_party_mon_parsers = [TrainerPartyMonParser0, TrainerPartyMonParser1, TrainerPartyMonParser2, TrainerPartyMonParser3]
def find_trainer_ids_from_scripts():
""" Looks through all scripts to find trainer group numbers and trainer numbers.
"""
Looks through all scripts to find trainer group numbers and trainer numbers.
This can be used with trainer_group_maximums to figure out the current number of
trainers in each of the originating trainer groups.
@ -3930,7 +3950,8 @@ def find_trainer_ids_from_scripts():
trainer_group_maximums[key] = value
def report_unreferenced_trainer_ids():
""" Reports on the number of unreferenced trainer ids in each group.
"""
Reports on the number of unreferenced trainer ids in each group.
This should be called after find_trainer_ids_from_scripts.
@ -3971,7 +3992,8 @@ def report_unreferenced_trainer_ids():
print "total unreferenced trainers: " + str(total_unreferenced_trainers)
def check_script_has_trainer_data(script):
""" see find_trainer_ids_from_scripts
"""
see find_trainer_ids_from_scripts
"""
for command in script.commands:
trainer_group = None
@ -3991,7 +4013,7 @@ def check_script_has_trainer_data(script):
trainer_group_maximums[trainer_group] = set([trainer_id])
def trainer_name_from_group(group_id, trainer_id=0):
""" This doesn't actually work for trainer_id > 0."""
"""This doesn't actually work for trainer_id > 0."""
bank = calculate_bank(0x39999)
ptr_address = 0x39999 + ((group_id - 1)*2)
address = calculate_pointer_from_bytes_at(ptr_address, bank=bank)
@ -3999,7 +4021,8 @@ def trainer_name_from_group(group_id, trainer_id=0):
return text
def trainer_group_report():
""" Reports how many trainer ids are used in each trainer group.
"""
Reports how many trainer ids are used in each trainer group.
"""
output = ""
total = 0
@ -4016,7 +4039,8 @@ def trainer_group_report():
return output
def make_trainer_group_name_trainer_ids(trainer_group_table, debug=True):
""" Edits trainer_group_names and sets the trainer names.
"""
Edits trainer_group_names and sets the trainer names.
For instance, "AMY & MAY" becomes "AMY_AND_MAY1" and "AMY_AND_MAY2"
This should only be used after TrainerGroupTable.parse has been called.
@ -4054,7 +4078,8 @@ def make_trainer_group_name_trainer_ids(trainer_group_table, debug=True):
print "done improving trainer names"
def pretty_print_trainer_id_constants():
""" Prints out some constants for trainer ids, for "constants.asm".
"""
Prints out some constants for trainer ids, for "constants.asm".
make_trainer_group_name_trainer_ids must be called prior to this.
"""
@ -4785,7 +4810,8 @@ def old_parse_map_header_at(address, map_group=None, map_id=None, debug=True):
def get_direction(connection_byte, connection_id):
""" Given a connection byte and a connection id, which direction is this
"""
Given a connection byte and a connection id, which direction is this
connection?
example:
@ -6228,7 +6254,8 @@ def parse_all_map_headers(debug=True):
map_names[group_id][map_id]["header_old"] = old_parsed_map
class PokedexEntryPointerTable:
""" A list of pointers.
"""
A list of pointers.
"""
def __init__(self):
@ -6277,8 +6304,6 @@ class PokedexEntryPointerTable:
return output
class PokedexEntry:
""" """
def __init__(self, address, pokemon_id):
self.address = address
self.dependencies = None
@ -6767,7 +6792,8 @@ class Asm:
return llabel
return False
def does_address_have_label(self, address):
""" Checks if an address has a label.
"""
Checks if an address has a label.
"""
# either something will directly have the address
# or- it's possibel that no label was given
@ -6993,8 +7019,8 @@ def list_things_in_bank(bank):
return objects
def list_texts_in_bank(bank):
""" Narrows down the list of objects
that you will be inserting into Asm.
"""
Narrows down the list of objects that you will be inserting into Asm.
"""
if len(all_texts) == 0:
raise Exception("all_texts is blank.. run_main() will populate it")
@ -7011,8 +7037,8 @@ def list_texts_in_bank(bank):
return texts
def list_movements_in_bank(bank):
""" Narrows down the list of objects
to speed up Asm insertion.
"""
Narrows down the list of objects to speed up Asm insertion.
"""
if len(all_movements) == 0:
raise Exception("all_movements is blank.. run_main() will populate it")
@ -7027,8 +7053,9 @@ def list_movements_in_bank(bank):
return movements
def dump_asm_for_texts_in_bank(bank, start=50, end=100):
""" Simple utility to help with dumping texts into a particular bank. This
is helpful for figuring out which text is breaking that bank.
"""
Simple utility to help with dumping texts into a particular bank. This is
helpful for figuring out which text is breaking that bank.
"""
# load and parse the ROM if necessary
if rom == None or len(rom) <= 4:
@ -7063,7 +7090,8 @@ def dump_asm_for_movements_in_bank(bank, start=0, end=100):
print "done dumping movements for bank $%.2x" % (bank)
def dump_things_in_bank(bank, start=50, end=100):
""" is helpful for figuring out which object is breaking that bank.
"""
is helpful for figuring out which object is breaking that bank.
"""
# load and parse the ROM if necessary
if rom == None or len(rom) <= 4:
@ -7155,7 +7183,8 @@ def get_label_for(address):
all_new_labels = []
class Label:
""" Every object in script_parse_table is given a label.
"""
Every object in script_parse_table is given a label.
This label is simply a way to keep track of what objects have
been previously written to file.
@ -7191,8 +7220,9 @@ class Label:
all_new_labels.append(self)
def check_is_in_file(self):
""" This method checks if the label appears in the file
based on the entries to the Asm.parts list.
"""
This method checks if the label appears in the file based on the
entries to the Asm.parts list.
"""
# assert new_asm != None, "new_asm should be an instance of Asm"
load_asm2()
@ -7201,18 +7231,19 @@ class Label:
return is_in_file
def check_address_is_in_file(self):
""" Checks if the address is in use by another label.
"""
Checks if the address is in use by another label.
"""
load_asm2()
self.address_is_in_file = new_asm.does_address_have_label(self.address)
return self.address_is_in_file
def old_check_address_is_in_file(self):
""" Checks whether or not the address of the object is
already in the file. This might happen if the label name
is different but the address is the same. Another scenario
is that the label is already used, but at a different
address.
"""
Checks whether or not the address of the object is already in the file.
This might happen if the label name is different but the address is the
same. Another scenario is that the label is already used, but at a
different address.
This method works by looking at the INCBINs. When there is
an INCBIN that covers this address in the file, then there
@ -7232,7 +7263,8 @@ class Label:
return False
def make_label(self):
""" Generates a label name based on parents and self.object.
"""
Generates a label name based on parents and self.object.
"""
object = self.object
name = object.make_label()

View File

@ -10,7 +10,8 @@ from romstr import (
)
class RomGraph(nx.DiGraph):
""" Graphs various functions pointing to each other.
"""
Graphs various functions pointing to each other.
TODO: Bank switches are nasty. They should be detected. Otherwise,
functions will point to non-functions within the same bank. Another way
@ -35,7 +36,8 @@ class RomGraph(nx.DiGraph):
rompath = "../baserom.gbc"
def __init__(self, rom=None, **kwargs):
""" Loads and parses the ROM into a function graph.
"""
Loads and parses the ROM into a function graph.
"""
# continue the initialization
nx.DiGraph.__init__(self, **kwargs)
@ -50,14 +52,16 @@ class RomGraph(nx.DiGraph):
self.parse()
def load_rom(self):
""" Creates a RomStr from rompath.
"""
Creates a RomStr from rompath.
"""
file_handler = open(self.rompath, "r")
self.rom = RomStr(file_handler.read())
file_handler.close()
def parse(self):
""" Parses the ROM starting with the first function address. Each
"""
Parses the ROM starting with the first function address. Each
function is disassembled and parsed to find where else it leads to.
"""
functions = {}
@ -123,13 +127,15 @@ class RomGraph(nx.DiGraph):
self.functions = functions
def pretty_printer(self):
""" Shows some text output describing which nodes point to which other
nodes.
"""
Shows some text output describing which nodes point to which other
nodes.
"""
print self.edges()
def to_d3(self):
""" Exports to d3.js because we're gangster like that.
"""
Exports to d3.js because we're gangster like that.
"""
import networkx.readwrite.json_graph as json_graph
content = json_graph.dumps(self)
@ -138,12 +144,14 @@ class RomGraph(nx.DiGraph):
fh.close()
def to_gephi(self):
""" Generates a gexf file.
"""
Generates a gexf file.
"""
nx.write_gexf(self, "graph.gexf")
class RedGraph(RomGraph):
""" Not implemented. Go away.
"""
Not implemented. Go away.
"""
rompath = "../pokered-baserom.gbc"

View File

@ -130,7 +130,8 @@ def line_has_comment_address(line, returnable={}, bank=None):
return True
def get_address_from_line_comment(line, bank=None):
""" wrapper for line_has_comment_address
"""
wrapper for line_has_comment_address
"""
returnable = {}
result = line_has_comment_address(line, returnable=returnable, bank=bank)

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
"""
"""
# this is modified in crystal.py during run-time
map_names = {

View File

@ -32,7 +32,8 @@ end_08_scripts_with = [
spacing = "\t"
class RomStr(str):
""" Simple wrapper to prevent a giant rom from being shown on screen.
"""
Simple wrapper to prevent a giant rom from being shown on screen.
"""
def __init__(self, *args, **kwargs):
@ -41,13 +42,15 @@ class RomStr(str):
str.__init__(self)
def __repr__(self):
""" Simplifies this object so that the output doesn't overflow stdout.
"""
Simplifies this object so that the output doesn't overflow stdout.
"""
return "RomStr(too long)"
@classmethod
def load(cls, filename=None, crystal=True, red=False):
""" Loads a ROM into a RomStr.
"""
Loads a ROM into a RomStr.
"""
if crystal and not red and not filename:
file_handler = open("../baserom.gbc", "r")
@ -62,8 +65,9 @@ class RomStr(str):
return RomStr(bytes)
def load_labels(self, filename="labels.json"):
""" Loads labels from labels.json, or parses the source code file and
generates new labels.
"""
Loads labels from labels.json, or parses the source code file and
generates new labels.
"""
filename = os.path.join(os.path.dirname(__file__), filename)
@ -109,7 +113,8 @@ class RomStr(str):
self.labels = json.read(open(filename, "r").read())
def get_address_for(self, label):
""" Returns the address of a label. This is slow and could be improved
"""
Returns the address of a label. This is slow and could be improved
dramatically.
"""
label = str(label)
@ -119,18 +124,20 @@ class RomStr(str):
return None
def length(self):
""" len(self)
"""
len(self)
"""
return len(self)
def len(self):
""" len(self)
"""
len(self)
"""
return self.length()
def interval(self, offset, length, strings=True, debug=True):
""" returns hex values for the rom starting at offset until
offset+length
"""
returns hex values for the rom starting at offset until offset+length
"""
returnable = []
for byte in self[offset:offset+length]:
@ -141,16 +148,17 @@ class RomStr(str):
return returnable
def until(self, offset, byte, strings=True, debug=False):
""" Returns hex values from rom starting at offset until the given
byte.
"""
Returns hex values from rom starting at offset until the given byte.
"""
return self.interval(offset, self.find(chr(byte), offset) - offset, strings=strings)
def to_asm(self, address, end_address=None, size=None, max_size=0x4000, debug=None):
""" Disassembles ASM at some address. This will stop disassembling when
either the end_address or size is met. Also, there's a maximum size
that will be parsed, so that large patches of data aren't parsed as
code.
"""
Disassembles ASM at some address. This will stop disassembling when
either the end_address or size is met. Also, there's a maximum size
that will be parsed, so that large patches of data aren't parsed as
code.
"""
if type(address) in [str, unicode] and "0x" in address:
address = int(address, 16)
@ -185,16 +193,19 @@ class RomStr(str):
#return DisAsm(start_address=start_address, end_address=end_address, size=size, max_size=max_size, debug=debug, rom=self)
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.
"""
def length(self):
""" len(self)
"""
len(self)
"""
return len(self)
def __repr__(self):
""" Simplifies this object so that the output doesn't overflow stdout.
"""
Simplifies this object so that the output doesn't overflow stdout.
"""
return "AsmList(too long)"

View File

@ -83,7 +83,8 @@ trainer_group_names = {
}
def remove_parentheticals_from_trainer_group_names():
""" Clean up the trainer group names.
"""
Clean up the trainer group names.
"""
i = 0
for (key, value) in trainer_group_names.items():

View File

@ -304,7 +304,8 @@ chars = {
}
def separate_comment(l):
""" Separates asm and comments on a single line.
"""
Separates asm and comments on a single line.
"""
asm = ""
@ -333,7 +334,8 @@ def separate_comment(l):
return asm, comment
def quote_translator(asm):
""" Writes asm with quoted text translated into bytes.
"""
Writes asm with quoted text translated into bytes.
"""
# split by quotes
@ -411,7 +413,8 @@ def make_macro_table():
macro_table = make_macro_table()
def macro_test(asm):
""" Returns a matching macro, or None/False.
"""
Returns a matching macro, or None/False.
"""
# macros are determined by the first symbol on the line
@ -424,7 +427,8 @@ def macro_test(asm):
return (None, None)
def macro_translator(macro, token, line):
""" Converts a line with a macro into a rgbasm-compatible line.
"""
Converts a line with a macro into a rgbasm-compatible line.
"""
assert macro.macro_name == token, "macro/token mismatch"