From: Niki Date: Fri, 11 Apr 2025 22:58:33 +0000 (+0200) Subject: new: readfile X-Git-Url: http://git.nikiroo.be/?a=commitdiff_plain;h=8132f70bb2660b9bf6207f8d362849db91a6931f;p=tdef.git new: readfile --- diff --git a/src/tdef/command.c b/src/tdef/command.c index 593a474..2786311 100644 --- a/src/tdef/command.c +++ b/src/tdef/command.c @@ -23,6 +23,7 @@ #include "cutils/cstring.h" #include "command.h" +array_t *read_word(command_t *self, char *line, int pstart, int pstop); command_t *new_command(command_type type) { command_t *self = malloc(sizeof(command_t)); @@ -41,6 +42,7 @@ int init_command(command_t *self, command_type type) { self->CNAME[sz - 1] = '\0'; self->type = type; + self->data = NULL; return 1; } @@ -54,5 +56,190 @@ void free_command(command_t *self) { void uninit_command(command_t *self) { self->CNAME[0] = '!'; + + if (self->data) { + array_loop (self->data, ptr, char*) { + free(*ptr); + } + + free_array(self->data); + } +} + +int command_read_str(command_t *self, char *line, int pstart, int pstop) { + if (!self->data) + self->data = new_array(sizeof(char *), 1); + + array_t *tmp = read_word(self, line, pstart, pstop); + if (!tmp) + return 0; + + int before = self->data->count; + int ok = 1; + array_loop (tmp, ptr, char*) { + char *str = *ptr; + size_t sz = (!str) ? 0 : strlen(str); + if (!str || str[0] != '"' || str[sz-1] != '"') { + ok = 0; + break; + } + + cstring_t *noquotes = new_cstring(); + cstring_addfn(noquotes, str, 1, sz-2); + + char **newptr = array_new(self->data); + *newptr = cstring_convert(noquotes); + free(*ptr); + *ptr = NULL; + } + + free_array(tmp); + + if (!ok) { + array_cut_at(self->data, before); + } + + return ok; +} + +int command_read_int(command_t *self, char *line, int pstart, int pstop) { + if (!self->data) + self->data = new_array(sizeof(char *), 1); + + array_t *tmp = read_word(self, line, pstart, pstop); + if (!tmp) + return 0; + + int before = self->data->count; + int ok = 1; + array_loop (tmp, ptr, char*) { + char *str = *ptr; + + for (size_t i = 0 ; str[i] ; i++) { + if (str[i] < '0' || str[i] > '9') { + ok = 0; + break; + } + } + + char **newptr = array_new(self->data); + *newptr = *ptr; + *ptr = NULL; + } + + free_array(tmp); + + if (!ok) { + array_cut_at(self->data, before); + } + + return ok; +} + +int command_read_file(command_t *self, char *line, int pstart, int pstop) { + if (!self->data) + self->data = new_array(sizeof(char *), 1); + + array_t *tmp = self->data; + self->data = new_array(sizeof(char *), 1); + if (!command_read_str(self, line, pstart, pstop)) { + free_array(self->data); + self->data = tmp; + return 0; + } + + array_t *swp = self->data; + self->data = tmp; + tmp = swp; + + int before = self->data->count; + int ok = 1; + array_loop (tmp, ptr, char*) { + char *filename = *ptr; + FILE *testopen = fopen(filename, "r"); + if (!testopen) { + ok = 0; + break; + } + + fclose(testopen); + char **newptr = array_new(self->data); + *newptr = *ptr; + *ptr = NULL; + } + + free_array(tmp); + + if (!ok) { + array_cut_at(self->data, before); + } + + return ok; +} + +array_t *read_word(command_t *self, char *line, int pstart, int pstop) { + array_t *tmp = new_array(sizeof(char *), 1); + + int howmany_read = 0; + int in_params = 0; + int escaped = 0; + int start = 0; + int stop = -1; + for (size_t i = 0 ; line[i] ; i++) { + if (!in_params) { + if (line[i] == ':') { + in_params = 1; + start = (i + 1); + } + + continue; + } + + if (line[i] == '"') + escaped = !escaped; + if (escaped) + continue; + + if (line[i] == ',') { + // parameter found + if ((howmany_read >= pstart) && + ((howmany_read <= pstop)||(pstop<0))) { + char **ptr = array_new(tmp); + cstring_t *trim = cstring_substring( + line, start, ((stop + 1) - start) + ); + cstring_trim(trim, ' '); + cstring_trim(trim, '\t'); + *ptr = cstring_convert(trim); + } + + start = (i + 1); + howmany_read++; + } + + stop = i; + } + + // Final parameter + if (start < stop) { + if ((howmany_read >= pstart) && + ((howmany_read <= pstop) || (pstop < 0))) { + char **ptr = array_new(tmp); + cstring_t *trim = cstring_substring( + line, start, ((stop + 1) - start) + ); + cstring_trim(trim, ' '); + cstring_trim(trim, '\t'); + *ptr = cstring_convert(trim); + } + howmany_read++; + } + + if ((pstop >= 0) && (tmp->count != (pstop - pstart))) { + free_array(tmp); + tmp = NULL; + } + + return tmp; } diff --git a/src/tdef/command.h b/src/tdef/command.h index e5910e9..26bc08e 100644 --- a/src/tdef/command.h +++ b/src/tdef/command.h @@ -23,7 +23,10 @@ typedef enum { TICK, DISPLAY, + READFILE, UNKNOWN, + INVALID, + FILE404, QUIT } command_type; @@ -82,5 +85,14 @@ void free_command(command_t *self); */ 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_int(command_t *self, char *line, int pstart, int pstop); + +int command_read_file(command_t *self, char *line, int pstart, int pstop); + #endif /* COMMAND_H */ diff --git a/src/tdef/reader.c b/src/tdef/reader.c index 602218f..4e6d9d9 100644 --- a/src/tdef/reader.c +++ b/src/tdef/reader.c @@ -43,8 +43,15 @@ command_t *reader_readnext(FILE *file) { if (!strcmp(".", line->string)) { cmd->type = TICK; - } else if (cstring_starts_with("display", line->string, 0)) { + } 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 (!command_read_file(cmd, line->string, 0, -1)) { + cmd->type = INVALID; + if (command_read_str(cmd, line->string, 0, -1)) + cmd->type = FILE404; + } } else if (cstring_starts_with("quit", line->string, 0)) { cmd->type = QUIT; } diff --git a/src/tdef/tdef.c b/src/tdef/tdef.c index 9a3d6b8..eae7a76 100644 --- a/src/tdef/tdef.c +++ b/src/tdef/tdef.c @@ -29,6 +29,10 @@ int displayMode = 0; +void display(map_t *self); +int process_cmd(command_t *cmd, engine_t *engine); +void read_commands(engine_t *engine, FILE *file); + void display(map_t *self) { fprintf(stderr, "==========\n\n"); for (int y = 0 ; y < self->height; y++) { @@ -88,9 +92,35 @@ int process_cmd(command_t *cmd, engine_t *engine) { display(engine->map); } break; + case READFILE: + array_loop (cmd->data, ptr, char*) { + char *subname = *ptr; + FILE *sub = fopen(subname, "r"); + if (!sub) { + fprintf(stderr, "Cannot read: %s\n", subname); + break; + } + + if (displayMode) + fprintf(stdout, "Start reading: %s\n",subname); + read_commands(engine, sub); + fclose(sub); + if (displayMode) + fprintf(stdout, "Done reading: %s\n",subname); + } + break; + case FILE404: + fprintf(stderr, "Unknown file(s):\n"); + array_loop_i (cmd->data, ptr, char*, i) { + fprintf(stderr, "%d. \"%s\"\n", (i+1), *ptr); + } + break; case UNKNOWN: fprintf(stderr, "Unrecognized command\n"); break; + case INVALID: + fprintf(stderr, "Invalid command\n"); + break; case QUIT: return 0; } @@ -98,6 +128,19 @@ int process_cmd(command_t *cmd, engine_t *engine) { return 1; } +void read_commands(engine_t *engine, FILE *file) { + command_t *cmd = reader_readnext(file); + while (cmd) { + if (process_cmd(cmd, engine)) { + free_command(cmd); + cmd = reader_readnext(file); + } else { + free_command(cmd); + cmd = NULL; + } + } +} + int main(int argc, char **argv) { map_t *map = new_map(6, 4); engine_t *engine = new_engine(map); @@ -122,16 +165,7 @@ int main(int argc, char **argv) { enemy->speed = 1; setup_enemy(engine, enemy); - command_t *cmd = reader_readnext(stdin); - while (cmd) { - if (process_cmd(cmd, engine)) { - free_command(cmd); - cmd = reader_readnext(stdin); - } else { - free_command(cmd); - cmd = NULL; - } - } + read_commands(engine, stdin); free_engine(engine); return 0;