diff options
| author | Mosder <xmosder12@gmail.com> | 2026-07-23 13:59:15 +0200 |
|---|---|---|
| committer | Mosder <xmosder12@gmail.com> | 2026-07-23 13:59:15 +0200 |
| commit | 05da5ef05778d0653685a20e9e5847b221a54f59 (patch) | |
| tree | 862c8534959fadb9a69278ea95bd4eeced0af4e8 | |
| parent | 196a30821dd1d3459807ed7ad1f45ceda1fa5585 (diff) | |
refactor: generalized command parsing and moved it into a separate file
| -rw-r--r-- | Makefile | 28 | ||||
| -rw-r--r-- | analyzer/commands.c | 99 | ||||
| -rw-r--r-- | analyzer/commands.h | 30 | ||||
| -rw-r--r-- | csv_table_gen.c (renamed from csv_to_headers.c) | 2 | ||||
| -rw-r--r-- | main.c | 56 |
5 files changed, 151 insertions, 64 deletions
@@ -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); @@ -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; } |
