summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjohannes <johannes.herman@gmail.com>2024-02-11 02:00:20 +0100
committerjohannes <johannes.herman@gmail.com>2024-02-11 02:00:20 +0100
commitc2e349569fcf796412b376db89304a19648f18b8 (patch)
treeaeb29720d99f7f42dd2def606ed87193f0ca3d8c /src
parentcb4a7637943d407187184b28d602b750c9547fa5 (diff)
added argument parser and run function
Diffstat (limited to 'src')
-rw-r--r--src/args.c129
-rw-r--r--src/commands.c45
-rw-r--r--src/main.c158
3 files changed, 330 insertions, 2 deletions
diff --git a/src/args.c b/src/args.c
new file mode 100644
index 0000000..9544e39
--- /dev/null
+++ b/src/args.c
@@ -0,0 +1,129 @@
+#include "../inc/args.h"
+#include "../inc/commands.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void parsecmdstr(cmdinput *cmd, char *cmdstr)
+{
+ switch (cmd->settype)
+ {
+ case 'i':
+ if (sscanf(cmdstr, "%i:%23[^\n]", &cmd->id, cmd->to) != 2)
+ {
+ fprintf(stderr, "ERROR: Failed to parse argument '%s' to type 'ID:RESULT'\n", cmdstr);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'n':
+ if (sscanf(cmdstr, "%23[^:]:%23[^\n]", cmd->from, cmd->to) != 2)
+ {
+ fprintf(stderr, "ERROR: Failed to parse argument '%s' to type 'NAME:RESULT'\n", cmdstr);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case '\0':
+ fprintf(stderr, "ERROR: Found no flag modifier\n");
+ exit(EXIT_FAILURE);
+ break;
+ default:
+ fprintf(stderr, "ERROR: Failed to parse flag with '%c' modifier\n", cmd->settype);
+ exit(EXIT_FAILURE);
+ break;
+ }
+}
+
+void parseargs(input *in, int argc, char *argv[])
+{
+ in->demopath = NULL;
+ in->mappath = NULL;
+ in->outpath = NULL;
+ in->print = 0;
+ in->extractmap = 0;
+
+ in->numcmds = 0;
+
+ int argi;
+ for (argi = 1; argi < argc; argi++)
+ {
+ if (argv[argi][0] == '-')
+ {
+ cmdinput *cmd = &in->commands[in->numcmds];
+ switch (argv[argi][1])
+ {
+ case 'n':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'n' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ cmd->cmdtype = argv[argi][1];
+ cmd->settype = argv[argi][2];
+ parsecmdstr(cmd, argv[argi + 1]);
+ in->numcmds++;
+ argi++;
+ break;
+ case 's':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 's' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ cmd->cmdtype = argv[argi][1];
+ cmd->settype = argv[argi][2];
+ parsecmdstr(cmd, argv[argi + 1]);
+ in->numcmds++;
+ argi++;
+ break;
+ case 'o':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'o' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ in->outpath = argv[argi + 1];
+ argi++;
+ break;
+ case 'p':
+ in->print = 1;
+ break;
+ case 'e':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'e' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ in->extractmap = argv[argi + 1];
+ argi++;
+ break;
+ case 'm':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'm' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ in->mappath = argv[argi + 1];
+ argi++;
+ break;
+ default:
+ fprintf(stderr, "ERROR: Unknown flag '%c'\n", argv[argi][1]);
+ exit(EXIT_FAILURE);
+ break;
+ }
+ }
+ else
+ {
+ if (in->demopath)
+ {
+ fprintf(stderr, "ERROR: Found two non-flag arguments\n");
+ exit(EXIT_FAILURE);
+ }
+ in->demopath = argv[argi];
+ }
+ }
+ if (!in->demopath)
+ {
+ fprintf(stderr, "ERROR: Found no demo input\n");
+ exit(EXIT_FAILURE);
+ }
+}
diff --git a/src/commands.c b/src/commands.c
index 599c6d0..e2353d8 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1,5 +1,6 @@
#include "../inc/demo.h"
#include "../inc/pack.h"
+#include "../inc/commands.h"
#include <stdio.h>
#include <stdlib.h>
@@ -122,7 +123,6 @@ int setskinbyname(char *name, char *skin, demo *demo)
char iname[16];
intstostr(item->data, 4, iname);
- printf("comparing: %s : %s\n", name, iname);
if (strcmp(name, iname) == 0)
{
memcpy(&item->data[8], intskin, 5 * sizeof(int));
@@ -142,6 +142,9 @@ int changemap(FILE *map, char *mapname, demo *demo)
fseek(map, 0, SEEK_END);
long mapsize = ftell(map);
fseek(map, 0, SEEK_SET);
+
+ if (mapsize < 4)
+ return -1;
char *mapbuff = (char *)malloc(mapsize);
if (mapbuff == NULL)
@@ -167,3 +170,43 @@ int changemap(FILE *map, char *mapname, demo *demo)
return 1;
}
+
+void runcommand(cmdinput *cmd, demo *demo)
+{
+ switch(cmd->cmdtype)
+ {
+ case 'n':
+ switch(cmd->settype)
+ {
+ case 'i':
+ if (setnamebyid(cmd->id, cmd->to, demo) < 0)
+ printf("WARNING: Could not set name '%s' because it exeeds max limit of 15 characters\n", cmd->to);
+ break;
+ case 'n':
+ if (setnamebyname(cmd->from, cmd->to, demo) < 0)
+ printf("WARNING: Could not set name '%s' because it exeeds max limit of 15 characters\n", cmd->to);
+ break;
+ default:
+ printf("WARNING: Unknown modifier for name\n");
+ }
+ break;
+ case 's':
+ switch(cmd->settype)
+ {
+ case 'i':
+ if (setskinbyid(cmd->id, cmd->to, demo) < 0)
+ printf("WARNING: Could not set skin '%s' because it exeeds max limit of 23 characters\n", cmd->to);
+ break;
+ case 'n':
+ if (setskinbyname(cmd->from, cmd->to, demo) < 0)
+ printf("WARNING: Could not set skin '%s' because it exeeds max limit of 23 characters\n", cmd->to);
+ break;
+ default:
+ printf("WARNING: Unknown modifier for skin\n");
+ }
+ break;
+ default:
+ printf("WARNING: Unknown command type\n");
+ break;
+ }
+}
diff --git a/src/main.c b/src/main.c
index 482bc3c..b344f3d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,7 @@
#include "../inc/commands.h"
#include "../inc/demo.h"
#include "../inc/huffman.h"
+#include "../inc/args.h"
#include <stdio.h>
#include <stdlib.h>
@@ -110,10 +111,165 @@ int testdecompress(char *line)
return 1;
}
-int main()
+int mapname(char *mappath, char *out)
+{
+ int start = 0;
+ int end;
+ int i = 0;
+ while (1)
+ {
+ if (mappath[i] == '/')
+ start = i + 1;
+ if (mappath[i] == '.' || mappath[i] == '\0')
+ {
+ end = i;
+ break;
+ }
+ i++;
+ }
+
+ if ((end - start) > 31)
+ return 0;
+
+ i = 0;
+ while (start != end)
+ {
+ out[i] = mappath[start];
+ start++;
+ i++;
+ }
+ out[i] = '\0';
+ return 1;
+}
+
+void run(input *in)
+{
+ if (!in->demopath)
+ exit(EXIT_FAILURE);
+
+ FILE *demofile, *outfile, *mapfile, *exmapfile;
+ demofile = NULL;
+ outfile = NULL;
+ mapfile = NULL;
+ exmapfile = NULL;
+
+ demofile = fopen(in->demopath, "r");
+ if (!demofile)
+ {
+ perror("ERROR: Failed to open demo file, reason");
+ exit(EXIT_FAILURE);
+ }
+
+ if (in->outpath)
+ {
+ outfile = fopen(in->outpath, "w");
+ if (!outfile)
+ {
+ perror("ERROR: Failed to open output file, reason");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (in->mappath)
+ {
+ mapfile = fopen(in->mappath, "r");
+ if (!mapfile)
+ {
+ perror("ERROR: Failed to open map file, reason");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (in->extractmap)
+ {
+ exmapfile = fopen(in->extractmap, "r");
+ if (!exmapfile)
+ {
+ perror("ERROR: Failed to open extract map file, reason");
+ exit(EXIT_FAILURE);
+ }
+ // TODO extract map here
+ }
+
+ demo dmo;
+
+ if (readdemo(demofile, &dmo) < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to parse demo\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (in->print)
+ printdemo(&dmo, 0);
+
+ if (mapfile)
+ {
+ char mname[32];
+ if (mapname(in->mappath, mname))
+ {
+ if (changemap(mapfile, mname, &dmo) < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to set map '%s'\n", in->mappath);
+ exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Given map has too long name (must be < 32)\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for (int i = 0; i < in->numcmds; i++)
+ {
+ runcommand(&in->commands[i], &dmo);
+ }
+
+ if (outfile)
+ {
+ if (writedemo(outfile, &dmo) < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to write demo to '%s'\n", in->outpath);
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
{
inithuff(NULL);
+ if (argc == 1)
+ {
+ printf("HELP! This should help you.\n");
+ exit(EXIT_SUCCESS);
+ }
+
+ input in;
+
+ parseargs(&in, argc, argv);
+
+ /*
+ printf("demopath: %s\n", in.demopath);
+ printf("outpath: %s\n", in.outpath);
+ printf("mappath: %s\n", in.mappath);
+ printf("extractpath: %s\n", in.extractmap);
+ printf("print: %d\n", in.print);
+
+ printf("\ncommands:\n");
+ for (int i = 0; i < in.numcmds; i++)
+ {
+ cmdinput *c = &in.commands[i];
+ printf("command: {cmd: %c, type: %c, id: %d, from: %s, to: %s}\n", c->cmdtype, c->settype, c->id, c->from, c->to);
+ }
+
+ printf("\nEXITING SUCCESS\n");
+ */
+
+ run(&in);
+
+ exit(EXIT_SUCCESS);
+
// FILE *fp = fopen("/home/johannes/.local/share/ddnet/demos/auto/pepeg_2024-02-09_20-35-38.demo", "r");
FILE *fp = fopen("data/test.demo", "r");
FILE *op = fopen("data/out.demo", "w");