/* Area creation utility. Plain text object parser. Part of HUB MUD. Copyright 1995-1997 by Henry McDaniel III. All rights reserved. */ #include <stdio.h> #include <ctype.h> #define VERSION "0.0" char prefix[10]; FILE *finput, *foutput; int lines = 0; /* number of lines read sofar */ char line_buffer[201]; /* current raw data input */ char map_name[30]; #define STRING_BUFFER_LIMIT 2000 char string_buffer[STRING_BUFFER_LIMIT + 1]; /* object tracking data */ #define MAX_OBJECTS 3000 int obj_count = 0; /* object counter */ int start_line[MAX_OBJECTS]; int obj_name[MAX_OBJECTS][30]; /* index of ids */ char block_name[30]; #define MODE_RESET 0 #define MODE_ID 1 #define MODE_SHORT 2 #define MODE_LONG 3 #define MODE_ANY 4 char tmp_buffer[2000]; #define GEM strcpy(tmp_buffer,label); \ strcat(tmp_buffer," "); strcat(tmp_buffer,line_buffer); \ strcpy(line_buffer,tmp_buffer); len=strlen(label)+1; /* current state */ int mode = 0, sub = 0; int in_mapping = 0, in_string = 0, string_start = 0, fatals = 0, warns = 0; void note (char *text, int line) { printf ("line %-2d: %s\n", line, text); } void warn (char *text, int line) { printf ("line %-2d: Warning, %s\n", line, text); warns++; } void fatal (char *text, int line) { printf ("line %-2d: Fatal, %s\n", line, text); fatals++; } int get_word (char *buf, char *input, int blimit) { int len, x = 0, y, n = 0, z, blimitr; /* while(isspace(*(input+x)))x++; */ while (*(input + x) < 33 || *(input + x) > 125) x++; if (!(len = strlen (input + x))) return 0; blimitr = blimit - 1; /* was len.. made len+1 */ for (y = x; y < (len + 1) && n <= blimitr; y++) if (*(input + y) == '\n' || *(input + y) == '\r' || isspace (*(input + y))) break; else { *(buf + n) = *(input + y); n++; } *(buf + n) = '\0'; if (n == blimitr) return 0; /* changed */ if (y == (len - 1)) return (y + 1); /* was len+1 */ for (z = y; z < len; z++) /* if(!isspace(*(input+z))) */ if (*(input + z) > 32 && *(input + z) < 126) return z; return 0; } int check_for_dup (char *test) { int limit = 0, x; char buf[256]; if (obj_count < 2) return; limit = obj_count - 1; for (x = 0; x < limit; x++) if (!strcmp (test, (char *) obj_name[x])) { buf[0] = '\0'; sprintf (buf, "object \"%s\" using same id as another", test); warn (buf, lines); if (obj_count >= 2) note ("original object ends here", start_line[obj_count - 2]); else note ("original object ends? around here", start_line[obj_count - 1]); return 1; } return 0; } int get_obtype (char *test) { char buf[256]; switch (*test) { case 'r': /* ROOM */ case 'R': return 3; break; case 'n': /* NPC */ case 'N': case 'c': case 'C': return 2; break; case 'o': /* Other Object */ case 'O': return 1; break; } buf[0] = '\0'; sprintf (buf, "unknown or illegal object type %s", test); fatal (buf, lines); return 0; } char label[21]; /* get local var type */ int get_type (char *name) { if (!strcmp (name, "size") || !strcmp (name, "block") || !strcmp (name, "start") || !strcmp (name, "store") || !strcmp (name, "weight") || !strcmp (name, "capacity") || !strcmp (name, "drink") || !strcmp (name, "food") || !strcmp (name, "wear") || !strcmp (name, "armor") || !strcmp (name, "point") || !strcmp (name, "decay") || !strcmp (name, "energy") || !strcmp (name, "mob") || !strcmp (name, "level") || !strcmp (name, "ud") || !strcmp (name, "ud") || !strcmp (name, "us") || !strcmp (name, "ld") || !strcmp (name, "ls") || !strcmp (name, "position") || !strcmp (name, "hunt")) return 11; /* is integer */ if (isdigit (*(label))) if (!strcmp (map_name, "block{")) return 11; return 10; /* string otherwise */ } void prefix_exit (char *test) { char tmp[STRING_BUFFER_LIMIT + 1]; char first_part[25]; int len; if (prefix[0] == '\0') return; first_part[0] = '\0'; len = get_word (first_part, string_buffer, 24); tmp[0] = '\0'; if (!len || *first_part == '\0') { sprintf (tmp, "exit named \"%s\" in error", label); fatal (tmp, lines); return; } sprintf (tmp, "%s %s%s", first_part, prefix, string_buffer + len); strcpy (string_buffer, tmp); } void add_string (char *to_add) { int end, x, chop = 0, y; end = strlen (to_add) - 1; if (!in_string) { string_buffer[0] = '\0'; string_start = lines; } /* expand any \n marks */ for (x = 0; x < (end - chop); x++) if (*(to_add + x) == '\\' && *(to_add + x + 1) == 'n') { *(to_add + x) = '\n'; for (y = (x + 1); y < (end + 1 - chop); y++) *(to_add + y) = *(to_add + y + 1); chop++; } end = strlen (to_add) - 1; if (*(to_add + end) == '\\') { /* note get_word will nullify space at start of string */ *(to_add + end) = ' '; *(to_add + end + 1) = '\0'; in_string = 1; if ((end + 2 + strlen (string_buffer)) > STRING_BUFFER_LIMIT) { warn ("string too long", lines); fatal ("possible start of excessive string", string_start); } } else in_string = 0; strcat (string_buffer, to_add); if (!in_string) { x = strlen (string_buffer); /* while(isspace(*(string_buffer+x))) x--; */ while (*(string_buffer + x) < 33 || *(string_buffer + x) > 125) x--; *(string_buffer + x + 1) = '\0'; if (!strcmp ("exits{", map_name) && in_mapping) prefix_exit (string_buffer); strcat (string_buffer, "|\n"); fprintf (foutput, "%s", string_buffer); string_buffer[0] = '\0'; } } char id[21], type[11], environment[21]; int typen = 0, flags = 0; void process_input () { int len = 0, cum_len = 0, local_type = 0; char check[11]; char buf[256]; if (in_string) { add_string (line_buffer); line_buffer[0] = '\0'; return; } else if (string_buffer[0] != '\0') { if (!strcmp ("exits{", map_name) && in_mapping) prefix_exit (string_buffer); fprintf (foutput, "%s|\n", string_buffer); string_buffer[0] = '\0'; } check[0] = '\0'; get_word (check, line_buffer, 10); if (!strcmp (check, "}") || *line_buffer == '}') { if (!in_mapping) warn ("end of mapping mark \"}\" outside of any mapping.", lines); else in_mapping = 0; line_buffer[0] = '\0'; return; } switch (mode) { case MODE_ID: /* try and get id information */ id[0] = '\0'; type[0] = '\0'; len = get_word (id, line_buffer, 20); cum_len += len; len = get_word (type, line_buffer + cum_len, 10); if (*type == '\0') { fatal ("ID entry missing object type information", lines); exit (0); } cum_len += len; environment[0] = '\0'; if (len) get_word (environment, line_buffer + cum_len, 20); if (*environment == '\0') strcpy (environment, "-"); check_for_dup (id); strcpy ((char *) obj_name[obj_count - 1], id); flags = 0; /* container special case */ if ((*type == 'c' || *type == 'C') && (*(type + 1) != 'h' && *(type + 1) != 'H')) { flags = 16; typen = 1; } else typen = get_obtype (type); /* print out data */ if (prefix[0] != '\0') fprintf (foutput, "%s%s %d %d - %s\n", prefix, id, flags, typen, environment); else fprintf (foutput, "%s %d %d - %s\n", id, flags, typen, environment); line_buffer[0] = '\0'; mode = MODE_SHORT; return; break; case MODE_SHORT: strcpy (label, "short:"); GEM mode = MODE_LONG; break; case MODE_LONG: strcpy (label, "long:"); GEM mode = MODE_ANY; break; case MODE_ANY: label[0] = '\0'; len = get_word (label, line_buffer, 20); break; } /* end of mode test switch */ /* buf[0]='\0'; sprintf(buf," label=\"%s\"\n",label); printf(buf); */ /* Mapping */ if (*(label + strlen (label) - 1) == '{') { if (in_mapping) fatal ("nested mappings are unsupported.", lines); else { in_mapping = 1; strcpy (map_name, label); } *(label + strlen (label) - 1) = '\0'; /* print out data for head of a mapping list */ fprintf (foutput, "%s 8 29 0 1\n", label); line_buffer[0] = '\0'; return; } else /* Regular data set */ if (*(label + strlen (label) - 1) == ':') { *(label + strlen (label) - 1) = '\0'; local_type = get_type (label); /* print the data out */ fprintf (foutput, "%s 8 %d %d 0 ", label, local_type, in_mapping); if (local_type != 10) /* if not string print data directly */ { if (!len) { buf[0] = '\0'; sprintf (buf, "variable \"%s\" without value! will assume %s=0", label, label); warn (buf, lines); } else { if (!isdigit (*(line_buffer + len))) fprintf (foutput, "%d\n", 0); else fprintf (foutput, "%s\n", line_buffer + len); } line_buffer[0] = '\0'; return; } } else if (*label != '\0') { buf[0] = '\0'; sprintf (buf, "\"%s\" unknown symbol or data.", label); fatal (buf, lines); line_buffer[0] = '\0'; return; } else if (*label == '\0') return; /* if it is our first crack at the string we will get to here */ if (len) add_string (line_buffer + len); line_buffer[0] = '\0'; } void run () { int data_to_process = 0, problem_character = 0, len, x, stop, start = 0; char buf[256]; char load_buffer[201]; while (!feof (finput)) { /* read in a line of data */ load_buffer[0] = '\0'; fgets (load_buffer, 200, finput); lines++; /* ignore comments */ if (*load_buffer == ';' || *load_buffer == '\0') continue; /* increment object count and associated load info if new object */ if (*load_buffer == '#') { start_line[obj_count] = lines; obj_count++; if (obj_count > 1) fprintf (foutput, "~\n"); if (obj_count > MAX_OBJECTS) { fatal ("too many objects", lines); buf[0] = '\0'; sprintf (buf, "%d is the maximum of objects per file.", MAX_OBJECTS); note (buf, lines); exit (0); } mode = MODE_ID; } else { /* do nothing if line is merely whitespace */ start = 0; len = strlen (load_buffer); data_to_process = 0; for (x = 0; x < len && !data_to_process; x++) /* if(!isspace(*(load_buffer+x))) data_to_process=1; */ if (*(load_buffer + x) > 32 && *(load_buffer + x) < 126) data_to_process = 1; else { start = x; *(load_buffer + x) = '\t'; } /* if not just whitespace... */ if (data_to_process) { problem_character = 0; for (x = 0; x < len; x++) if (*(load_buffer + x) == 27 || *(load_buffer + x) > 126 || *(load_buffer + x) == '|') { problem_character = 1; *(load_buffer + x) = '?'; } else if (*(load_buffer + x) == '\n' || *(load_buffer + x) == '\r') *(load_buffer + x) = '\0'; if (problem_character) { warn ("illegal character(s) detected and nullified.", lines); note ("illegal chatacter(s) are replaced with \"?\".", lines); } strcpy (line_buffer, load_buffer + start); process_input (); } } } /* end of while !feof */ } void main (int argvc, char **argv) { if (argvc < 3 || argvc > 4) { printf ("use: %s source output <prefix>\n\r", argv[0]); exit (0); } if (argvc == 4) { int fail = 0; if (*prefix == '~') { printf ("Prefix cannot start with ~. Sorry.\n\r"); fail = 1; } else { int len, x; len = strlen (prefix); for (x = 0; x < len; x++) if (*(prefix + x) == 27 || *(prefix + x) > 126) { printf ("Illegal character ascii %d in prefix.\n\r", *(prefix + x)); fail = 1; } } if (fail) exit (1); strcpy (prefix, argv[3]); } else prefix[0] = '\0'; if (!(finput = fopen (argv[1], "r"))) { printf ("Could not open input file \"%s\"\n\r", argv[1]); exit (0); } if (!(foutput = fopen (argv[2], "a+"))) { printf ("Could not open ouput file \"%s\"\n\r", argv[2]); exit (0); } map_name[0] = '\0'; string_buffer[0] = '\0'; printf ("HUB MUD English to Raw Data translator v%s.\n\ Input file=\"%s\"\n", VERSION, argv[1]); if (prefix[0] != '\0') printf ("Using ObjID prefix (\"%s\")\n", prefix); printf ("-----------------------------------------------\n"); /* Do the job */ run (); fclose (finput); fclose (foutput); if (warns && fatals) printf ("%d warnings and ", warns); else if (warns) printf ("%d warnings.\n", warns); if (fatals) printf ("%d fatal errors.\n", fatals); if (!warns && !fatals) printf ("*** %d objects translated ***\n\r", obj_count); exit (0); }