From cded59d3ca5e754f115ce5cc235f0e2c21f81b8e Mon Sep 17 00:00:00 2001 From: Niki Date: Tue, 15 Apr 2025 17:54:58 +0200 Subject: [PATCH] prepare new commands --- src/tdef/command.c | 40 ++++++++++++++++++--- src/tdef/command.h | 28 +++++++++------ src/tdef/reader.c | 90 ++++++++++++++++++++++++++++++++++++++-------- src/tdef/tdef.c | 17 ++++----- 4 files changed, 138 insertions(+), 37 deletions(-) diff --git a/src/tdef/command.c b/src/tdef/command.c index 2786311..4a249f8 100644 --- a/src/tdef/command.c +++ b/src/tdef/command.c @@ -23,7 +23,7 @@ #include "cutils/cstring.h" #include "command.h" -array_t *read_word(command_t *self, char *line, int pstart, int pstop); +array_t *read_word(command_t *self,const char line[],int pstart,int pstop); command_t *new_command(command_type type) { command_t *self = malloc(sizeof(command_t)); @@ -66,7 +66,37 @@ void uninit_command(command_t *self) { } } -int command_read_str(command_t *self, char *line, int pstart, int pstop) { +int command_read_count(command_t *self, const char line[]) { + int howmany_read = 0; + int in_params = 0; + int escaped = 0; + for (size_t i = 0 ; line[i] ; i++) { + if (!in_params) { + if (line[i] == ':') + in_params = 1; + + continue; + } + + if (line[i] == '"') + escaped = !escaped; + if (escaped) + continue; + + if (line[i] == ',') { + // parameter found + howmany_read++; + } + } + + // Final parameter + if (in_params) + howmany_read++; + + return howmany_read; +} + +int command_read_str(command_t *self,const char line[],int pstart,int pstop) { if (!self->data) self->data = new_array(sizeof(char *), 1); @@ -102,7 +132,7 @@ int command_read_str(command_t *self, char *line, int pstart, int pstop) { return ok; } -int command_read_int(command_t *self, char *line, int pstart, int pstop) { +int command_read_int(command_t *self,const char line[],int pstart,int pstop) { if (!self->data) self->data = new_array(sizeof(char *), 1); @@ -136,7 +166,7 @@ int command_read_int(command_t *self, char *line, int pstart, int pstop) { return ok; } -int command_read_file(command_t *self, char *line, int pstart, int pstop) { +int command_read_file(command_t *self,const char line[],int pstart,int pstop) { if (!self->data) self->data = new_array(sizeof(char *), 1); @@ -177,7 +207,7 @@ int command_read_file(command_t *self, char *line, int pstart, int pstop) { return ok; } -array_t *read_word(command_t *self, char *line, int pstart, int pstop) { +array_t *read_word(command_t *self,const char line[],int pstart,int pstop) { array_t *tmp = new_array(sizeof(char *), 1); int howmany_read = 0; diff --git a/src/tdef/command.h b/src/tdef/command.h index 26bc08e..d290162 100644 --- a/src/tdef/command.h +++ b/src/tdef/command.h @@ -21,13 +21,19 @@ * blablabla */ typedef enum { - TICK, - DISPLAY, - READFILE, - UNKNOWN, - INVALID, - FILE404, - QUIT + COMMAND_TICK, + COMMAND_DISPLAY, + COMMAND_READFILE, + COMMAND_MAP, + COMMAND_LIFE, + COMMAND_BITS, + COMMAND_PATH, + COMMAND_QUIT, + + // error management: + COMMAND_UNKNOWN, + COMMAND_INVALID, + COMMAND_FILE404 } command_type; /** @@ -88,11 +94,13 @@ void uninit_command(command_t *self); // COMMAND:param1,param2,... // pstop 0 -> continue until no more param // white space ignored (trimmed) -int command_read_str(command_t *self, char *line, int pstart, int pstop); +int command_read_count(command_t *self, const char line[]); -int command_read_int(command_t *self, char *line, int pstart, int pstop); +int command_read_str(command_t *self,const char line[],int pstart,int pstop); -int command_read_file(command_t *self, char *line, int pstart, int pstop); +int command_read_int(command_t *self,const char line[],int pstart,int pstop); + +int command_read_file(command_t *self,const char line[],int pstart,int pstop); #endif /* COMMAND_H */ diff --git a/src/tdef/reader.c b/src/tdef/reader.c index 4e6d9d9..d3b2184 100644 --- a/src/tdef/reader.c +++ b/src/tdef/reader.c @@ -23,14 +23,46 @@ #include "cutils/cstring.h" #include "reader.h" +// Commands are given in the form of: +// KEYWORD +// or: +// KEYWORD: [parameters] +// +// Parameters are given in the form of: +// int_parameter1, int_parameter2... +// or: +// "string parameter", "file parameter" +// +// Note that white space around the separators (':' or ',') are allowed. +// +// Known commands: +// > . = will process a tick in the game engine +// > display = will toggle display (debug) mode +// > readfile : "file1..." = will read commands from the given file(s) +// > map : width, height = will setup the map (and reset the path) +// > life : lives = will set the number of life points +// > bits : bit_amount = will set the current bits (money) balance +// > path : x1,y1,x2,y2.. = will setup the enemies path (cumulative) +// > quit = will immediately exit the game // TODO: configuration: -// map size -// path: 1,1;1,2;1,3; -// basic: setMoney, setLife, start... // tower: configTower('1', ...) // enemy: configEnemy('a', ...) +int is_cmd(cstring_t *line, const char cmd[]) { + if (cstring_starts_with(line->string, cmd, 0)) { + int first_non_space = strlen(cmd); + while (line->string[first_non_space] == ' ') + first_non_space++; + + char car = line->string[first_non_space]; + if ((car == ':') || (car == '\0')) + return 1; + } + + return 0; +} + command_t *reader_readnext(FILE *file) { static cstring_t *line = NULL; if (!line) @@ -39,21 +71,51 @@ command_t *reader_readnext(FILE *file) { command_t *cmd = NULL; if (cstring_readline(line, file)) { - cmd = new_command(UNKNOWN); + cmd = new_command(COMMAND_UNKNOWN); - if (!strcmp(".", line->string)) { - cmd->type = TICK; - } else if (cstring_starts_with(line->string, "display", 0)) { - cmd->type = DISPLAY; - } else if (cstring_starts_with(line->string, "readfile", 0)) { - cmd->type = READFILE; + if (is_cmd(line, ".")) { + cmd->type = COMMAND_TICK; + if (command_read_count(cmd, line->string)) + cmd->type = COMMAND_INVALID; + } else if (is_cmd(line, "display")) { + cmd->type = COMMAND_DISPLAY; + if (command_read_count(cmd, line->string)) + cmd->type = COMMAND_INVALID; + } else if (is_cmd(line, "readfile")) { + cmd->type = COMMAND_READFILE; if (!command_read_file(cmd, line->string, 0, -1)) { - cmd->type = INVALID; + cmd->type = COMMAND_INVALID; if (command_read_str(cmd, line->string, 0, -1)) - cmd->type = FILE404; + cmd->type = COMMAND_FILE404; } - } else if (cstring_starts_with("quit", line->string, 0)) { - cmd->type = QUIT; + } else if (is_cmd(line, "map")) { + cmd->type = COMMAND_MAP; + if (!command_read_int(cmd, line->string, 0, 1)) + cmd->type = COMMAND_INVALID; + if (command_read_count(cmd, line->string) > 2) + cmd->type = COMMAND_INVALID; + } else if (is_cmd(line, "life")) { + cmd->type = COMMAND_LIFE; + if (!command_read_int(cmd, line->string, 0, 0)) + cmd->type = COMMAND_INVALID; + if (command_read_count(cmd, line->string) > 2) + cmd->type = COMMAND_INVALID; + } else if (is_cmd(line, "bits")) { + cmd->type = COMMAND_BITS; + if (!command_read_int(cmd, line->string, 0, 0)) + cmd->type = COMMAND_INVALID; + if (command_read_count(cmd, line->string) > 2) + cmd->type = COMMAND_INVALID; + } else if (is_cmd(line, "path")) { + cmd->type = COMMAND_PATH; + if (!command_read_int(cmd, line->string, 0, -1)) + cmd->type = COMMAND_INVALID; + if ((command_read_count(cmd, line->string) % 2) == 1) + cmd->type = COMMAND_INVALID; + } else if (is_cmd(line, "quit")) { + cmd->type = COMMAND_QUIT; + if (command_read_count(cmd, line->string)) + cmd->type = COMMAND_INVALID; } } diff --git a/src/tdef/tdef.c b/src/tdef/tdef.c index 8d7cf14..84c2e22 100644 --- a/src/tdef/tdef.c +++ b/src/tdef/tdef.c @@ -79,13 +79,13 @@ int process_cmd(command_t *cmd, engine_t *engine) { out = new_cstring(); switch(cmd->type) { - case TICK: + case COMMAND_TICK: engine_tick(engine); break; - case DISPLAY: + case COMMAND_DISPLAY: displayMode = !displayMode; break; - case READFILE: + case COMMAND_READFILE: array_loop (cmd->data, ptr, char*) { char *subname = *ptr; FILE *sub = fopen(subname, "r"); @@ -102,19 +102,19 @@ int process_cmd(command_t *cmd, engine_t *engine) { fprintf(stdout, "Done reading: %s\n",subname); } break; - case FILE404: + case COMMAND_FILE404: fprintf(stderr, "Unknown file(s):\n"); array_loop_i (cmd->data, ptr, char*, i) { fprintf(stderr, "%zu. \"%s\"\n", (i+1), *ptr); } break; - case UNKNOWN: + case COMMAND_UNKNOWN: fprintf(stderr, "Unrecognized command\n"); break; - case INVALID: + case COMMAND_INVALID: fprintf(stderr, "Invalid command\n"); break; - case QUIT: + case COMMAND_QUIT: return 0; } @@ -127,7 +127,8 @@ int process_cmd(command_t *cmd, engine_t *engine) { array_clear(engine->events); // display mode - if ((cmd->type == TICK || cmd->type == DISPLAY) && (displayMode)) { + if ((cmd->type == COMMAND_TICK || cmd->type == COMMAND_DISPLAY) + && (displayMode)) { fprintf(stderr, "Tick is: %zu\n", engine->current_tick); display(engine->map); -- 2.27.0