#include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include "cartograph.h" #include "utils.h" #include "tokendb.h" struct tokenrec token[MAX_TOKEN]; char pathstr[] = "NARBL\0"; char bitstr[] = "SUD\0"; void free_record(int index) { switch(token[index].type) { case TYPE_ROOM: free((struct arearec *) token[index].record); break; case TYPE_DOOR: free(((struct doorrec *) token[index].record)->name); free((struct doorrec *) token[index].record); break; case TYPE_PATH: free((struct pathrec *) token[index].record); break; } token[index].type = TYPE_NONE; token[index].record = 0; } int ok_token(int tokenid, int linenum, char *fn) { char buf[256]; if (tokenid < 33) { sprintf(buf, "Illegal ASCII token %d\n", tokenid); warning(buf, linenum, fn); return(0); } if ((struct arearec *) token[tokenid].record) { sprintf(buf, "Redefinition of token '%c'\n", tokenid); warning(buf, linenum, fn); free_record(tokenid); } return(1); } void define_new_area(char *s, int linenum, char *fn) { char ptr, buf[256], flagtext[100], *temp; long flags; int sector, i, tokenid; if (sscanf(s, "%s %c %s %d", buf, &ptr, flagtext, §or) < 4) { warning("Missing arguments for #ROOM definition\n", linenum, fn); return; } /* Grab possible room name v3.10 - 04/26/95 */ temp = s; for(i = 0; i < 4; i++) { while(*temp && !isspace(*temp)) temp++; while(isspace(*temp)) temp++; } if (*temp == ';') temp = 0; else { strcpy(buf, temp); if ((temp = strchr(buf, ';'))) *temp = 0; while(*buf && isspace(buf[strlen(buf) - 1])) buf[strlen(buf) - 1] = 0; temp = buf; } if (!ok_token(ptr, linenum, fn)) return; tokenid = ptr; if ((flags = decipher_flag_text(flagtext)) < 0) warning("Illegal ASCII bitvector in #ROOM definition\n", linenum, fn); token[tokenid].type = TYPE_ROOM; token[tokenid].record = (struct arearec *) malloc(sizeof(struct arearec)); /* Set up possible room name v3.10 - 04/26/95 */ if (temp) ((struct arearec *) token[tokenid].record)->name = str_dup(temp); else ((struct arearec *) token[tokenid].record)->name = 0; ((struct arearec *) token[tokenid].record)->room_flags = flags; ((struct arearec *) token[tokenid].record)->sector = sector; } char *skip_spaces(char *ptr) { while(isspace(*ptr)) ptr++; return(ptr); } void define_new_path(char *s, int linenum, char *fn) { struct pathrec *path; int index, startdir, tokenid; char buf[256], *cnt, *ptr; cnt = skip_spaces(s + strlen("#PATH")); if (!ok_token(tokenid = *cnt++, linenum, fn)) return; token[tokenid].type = TYPE_PATH; token[tokenid].record = (struct pathrec *) malloc(sizeof(struct pathrec)); path = (struct pathrec *) token[tokenid].record; for(index = ABOVE; index <= LEFT; index++) { path->dir[index].newdir = NOWHERE; path->dir[index].bitvector = 0; } cnt = skip_spaces(cnt); while ((*cnt != '\n') && (*cnt != '\r') && (*cnt)) { if (*cnt == ';') break; if ((ptr = strchr(pathstr, *cnt)) == NULL) { sprintf(buf, "Illegal direction %c in #PATH definition\n", *cnt); warning(buf, linenum, fn); free_record(tokenid); break; } startdir = strlen(pathstr) - strlen(ptr) - 1; cnt = skip_spaces(++cnt); if (*cnt++ != '-') { warning("Illegal format in #PATH definition\n", linenum, fn); free_record(tokenid); break; } cnt = skip_spaces(cnt); while (isalpha(*cnt)) { if ((ptr = strchr(pathstr, *cnt)) != NULL) { if (startdir != NOWHERE) { if (path->dir[startdir].newdir != NOWHERE) { sprintf(buf,"Direction %c redefined in #PATH statement\n", pathstr[startdir + 1]); warning(buf, linenum, fn); } path->dir[startdir].newdir = ptr - pathstr - 1; } } else if ((ptr = strchr(bitstr, *cnt)) != NULL) { if (startdir != NOWHERE) path->dir[startdir].bitvector |= (1 << (ptr - bitstr)); } else { sprintf(buf, "Illegal character %c in #PATH definition\n", *cnt); warning(buf, linenum, fn); free_record(tokenid); } cnt++; } cnt = skip_spaces(cnt); } } void define_new_door(char *s, int linenum, char *fn) { char *cnt, *ptr; int tokenid; struct doorrec *door; cnt = skip_spaces(s + strlen("#DOOR")); if (!ok_token(tokenid = *cnt++, linenum, fn)) return; token[tokenid].type = TYPE_DOOR; token[tokenid].record = (struct doorrec *) malloc(sizeof(struct doorrec)); door = (struct doorrec *) token[tokenid].record; cnt = skip_spaces(cnt); if (sscanf(cnt, "%d %d", &(door->doortype), &(door->key)) != 2) { warning("Missing parameters in #DOOR definition\n", linenum, fn); free_record(tokenid); return; } while (!isspace(*cnt)) cnt++; cnt = skip_spaces(cnt); while (!isspace(*cnt)) cnt++; cnt = skip_spaces(cnt); if ((ptr = strchr(cnt, ';'))) *ptr = 0; if ((ptr = strchr(cnt, '~'))) *ptr = 0; if ((ptr = strchr(cnt, '\n'))) *ptr = 0; while (isspace(cnt[strlen(cnt) - 1])) cnt[strlen(cnt) - 1] = 0; door->name = str_dup(cnt); } void analyze_line(char *s, int linenum, char *fn) { char cmd[256]; char *ptr; if ((ptr = strchr(s, '\n'))) *ptr = 0; strcpy(cmd, s); if (!(ptr = strtok(cmd, " \t"))) return; if (!strcmp(ptr, "#ROOM")) define_new_area(s, linenum, fn); else if (!strcmp(ptr, "#PATH")) define_new_path(s, linenum, fn); else if (!strcmp(ptr, "#DOOR")) define_new_door(s, linenum, fn); } void read_token_types(char *arg0) { FILE *fp; char s[256]; int linenum = 0; if ((fp = fopen(ARCHETYPE_FILE, "rt")) == NULL) { /* Look at argv[0] to find archetype file v3.10 - 05/04/95 */ strcpy(s, arg0); while(*s && (s[strlen(s) - 1] != '/')) s[strlen(s) - 1] = 0; strcat(s, ARCHETYPE_FILE); if ((fp = fopen(s, "rt")) == NULL) { error("Couldn't find startup file.\n\n"); exit(1); } } while(fgets(s, 255, fp) != NULL) analyze_line(s, ++linenum, ARCHETYPE_FILE); fclose(fp); } void print_dir_string(int tokenid, int dir) { char special[10]; int index; *special = 0; for(index = 0; bitstr[index]; index++) if (((struct pathrec *) token[tokenid].record)->dir[dir].bitvector & (1 << index)) sprintf(special + strlen(special), "%c", bitstr[index]); if (((struct pathrec *) token[tokenid].record)->dir[dir].newdir != NOWHERE) printf("%c-%s%c ", pathstr[dir + 1], special, pathstr[ ((struct pathrec *) token[tokenid].record)->dir[dir].newdir + 1]); } void print_token_list() { int index, dir; for(index = 0; index < MAX_TOKEN; index++) if ((struct arearec *) token[index].record) { printf("%c: ", index); switch(token[index].type) { case TYPE_ROOM: printf("Flags: %ld Sector: %d\n", ((struct arearec *) token[index].record)->room_flags, ((struct arearec *) token[index].record)->sector); break; case TYPE_DOOR: printf("Name %s Type: %d Key: %d\n", ((struct doorrec *) token[index].record)->name, ((struct doorrec *) token[index].record)->doortype, ((struct doorrec *) token[index].record)->key); break; case TYPE_PATH: for(dir = ABOVE; dir <= LEFT; dir++) print_dir_string(index, dir); printf("\n"); break; } } } void init_tokendb(char *arg0) { int index; for(index = 0; index < MAX_TOKEN; index++) { token[index].type = TYPE_NONE; token[index].record = 0; } read_token_types(arg0); } void free_all_tokens() { int index; for(index = 0; index < MAX_TOKEN; index++) if ((struct arearec *) token[index].record) free_record(index); } int get_token_room(int tokenid) { if (token[tokenid].type != TYPE_ROOM) return(0); return(tokenid); } int get_token_path(int tokenid) { if (token[tokenid].type != TYPE_PATH) return(0); return(tokenid); } int get_token_door(int tokenid) { if (token[tokenid].type != TYPE_DOOR) return(0); return(tokenid); } struct doorrec *get_door(int tokenid) { return((struct doorrec *) token[tokenid].record); } int find_new_direction(int tokenid, int fromdir) { return(((struct pathrec *) token[tokenid].record)->dir[fromdir].newdir); } long find_path_bitvector(int tokenid, int fromdir) { return(((struct pathrec *) token[tokenid].record)->dir[fromdir].bitvector); } void get_room_data(int tokenid, struct roomrec *room) { room->name = ((struct arearec *) token[tokenid].record)->name; room->room_flags = ((struct arearec *) token[tokenid].record)->room_flags; room->sector = ((struct arearec *) token[tokenid].record)->sector; }