aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMosder <xmosder12@gmail.com>2026-07-23 13:59:15 +0200
committerMosder <xmosder12@gmail.com>2026-07-23 13:59:15 +0200
commit05da5ef05778d0653685a20e9e5847b221a54f59 (patch)
tree862c8534959fadb9a69278ea95bd4eeced0af4e8
parent196a30821dd1d3459807ed7ad1f45ceda1fa5585 (diff)
refactor: generalized command parsing and moved it into a separate file
-rw-r--r--Makefile28
-rw-r--r--analyzer/commands.c99
-rw-r--r--analyzer/commands.h30
-rw-r--r--csv_table_gen.c (renamed from csv_to_headers.c)2
-rw-r--r--main.c56
5 files changed, 151 insertions, 64 deletions
diff --git a/Makefile b/Makefile
index 31c1275..fa3a294 100644
--- a/Makefile
+++ b/Makefile
@@ -10,16 +10,22 @@ local: compile
debug: CFLAGS=-iquote ./analyzer -Og -g
debug: global
-compile: csv structures utils parser capture analyzer render
+compile: csv_table_gen main_files structures utils parser
$(CC) $(CFLAGS) -lpcap *.o main.c -o branal
rm *.o
-csv:
- $(CC) $(CFLAGS) csv_to_headers.c -o csv_to_headers
- ./csv_to_headers
- rm csv_to_headers
+csv_table_gen:
+ $(CC) $(CFLAGS) csv_table_gen.c -o csv_table_gen
+ ./csv_table_gen
+ rm csv_table_gen
$(CC) $(CFLAGS) -c analyzer/csv/*.c
+main_files:
+ $(CC) $(CFLAGS) -c analyzer/commands.c
+ $(CC) $(CFLAGS) -c analyzer/capture.c
+ $(CC) $(CFLAGS) -c analyzer/analyzer.c
+ $(CC) $(CFLAGS) -c analyzer/render.c
+
structures:
$(CC) $(CFLAGS) -c analyzer/structures/hashmap.c
$(CC) $(CFLAGS) -c analyzer/structures/heap.c
@@ -35,15 +41,3 @@ parser:
$(CC) $(CFLAGS) -c analyzer/parser/parser.c
$(CC) $(CFLAGS) -c analyzer/parser/structs.c
$(CC) $(CFLAGS) -c analyzer/parser/fight_results/fight_results.c
-
-capture:
- $(CC) $(CFLAGS) -c analyzer/capture.c
-
-analyzer:
- $(CC) $(CFLAGS) -c analyzer/analyzer.c
-
-render:
- $(CC) $(CFLAGS) -c analyzer/render.c
-
-.PHONY: analyzer
-.PHONY: csv
diff --git a/analyzer/commands.c b/analyzer/commands.c
new file mode 100644
index 0000000..cb3cdea
--- /dev/null
+++ b/analyzer/commands.c
@@ -0,0 +1,99 @@
+#include "commands.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "analyzer.h"
+#include "capture.h"
+#include "utils/memory.h"
+
+#define PROGRAM_NAME "branal"
+#define INDENT " "
+#define MAX_COMMAND_LENGTH 100
+
+// calculate the longest command length to align explenations
+int longest_command_length() {
+ int longest_len = 0;
+ for (size_t i = 0; i < commands_count; i++) {
+ Command cmd = commands[i];
+ int len = strlen(PROGRAM_NAME);
+ len += strlen(" ( | ) ");
+ len += strlen(cmd.short_name) + strlen(cmd.name);
+ len += strlen(cmd.args_str) == 0 ? 0 : strlen(cmd.args_str) + 1;
+ if (len > longest_len)
+ longest_len = len;
+ }
+ return longest_len;
+}
+
+// help command handler
+int print_help(int argc, char *argv[]) {
+ int len = longest_command_length();
+
+ printf("A bare-bones analyzer for the game Broken Ranks\n");
+ printf("\nUsage:\n");
+ printf(INDENT "%-*s- same as below\n", len, PROGRAM_NAME);
+
+ for (size_t i = 0; i < commands_count; i++) {
+ Command cmd = commands[i];
+
+ char buffer[MAX_COMMAND_LENGTH];
+ sprintf(buffer, PROGRAM_NAME " (%s | %s) ", cmd.short_name, cmd.name);
+ if (strlen(cmd.args_str))
+ strcat(buffer, cmd.args_str);
+
+ printf(INDENT "%-*s- %s\n", len, buffer, cmd.explanation[0]);
+ for (size_t j = 1; j < cmd.explanation_lines; j++) {
+ printf(INDENT "%*s%s\n", len + 2, "", cmd.explanation[j]);
+ }
+ }
+
+ return 0;
+}
+
+// live analyzer command handler
+int live_anal(int argc, char *argv[]) {
+ // TODO: implement
+ printf("Not implemented\n");
+ return 1;
+}
+
+// capturing mode command handler
+int capture(int argc, char *argv[]) {
+ capturing_mode(argc >= 3 ? argv[2] : NULL);
+ return 0;
+}
+
+// file analysis command handler
+int file_anal(int argc, char *argv[]) {
+ if (argc < 3) {
+ printf("You need to provide a file (or files) to analyze");
+ return 1;
+ }
+
+ for (size_t i = 2; i < argc; i++) {
+ printf("FILE: %s\n", argv[i]);
+ analyze_file(argv[i]);
+ printf("\n");
+ }
+
+ return 0;
+}
+
+const Command help_command = {"help", "h", "", {"display this help"}, 1, print_help};
+const Command commands[] = {
+ {"live", "l", "", {"start live analysis"}, 1, live_anal},
+ {"capture", "c", "[file]", {"start capturing packers to file", "If file isn't provided - captures to: $HOME/.local/share/branal/captures"}, 2, capture},
+ {"file", "f", "<file...>", {"analyze the specified file(s)"}, 1, file_anal},
+ help_command
+};
+const size_t commands_count = ARR_LEN(commands);
+
+int is_command(Command command, char *str) {
+ return !strcmp(command.short_name, str) || !strcmp(command.name, str);
+}
+
+void command_not_recognized() {
+ printf("Command not recognized\n");
+ printf("Use \"%s (%s | %s)\" for help\n", PROGRAM_NAME, help_command.short_name, help_command.name);
+}
diff --git a/analyzer/commands.h b/analyzer/commands.h
new file mode 100644
index 0000000..f53a140
--- /dev/null
+++ b/analyzer/commands.h
@@ -0,0 +1,30 @@
+// commands.h
+// commands to use in the program
+
+#include <stddef.h>
+
+#define MAX_EXPLANATION_LINES 3
+
+typedef struct {
+ char *name;
+ char *short_name;
+ char *args_str;
+ char *explanation[MAX_EXPLANATION_LINES];
+ size_t explanation_lines;
+ int (*handler)(int argc, char *argv[]);
+} Command;
+
+// all commands of the program
+extern const Command commands[];
+extern const size_t commands_count;
+
+// check if the given command is represented by the given string
+// params:
+// - command - potentailly represented command
+// - str - potentially representing string
+// returns:
+// 1 if command is represneted by string, 0 if not
+extern int is_command(Command command, char *str);
+
+// print information about help when program didn't recognize command
+extern void command_not_recognized();
diff --git a/csv_to_headers.c b/csv_table_gen.c
index 51a1c58..9be57d0 100644
--- a/csv_to_headers.c
+++ b/csv_table_gen.c
@@ -112,7 +112,7 @@ int main() {
char *file_name = entry->d_name;
size_t file_name_len = strlen(file_name);
// create lookup tables for each *.csv file
- if (file_name_len > EXT_LEN && strcmp(file_name + file_name_len - EXT_LEN, EXT) == 0)
+ if (file_name_len > EXT_LEN && !strcmp(file_name + file_name_len - EXT_LEN, EXT))
create_table(entry->d_name);
}
closedir(csv_dir);
diff --git a/main.c b/main.c
index eadb516..38dfc36 100644
--- a/main.c
+++ b/main.c
@@ -1,54 +1,18 @@
-#include <stdio.h>
-#include <string.h>
-
-#include "analyzer/analyzer.h"
-#include "analyzer/capture.h"
-#include "analyzer/utils/fs.h"
-
-// prints help
-void print_help() {
- printf("A bare-bones analyzer for the game Broken Ranks\n");
- printf("\nUsage:\n");
- printf(" branal - start live analysis\n");
- printf(" branal (l | live) - start live analysis (same as above)\n");
- printf(" branal (c | capture) [file] - start capturing packets to [file].\n");
- printf(" If [file] not given - captures to $HOME/.local/share/branal/captures\n");
- printf(" branal (f | file) <file> - analyze the specified <file>\n");
- printf(" branal (h | help) - display this help\n");
-}
-
-// starts live analyzer mode
-void start_live_analyzer() {
- // TODO: implement
- printf("Not implemented\n");
-}
+#include "commands.h"
+#include "utils/fs.h"
int main(int argc, char *argv[]) {
create_necessary_directories();
- // start live analysis if no arguments provided
- if (argc < 2) {
- start_live_analyzer();
- return 0;
- }
+ // start first command if no arguments provided
+ if (argc < 2)
+ return commands[0].handler(argc, argv);
- if (strcmp("l", argv[1]) == 0 || strcmp("live", argv[1]) == 0) {
- start_live_analyzer();
- }
- else if (strcmp("c", argv[1]) == 0 || strcmp("capture", argv[1]) == 0) {
- capturing_mode(argc >= 3 ? argv[2] : NULL);
- }
- else if (strcmp("h", argv[1]) == 0 || strcmp("help", argv[1]) == 0) {
- print_help();
- }
- else if (argc >= 3 && (strcmp("f", argv[1]) == 0 || strcmp("file", argv[1]) == 0)) {
- analyze_file(argv[2]);
- }
- else {
- printf("Command not recognized\n");
- printf("Use \"branal (h | help)\" for help\n");
- return 1;
+ for (size_t i = 0; i < commands_count; i++) {
+ if (is_command(commands[i], argv[1]))
+ return commands[i].handler(argc, argv);
}
- return 0;
+ command_not_recognized();
+ return 1;
}