Rev 8975 | Rev 8977 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 8975 | Rev 8976 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | import re |
1 | import re |
2 | import os |
2 | import os |
3 | import argparse |
3 | import argparse |
4 | import sys |
4 | import sys |
Line 5... | Line -... | ||
5 | - | ||
6 | """ TODO: |
- | |
7 | - Optimize name and var_type checking |
- | |
8 | """ |
- | |
9 | 5 | ||
10 | # Parameters |
6 | # Parameters |
11 | # Path to doxygen folder to make doxygen files in: -o |
7 | # Path to doxygen folder to make doxygen files in: -o |
12 | doxygen_src_path = 'docs/doxygen' |
8 | doxygen_src_path = 'docs/doxygen' |
13 | # Remove generated doxygen files: --clean |
9 | # Remove generated doxygen files: --clean |
Line 1152... | Line 1148... | ||
1152 | "dq", "rq", |
1148 | "dq", "rq", |
1153 | "dt", "rt", |
1149 | "dt", "rt", |
1154 | "du", |
1150 | "du", |
1155 | ] |
1151 | ] |
Line -... | Line 1152... | ||
- | 1152 | ||
- | 1153 | # Dict where an identifier is assicoated with a string |
|
- | 1154 | # The string contains characters specifying flags |
|
- | 1155 | # Available flags: |
|
- | 1156 | # k - Keyword |
|
- | 1157 | # m - Macro name |
|
- | 1158 | # t - fasm data Type name (db, rq, etc.) |
|
- | 1159 | # s - Struct type name |
|
- | 1160 | # e - equated constant (name equ value) |
|
- | 1161 | # = - set constants (name = value) |
|
- | 1162 | ID_KIND_KEYWORD = 'k' |
|
- | 1163 | ID_KIND_MACRO_NAME = 'm' |
|
- | 1164 | ID_KIND_FASM_TYPE = 't' |
|
- | 1165 | ID_KIND_STRUCT_NAME = 's' |
|
- | 1166 | ID_KIND_EQUATED_CONSTANT = 'e' |
|
- | 1167 | ID_KIND_SET_CONSTANT = '=' |
|
- | 1168 | id2kind = {} |
|
- | 1169 | ||
- | 1170 | # Add kind flag to identifier in id2kind |
|
- | 1171 | def id_add_kind(identifier, kind): |
|
- | 1172 | if identifier not in id2kind: |
|
- | 1173 | id2kind[identifier] = '' |
|
- | 1174 | id2kind[identifier] += kind |
|
- | 1175 | ||
- | 1176 | # Remove kind flag of identifier in id2kind |
|
- | 1177 | def id_remove_kind(identifier, kind): |
|
- | 1178 | if identifier in id2kind: |
|
- | 1179 | if kind in id2kind[identifier]: |
|
- | 1180 | id2kind[identifier] = id2kind[identifier].replace(kind, '') |
|
- | 1181 | ||
- | 1182 | # Get kind of an identifier |
|
- | 1183 | def id_get_kind(identifier): |
|
- | 1184 | if identifier in id2kind: |
|
- | 1185 | return id2kind[identifier] |
|
- | 1186 | else: |
|
- | 1187 | return '' |
|
- | 1188 | ||
- | 1189 | for keyword in keywords: |
|
- | 1190 | id_add_kind(keyword, ID_KIND_KEYWORD) |
|
- | 1191 | ||
- | 1192 | for fasm_type in fasm_types: |
|
- | 1193 | id_add_kind(fasm_type, ID_KIND_FASM_TYPE) |
|
1156 | 1194 | ||
1157 | # Warning list |
1195 | # Warning list |
Line 1158... | Line 1196... | ||
1158 | warnings = "" |
1196 | warnings = "" |
1159 | 1197 | ||
1160 | # Parse arguments |
1198 | # Parse arguments |
1161 | parser = argparse.ArgumentParser() |
1199 | parser = argparse.ArgumentParser() |
1162 | parser.add_argument("-o", help="Doxygen output folder") |
1200 | parser.add_argument("-o", help="Doxygen output folder") |
1163 | parser.add_argument("--clean", help="Remove generated files", action="store_true") |
1201 | parser.add_argument("--clean", help="Remove generated files", action="store_true") |
1164 | parser.add_argument("--dump", help="Dump all defined symbols", action="store_true") |
1202 | parser.add_argument("--dump", help="Dump all defined symbols", action="store_true") |
- | 1203 | parser.add_argument("--stats", help="Print symbol stats", action="store_true") |
|
1165 | parser.add_argument("--stats", help="Print symbol stats", action="store_true") |
1204 | parser.add_argument("--nowarn", help="Do not write warnings file", action="store_true") |
1166 | parser.add_argument("--nowarn", help="Do not write warnings file", action="store_true") |
1205 | parser.add_argument("--noemit", help="Do not emit doxygen files (for testing)", action="store_true") |
1167 | args = parser.parse_args() |
1206 | args = parser.parse_args() |
1168 | doxygen_src_path = args.o if args.o else 'docs/doxygen' |
1207 | doxygen_src_path = args.o if args.o else 'docs/doxygen' |
1169 | clean_generated_stuff = args.clean |
1208 | clean_generated_stuff = args.clean |
1170 | dump_symbols = args.dump |
1209 | dump_symbols = args.dump |
- | 1210 | print_stats = args.stats |
|
Line 1171... | Line 1211... | ||
1171 | print_stats = args.stats |
1211 | enable_warnings = not args.nowarn |
1172 | enable_warnings = not args.nowarn |
1212 | noemit = args.noemit |
1173 | - | ||
1174 | # Variables, functions, labels, macros, structure types |
- | |
1175 | elements = [] |
- | |
1176 | # Names of macroses |
- | |
1177 | macro_names = [] |
- | |
1178 | # Names of structs |
- | |
1179 | struct_names = [] |
- | |
1180 | # Equated constant names (name = value) |
- | |
Line 1181... | Line 1213... | ||
1181 | equated_constant_names = [] |
1213 | |
1182 | # Literally equated constant names (name equ value) |
1214 | # Variables, functions, labels, macros, structure types |
1183 | equ_names = [] |
1215 | elements = [] |
1184 | 1216 | ||
Line 1619... | Line 1651... | ||
1619 | if len(name) == 0: |
1651 | if len(name) == 0: |
1620 | return None |
1652 | return None |
1621 | # If it starts from digit or othervice illegally it's illegal |
1653 | # If it starts from digit or othervice illegally it's illegal |
1622 | if not is_starts_as_id(name): |
1654 | if not is_starts_as_id(name): |
1623 | return None |
1655 | return None |
- | 1656 | # Get kind of the identifier from id2kind table |
|
- | 1657 | kind = id_get_kind(name) |
|
1624 | # If it's a keyword, that's not a variable declaration |
1658 | # If it's a keyword, that's not a variable declaration |
1625 | if name in keywords: |
1659 | if ID_KIND_KEYWORD in kind: |
1626 | return None |
1660 | return None |
1627 | # If it's a macro name, that's not a variable declaration |
1661 | # If it's a macro name, that's not a variable declaration |
1628 | if name in macro_names: |
1662 | if ID_KIND_MACRO_NAME in kind: |
1629 | return VariableNameIsMacroName(name) |
1663 | return VariableNameIsMacroName(name) |
1630 | # If it's a datatype or a structure name that's not a variable declaration: that's just a data |
1664 | # If it's a datatype or a structure name that's not a variable declaration: that's just a data |
1631 | # don't document just a data for now |
1665 | # don't document just a data for now |
1632 | if name in struct_names or name in fasm_types: |
1666 | if ID_KIND_STRUCT_NAME in kind or ID_KIND_FASM_TYPE in kind: |
1633 | return None |
1667 | return None |
1634 | # Skip spaces before type name |
1668 | # Skip spaces before type name |
1635 | r.skip_spaces() |
1669 | r.skip_spaces() |
1636 | # Read type name |
1670 | # Read type name |
1637 | var_type = "" |
1671 | var_type = "" |
Line 1644... | Line 1678... | ||
1644 | # return it |
1678 | # return it |
1645 | return name |
1679 | return name |
1646 | # If it starts from digit or othervice illegally it's illegal |
1680 | # If it starts from digit or othervice illegally it's illegal |
1647 | if not is_starts_as_id(var_type): |
1681 | if not is_starts_as_id(var_type): |
1648 | return None |
1682 | return None |
- | 1683 | # Get kind of type identifier |
|
- | 1684 | type_kind = id_get_kind(var_type) |
|
1649 | # If it's a keyword, that's not a variable declaration |
1685 | # If it's a keyword, that's not a variable declaration |
1650 | # return the two words of the lexical structure |
1686 | # return the two words of the lexical structure |
1651 | if var_type in keywords: |
1687 | if ID_KIND_KEYWORD in type_kind: |
1652 | return (name, var_type) |
1688 | return (name, var_type) |
1653 | # Skip spaces before the value |
1689 | # Skip spaces before the value |
1654 | r.skip_spaces() |
1690 | r.skip_spaces() |
1655 | # Read the value until the comment or end of the line |
1691 | # Read the value until the comment or end of the line |
1656 | value = "" |
1692 | value = "" |
Line 1781... | Line 1817... | ||
1781 | first_word += r.step() |
1817 | first_word += r.step() |
1782 | # Match macro declaration |
1818 | # Match macro declaration |
1783 | if first_word == "macro": |
1819 | if first_word == "macro": |
1784 | macro = parse_after_macro(r) |
1820 | macro = parse_after_macro(r) |
1785 | elements.append(macro) |
1821 | elements.append(macro) |
1786 | macro_names.append(macro.name) |
1822 | id_add_kind(macro.name, ID_KIND_MACRO_NAME) |
1787 | # Match structure declaration |
1823 | # Match structure declaration |
1788 | elif first_word == "struct": |
1824 | elif first_word == "struct": |
1789 | struct = parse_after_struct(r) |
1825 | struct = parse_after_struct(r) |
1790 | elements.append(struct) |
1826 | elements.append(struct) |
1791 | struct_names.append(struct.name) |
1827 | id_add_kind(struct.name, ID_KIND_STRUCT_NAME) |
1792 | # Match function definition |
1828 | # Match function definition |
1793 | elif first_word == "proc": |
1829 | elif first_word == "proc": |
1794 | proc = parse_after_proc(r) |
1830 | proc = parse_after_proc(r) |
1795 | elements.append(proc) |
1831 | elements.append(proc) |
1796 | elif first_word == 'format': |
1832 | elif first_word == 'format': |
Line 1813... | Line 1849... | ||
1813 | name = '' |
1849 | name = '' |
1814 | while is_id(r.curr()): |
1850 | while is_id(r.curr()): |
1815 | name += r.step() |
1851 | name += r.step() |
1816 | # Remove the purged macro from the macro names list |
1852 | # Remove the purged macro from the macro names list |
1817 | try: |
1853 | try: |
1818 | macro_names.remove(name) |
1854 | id_remove_kind(name, ID_KIND_MACRO_NAME) |
1819 | except: |
1855 | except: |
1820 | pass |
1856 | pass |
1821 | # Skip spaces after the name |
1857 | # Skip spaces after the name |
1822 | r.skip_spaces() |
1858 | r.skip_spaces() |
1823 | # If it's comma (',') after then that's not the last purged macro, continue purging |
1859 | # If it's comma (',') after then that's not the last purged macro, continue purging |
Line 1849... | Line 1885... | ||
1849 | comment = r.comment |
1885 | comment = r.comment |
1850 | # Only handle non-local labels |
1886 | # Only handle non-local labels |
1851 | if name[0] != '.' and name != "@@" and name != "$Revision": |
1887 | if name[0] != '.' and name != "@@" and name != "$Revision": |
1852 | elements.append(AsmLabel(r.location(), name, comment)) |
1888 | elements.append(AsmLabel(r.location(), name, comment)) |
1853 | elif r.curr() == '=': |
1889 | elif r.curr() == '=': |
1854 | # Add the equated constant (name = value) to equated constants list |
1890 | # Save the identifier as a set constant |
1855 | equated_constant_names.append(first_word) |
1891 | id_add_kind(first_word, ID_KIND_SET_CONSTANT) |
1856 | elif type(var) == tuple: |
1892 | elif type(var) == tuple: |
1857 | (word_one, word_two) = var |
1893 | (word_one, word_two) = var |
1858 | if word_two == 'equ': |
1894 | if word_two == 'equ': |
1859 | # Add the name to equ names list |
1895 | # Save the identifier as an equated constant |
1860 | equ_names.append(word_one) |
1896 | id_add_kind(word_one, ID_KIND_EQUATED_CONSTANT) |
1861 | r.nextline() |
1897 | r.nextline() |
Line 1862... | Line 1898... | ||
1862 | 1898 | ||
1863 | def it_neds_to_be_parsed(source_file): |
1899 | def it_neds_to_be_parsed(source_file): |
1864 | dest = doxygen_src_path + '/' + source_file |
1900 | dest = doxygen_src_path + '/' + source_file |
Line 1927... | Line 1963... | ||
1927 | doxygen_file = f"{doxygen_src_path}/{file}" |
1963 | doxygen_file = f"{doxygen_src_path}/{file}" |
1928 | if (os.path.isfile(doxygen_file)): |
1964 | if (os.path.isfile(doxygen_file)): |
1929 | print(f"Removing {file}... ", end = '') |
1965 | print(f"Removing {file}... ", end = '') |
1930 | os.remove(doxygen_file) |
1966 | os.remove(doxygen_file) |
1931 | print("Done.") |
1967 | print("Done.") |
1932 | else: |
1968 | elif not noemit: |
1933 | print(f"Writing doumented sources to {doxygen_src_path}") |
1969 | print(f"Writing doumented sources to {doxygen_src_path}") |
Line 1934... | Line 1970... | ||
1934 | 1970 | ||
1935 | i = 0 |
1971 | i = 0 |
1936 | for element in elements: |
1972 | for element in elements: |