#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));
self->CNAME[sz - 1] = '\0';
self->type = type;
+ self->data = NULL;
return 1;
}
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;
}
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++) {
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;
}
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);
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;