diff options
| author | johannes <johannes.herman@gmail.com> | 2024-02-11 02:00:20 +0100 |
|---|---|---|
| committer | johannes <johannes.herman@gmail.com> | 2024-02-11 02:00:20 +0100 |
| commit | c2e349569fcf796412b376db89304a19648f18b8 (patch) | |
| tree | aeb29720d99f7f42dd2def606ed87193f0ca3d8c | |
| parent | cb4a7637943d407187184b28d602b750c9547fa5 (diff) | |
added argument parser and run function
| -rw-r--r-- | inc/args.h | 22 | ||||
| -rw-r--r-- | inc/commands.h | 11 | ||||
| -rw-r--r-- | src/args.c | 129 | ||||
| -rw-r--r-- | src/commands.c | 45 | ||||
| -rw-r--r-- | src/main.c | 158 |
5 files changed, 363 insertions, 2 deletions
diff --git a/inc/args.h b/inc/args.h new file mode 100644 index 0000000..6c06fb2 --- /dev/null +++ b/inc/args.h @@ -0,0 +1,22 @@ +#ifndef ARGS_H +#define ARGS_H + +#include "../inc/commands.h" + +#define MAX_COMMANDS 64 + +typedef struct +{ + char *demopath; + char *mappath; + char *outpath; + char *extractmap; + char print; + + int numcmds; + cmdinput commands[MAX_COMMANDS]; +} input; + +void parseargs(input *in, int argc, char *argv[]); + +#endif // ARGS_H diff --git a/inc/commands.h b/inc/commands.h index 654d8b7..9761151 100644 --- a/inc/commands.h +++ b/inc/commands.h @@ -3,6 +3,15 @@ #include "demo.h" +typedef struct +{ + char cmdtype; + char settype; + int id; + char from[24]; + char to[24]; +} cmdinput; + int setnamebyid(int id, char *newname, demo *demo); int setnamebyname(char *oldname, char *newname, demo *demo); @@ -14,4 +23,6 @@ int setskinbyname(char *name, char *skin, demo *demo); /* Will fail if mapname >= 31, or map is not a teeworlds datafile */ int changemap(FILE *map, char *mapname, demo *demo); +void runcommand(cmdinput *cmd, demo *demo); + #endif // COMMANDS_H 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; + } +} @@ -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"); |
