summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore1
-rw-r--r--shell.nix2
-rw-r--r--symbol_analyzer/extractor.py56
-rw-r--r--symbol_analyzer/main.py26
-rw-r--r--symbol_analyzer/parser.py65
-rw-r--r--symbol_analyzer/symbols.py17
6 files changed, 167 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 104c591..27b960a 100755
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ build
*.o
generated
opt
+__pycache__
diff --git a/shell.nix b/shell.nix
index d6e70f7..7630108 100644
--- a/shell.nix
+++ b/shell.nix
@@ -14,6 +14,8 @@ let
in
pkgs.mkShell {
packages = with pkgs; [
+ python313
+
gcc
glib.dev
pango
diff --git a/symbol_analyzer/extractor.py b/symbol_analyzer/extractor.py
new file mode 100644
index 0000000..0e8694c
--- /dev/null
+++ b/symbol_analyzer/extractor.py
@@ -0,0 +1,56 @@
+def parse_file(file):
+ f = open(file)
+ contents = f.read()
+ f.close()
+
+ significant_token = ""
+ depth = 0
+ tokens = []
+ swallen_tokens = [0, 0]
+ token_buffer = ""
+ define_striping = False
+ for c in contents:
+ if c == " " or c == "{" or c == "}" or \
+ c == ";" or c == ":" or c == "[" or c == "]" or \
+ c == "(" or c == ")" or c == "," or c == "\n" or c == "*":
+
+ if significant_token == "":
+ if c == "{" or c == "}":
+ depth += 1 if c == "{" else -1
+ elif significant_token == "#define":
+ if tokens[-1] == ")":
+ define_striping = True
+ depth = 1
+ if swallen_tokens[-2] != "\\" and swallen_tokens[-1] == "\n":
+ significant_token = ""
+ define_striping = False
+ depth = 0
+ else:
+ depth = 0
+ if swallen_tokens[-1] == ";":
+ significant_token = ""
+
+ if depth == 0:
+ if len(token_buffer) > 0:
+ if token_buffer in ["#define", "enum", "struct"]:
+ significant_token = token_buffer
+ tokens.append(token_buffer)
+ if c != ' ' and len(c) > 0:
+ tokens.append(c)
+ else:
+ if len(token_buffer) > 0:
+ if token_buffer in ["#define", "enum", "struct"]:
+ significant_token = token_buffer
+ swallen_tokens.append(token_buffer)
+ if c != ' ' and len(c) > 0:
+ swallen_tokens.append(c)
+
+ token_buffer = ""
+ continue
+
+ token_buffer += c
+
+ if depth == 0 and len(token_buffer) > 0:
+ tokens.append(token_buffer)
+
+ return tokens, swallen_tokens
diff --git a/symbol_analyzer/main.py b/symbol_analyzer/main.py
new file mode 100644
index 0000000..1fa5457
--- /dev/null
+++ b/symbol_analyzer/main.py
@@ -0,0 +1,26 @@
+import os
+
+from extractor import parse_file
+from parser import parse_definition_tokens
+from symbols import symbols_from_struct_tokens, symbols_from_enum_tokens
+
+symbols = set()
+
+for root, subdirs, files in os.walk("include"):
+ for file in files:
+ file_symbols = ["int", "bool", "char"]
+ definitions, usage = parse_file(root + "/" + file)
+ structs, enums, functions, typedefs = parse_definition_tokens(
+ definitions,
+ file_symbols
+ )
+ file_symbols.extend(symbols_from_struct_tokens(structs))
+ file_symbols.extend(symbols_from_enum_tokens(enums))
+ file_symbols.extend(functions)
+ file_symbols.extend(typedefs)
+ for item in file_symbols:
+ if item.isnumeric():
+ continue
+ symbols.add(item)
+
+print(symbols)
diff --git a/symbol_analyzer/parser.py b/symbol_analyzer/parser.py
new file mode 100644
index 0000000..551857e
--- /dev/null
+++ b/symbol_analyzer/parser.py
@@ -0,0 +1,65 @@
+def parse_definition_tokens(tokens, symbols):
+ typedeffed = False
+ simple_typedefs = []
+ structs = []
+ enums = []
+ functions = []
+
+ i = 0
+ while i < len(tokens):
+ # skip comments
+ if tokens[i] == "//":
+ while tokens[i] != "\n":
+ i += 1
+ i += 1
+ continue
+ if tokens[i] == "typedef":
+ if tokens[i + 1] in symbols:
+ simple_typedefs.append(tokens[i + 2])
+ i += 2
+ if tokens[i] == "struct":
+ i += 1
+ defs = []
+ depth = 0
+ while True:
+ if tokens[i] == "//":
+ while tokens[i] != "\n":
+ i += 1
+ i += 1
+ continue
+ if tokens[i] == ";":
+ if depth == 0:
+ break
+ if tokens[i] == "{":
+ depth += 1
+ if tokens[i] == "}":
+ depth -= 1
+ defs.append(tokens[i])
+ i += 1
+ structs.append(defs)
+ if tokens[i] == "enum":
+ i += 1
+ defs = []
+ depth = 0
+ while True:
+ if tokens[i] == "//":
+ while tokens[i] != "\n":
+ i += 1
+ i += 1
+ continue
+ if tokens[i] == ";":
+ if depth == 0:
+ break
+ if tokens[i] == "{":
+ depth += 1
+ if tokens[i] == "}":
+ depth -= 1
+ defs.append(tokens[i])
+ i += 1
+ enums.append(defs)
+ i += 1
+
+ if tokens[i] == "(":
+ functions.append(tokens[i - 1])
+
+ return structs, enums, functions, simple_typedefs
diff --git a/symbol_analyzer/symbols.py b/symbol_analyzer/symbols.py
new file mode 100644
index 0000000..7384d33
--- /dev/null
+++ b/symbol_analyzer/symbols.py
@@ -0,0 +1,17 @@
+def symbols_from_struct_tokens(tokens):
+ symbols = []
+ for struct in tokens:
+ if struct[0] == "{":
+ symbols.append(struct[-1])
+ else:
+ symbols.append(struct[0])
+ return symbols
+
+def symbols_from_enum_tokens(tokens):
+ symbols = []
+ for enum in tokens:
+ for token in enum:
+ if token == "{" or token == "}" or token == ",":
+ continue
+ symbols.append(token)
+ return symbols