new: readfile
authorNiki <niki@nikiroo.be>
Fri, 11 Apr 2025 22:58:33 +0000 (00:58 +0200)
committerNiki <niki@nikiroo.be>
Fri, 11 Apr 2025 22:58:33 +0000 (00:58 +0200)
src/tdef/command.c
src/tdef/command.h
src/tdef/reader.c
src/tdef/tdef.c

index 593a4744cca1d2cc3817c57ca3434814be9ea0ff..2786311905a09eca52a4d3b4d2035cd93e1dd33b 100644 (file)
@@ -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;
 }
 
index e5910e98dbca1c8611d874aa8945038d1fc358c9..26bc08eb04158be3b3aee44912bf70bb09f8df6c 100644 (file)
 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 */
 
index 602218f0b08f76e49f9c9cfd5af94b4544c6e14e..4e6d9d99a41b1df5dd5de66c23f4315f358763e3 100644 (file)
@@ -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;
                }
index 9a3d6b880814797ff0cb4f7fc1621ad28c9c1e08..eae7a766e8f191e1b8246119f147f4dd84baddcd 100644 (file)
 
 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;