aboutsummaryrefslogtreecommitdiff
path: root/analyzer
diff options
context:
space:
mode:
Diffstat (limited to 'analyzer')
-rw-r--r--analyzer/commands.c99
-rw-r--r--analyzer/commands.h30
2 files changed, 129 insertions, 0 deletions
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();