Rev 8961 | Rev 8966 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 8961 | Rev 8963 | ||
---|---|---|---|
Line 2... | Line 2... | ||
2 | import os |
2 | import os |
3 | import argparse |
3 | import argparse |
4 | import sys |
4 | import sys |
Line 5... | Line 5... | ||
5 | 5 | ||
- | 6 | """ TODO: |
|
- | 7 | - Implement function parsing |
|
6 | """ TODO: |
8 | - Check if file was doxygenerated already (only handle changed and not doxygenerated files) |
- | 9 | - Optimize name and var_type checking |
|
- | 10 | - Translate dict in AsmReaderReadingComments into just a set of fields |
|
7 | - Add methods to dump stuff to file |
11 | - Remove get_comment method from AsmReaderReadingComments |
Line 8... | Line 12... | ||
8 | """ |
12 | """ |
9 | 13 | ||
10 | # Parameters |
14 | # Parameters |
Line 1313... | Line 1317... | ||
1313 | self.update_status() |
1317 | self.update_status() |
Line 1314... | Line 1318... | ||
1314 | 1318 | ||
1315 | def get_comment(self): |
1319 | def get_comment(self): |
Line -... | Line 1320... | ||
- | 1320 | return self.comment |
|
- | 1321 | ||
- | 1322 | class AsmReaderFetchingIdentifiers(AsmReaderReadingComments): |
|
- | 1323 | def __init__(self, file): |
|
- | 1324 | super().__init__(file) |
|
- | 1325 | ||
- | 1326 | def fetch_identifier(self): |
|
- | 1327 | self.skip_spaces() |
|
- | 1328 | result = '' |
|
- | 1329 | while is_id(self.curr()): |
|
- | 1330 | result += self.step() |
|
1316 | return self.comment |
1331 | return result |
1317 | 1332 | ||
1318 | class AsmReader(AsmReaderReadingComments): |
1333 | class AsmReader(AsmReaderFetchingIdentifiers): |
Line 1319... | Line 1334... | ||
1319 | def __init__(self, file): |
1334 | def __init__(self, file): |
Line 1393... | Line 1408... | ||
1393 | declaration = f"{var_type} {name};" |
1408 | declaration = f"{var_type} {name};" |
1394 | # Emit this |
1409 | # Emit this |
1395 | super().emit(dest, doxycomment, declaration) |
1410 | super().emit(dest, doxycomment, declaration) |
Line 1396... | Line 1411... | ||
1396 | 1411 | ||
1397 | class AsmFunction(AsmElement): |
1412 | class AsmFunction(AsmElement): |
1398 | def __init__(self, location, name, comment): |
1413 | def __init__(self, location, name, comment, calling_convention, args, used_regs): |
- | 1414 | super().__init__(location, name, comment) |
|
- | 1415 | self.calling_convention = calling_convention |
|
- | 1416 | self.args = args |
|
Line 1399... | Line 1417... | ||
1399 | super().__init__(location, name, comment) |
1417 | self.used_regs = used_regs |
1400 | 1418 | ||
1401 | def dump(self): |
1419 | def dump(self): |
Line 1406... | Line 1424... | ||
1406 | # Build doxycomment specific for the variable |
1424 | # Build doxycomment specific for the variable |
1407 | doxycomment = '' |
1425 | doxycomment = '' |
1408 | doxycomment += self.comment |
1426 | doxycomment += self.comment |
1409 | if '@brief' not in doxycomment: |
1427 | if '@brief' not in doxycomment: |
1410 | doxycomment = '@brief ' + doxycomment |
1428 | doxycomment = '@brief ' + doxycomment |
- | 1429 | # Build the arg list for declaration |
|
- | 1430 | arg_list = '(' |
|
- | 1431 | if len(self.args) > 0: |
|
- | 1432 | argc = 0 |
|
- | 1433 | for arg in self.args: |
|
- | 1434 | if argc != 0: |
|
- | 1435 | arg_list += ", " |
|
- | 1436 | arg_list += f"{arg[1]} {arg[0]}" |
|
- | 1437 | argc += 1 |
|
- | 1438 | arg_list += ')' |
|
1411 | # Build the declaration |
1439 | # Build the declaration |
1412 | name = self.name.replace(".", "_") |
1440 | name = self.name.replace(".", "_") |
1413 | declaration = f"void {name}();" |
1441 | declaration = f"void {name}{arg_list};" |
1414 | # Emit this |
1442 | # Emit this |
1415 | super().emit(dest, doxycomment, declaration) |
1443 | super().emit(dest, doxycomment, declaration) |
Line 1416... | Line 1444... | ||
1416 | 1444 | ||
1417 | class AsmLabel(AsmElement): |
1445 | class AsmLabel(AsmElement): |
Line 1694... | Line 1722... | ||
1694 | if as_union: |
1722 | if as_union: |
1695 | return AsmStruct(location, name, comment, members) |
1723 | return AsmStruct(location, name, comment, members) |
1696 | else: |
1724 | else: |
1697 | return AsmUnion(location, name, comment, members) |
1725 | return AsmUnion(location, name, comment, members) |
Line -... | Line 1726... | ||
- | 1726 | ||
- | 1727 | def parse_after_proc(r): |
|
- | 1728 | # Get proc name |
|
- | 1729 | name = r.fetch_identifier() |
|
- | 1730 | # Next identifier after the proc name |
|
- | 1731 | identifier = r.fetch_identifier() |
|
- | 1732 | # Check if the id is 'stdcall' or 'c' (calling convention specifier) |
|
- | 1733 | # and if so - save the convention and lookup the next identifier |
|
- | 1734 | calling_convention = '' |
|
- | 1735 | if identifier == 'stdcall' or identifier == 'c': |
|
- | 1736 | calling_convention = identifier |
|
- | 1737 | # If next is a comma, just skip it |
|
- | 1738 | if r.curr() == ',': |
|
- | 1739 | r.step() |
|
- | 1740 | # Read the next identifier |
|
- | 1741 | identifier = r.fetch_identifier() |
|
- | 1742 | # Check if the id is 'uses' (used register list specifier) |
|
- | 1743 | # and if so save the used register list |
|
- | 1744 | used_regs = [] |
|
- | 1745 | if identifier == 'uses': |
|
- | 1746 | # Read the registers |
|
- | 1747 | while True: |
|
- | 1748 | reg_name = r.fetch_identifier() |
|
- | 1749 | if reg_name != '': |
|
- | 1750 | used_regs.append(reg_name) |
|
- | 1751 | else: |
|
- | 1752 | break |
|
- | 1753 | # If next is a comma, just skip it |
|
- | 1754 | if r.curr() == ',': |
|
- | 1755 | r.step() |
|
- | 1756 | # Read the next identifier |
|
- | 1757 | identifier = r.fetch_identifier() |
|
- | 1758 | # Check if there are argument identifiers |
|
- | 1759 | args = [] |
|
- | 1760 | while identifier != '': |
|
- | 1761 | arg_name = identifier |
|
- | 1762 | arg_type = 'arg_t' |
|
- | 1763 | # Skip spaces after argument name |
|
- | 1764 | r.skip_spaces() |
|
- | 1765 | # If there's a ':' after the name - the next identifier is type |
|
- | 1766 | if r.curr() == ':': |
|
- | 1767 | r.step() |
|
- | 1768 | arg_type = r.fetch_identifier() |
|
- | 1769 | # If there's a comma - there's one more argument |
|
- | 1770 | # else no arguments anymore |
|
- | 1771 | if r.curr() == ',': |
|
- | 1772 | r.step() |
|
- | 1773 | identifier = r.fetch_identifier() |
|
- | 1774 | else: |
|
- | 1775 | identifier = '' |
|
- | 1776 | args.append((arg_name, arg_type)) |
|
- | 1777 | # Get to the end of the line and get a comment from the reader |
|
- | 1778 | while r.curr() != '': |
|
- | 1779 | r.step() |
|
- | 1780 | comment = r.get_comment() |
|
- | 1781 | # Build the element |
|
- | 1782 | return AsmFunction(r.location(), name, comment, calling_convention, args, used_regs) |
|
1698 | 1783 | ||
1699 | def get_declarations(asm_file_contents, asm_file_name): |
1784 | def get_declarations(asm_file_contents, asm_file_name): |
1700 | cwd = os.path.abspath(os.path.dirname(sys.argv[0])) |
1785 | cwd = os.path.abspath(os.path.dirname(sys.argv[0])) |
1701 | asm_file_name = os.path.realpath(asm_file_name) |
1786 | asm_file_name = os.path.realpath(asm_file_name) |
Line 1724... | Line 1809... | ||
1724 | struct = parse_after_struct(r) |
1809 | struct = parse_after_struct(r) |
1725 | elements.append(struct) |
1810 | elements.append(struct) |
1726 | struct_names.append(struct.name) |
1811 | struct_names.append(struct.name) |
1727 | # Match function definition |
1812 | # Match function definition |
1728 | elif first_word == "proc": |
1813 | elif first_word == "proc": |
1729 | # Skip spaces after "proc" |
1814 | proc = parse_after_proc(r) |
1730 | r.skip_spaces() |
- | |
1731 | # Get proc name |
- | |
1732 | name = "" |
- | |
1733 | while is_id(r.curr()): |
- | |
1734 | name += r.step() |
- | |
1735 | # Get to the end of the line to get the comment from the reader |
- | |
1736 | while r.curr() != '': |
- | |
1737 | r.step() |
- | |
1738 | comment = r.get_comment() |
1815 | elements.append(proc) |
1739 | # Create the function |
- | |
1740 | elements.append(AsmFunction(r.location(), name, comment)) |
- | |
1741 | elif first_word == 'format': |
1816 | elif first_word == 'format': |
1742 | # Skip the format directive |
1817 | # Skip the format directive |
1743 | pass |
1818 | pass |
1744 | elif first_word == 'include': |
1819 | elif first_word == 'include': |
1745 | # Skip the include directive |
1820 | # Skip the include directive |