pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
/* DUMBASS CONVERTER, converts zone files */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "kernel.h"
#include "gen.h"
#include "exitnames.h"

#define ZONSEGMENT	0
#define DATSEGMENT	1
#define MOBSEGMENT	2
#define OBJSEGMENT	3
#define LOCSEGMENT	4

typedef struct _funccalls {
	char	funcname[120];
	char 	created_in[120];
	struct	_funccalls *next;
} FuncCall;

int this_segment = ZONSEGMENT;
int linenr=1;
int write_zone_start=0;
int write_zone_end = 0;
zone_record this_zone;
FuncCall *function_list = NULL;

/* Tokens that chance shape in the new format */
char *conversionTable[] = {
	"desc[0]",	"Desc0",
	"desc[1]",	"Desc1",
	"desc[2]",	"Desc2",
	"desc[3]",	"Desc3",
	"Startcode",	"Trap",
	"EndCode",	"EndTrap",
	"Pname",	"Name",
	"Description",	"Desc\t",
        "BValue",	"BaseValue",
	"Extern",	"UseTrap",
	"Oflags",	"OFlags",
	"Pflags",	"PFlags",
	"SFlags",	"SFlags",
	"Mflags",	"MFlags",
	"Lflags",	"LFlags",
	"Altname",	"AltName",
	"Strength",	"Strength",
	"Damage",	"Damage",
	"Aggression",	"Aggression",
	"Speed",	"Speed",
	"Armor",	"Armor",
	"Weight",	"Weight",
	"Linked",	"Linked",
	"Location",	"Location",
	"Wimpy",	"Wimpy",
	"Visibility",	"Visibility",
	TABLE_END,	TABLE_END
};

/* Segments in the old format */
char *segmentIds[] = {
	"%zone",	"%globaldata",	"%mobiles",	"%objects",	
	"%locations",	TABLE_END
};

char *StartTokens[] = {
	"Zone",	"",	"Mobile",	"Object",	"Location",
};

char *EndTokens[] = {
	"EndZone",	"",	"EndMobile",	"EndObject",	"EndLocation"
};

char *flags[] = {
	"OFlags",	"Sflags",	"Pflags",	"MFlags",	"Lflags",
	TABLE_END
};

char *exitIds[] = {
	"n",	"North\t",
	"s",	"South\t",
	"e",	"East\t",
	"w",	"West\t",
	"u",	"Up\t",
	"d",	"Down\t",
	"ne",	"NorthEast",
	"se",	"SouthEast",
	"nw",	"NorthWest",
	"sw",	"SouthWest",
	TABLE_END, TABLE_END
};
int lookup(char *token,char **table)
{   int i=0;

    if (strlen(token) < 3)
       return 0;

    for (i=0; table[i] != TABLE_END; i++)
    {   if (strncasecmp(token,table[i],strlen(token)) == 0)
           return 1;
    }
    return 0;
}

void addFunctionCall(char *object, char *function)
{   FuncCall *p;
    
    p = (FuncCall *)malloc(sizeof(FuncCall));
    strcpy(p->created_in,object);
    strcpy(p->funcname,function);
    p->next = function_list;
    function_list = p;
}

char *findObjectByFunction(char *func)
{   FuncCall *p = function_list;

    while (p != NULL && strcmp(p->funcname,func) != 0)
       p = p->next;

    if (p == NULL)
    {  if (strchr(func,'@') != NULL)
          printf("Warning: reference to an external function not defined in this zone: %s\n",func);
  
       return "undefined\n";
    }
    return p->created_in;    
}

void clearFuncList()
{   FuncCall *p = function_list;
    
    while (p != NULL)
    {   function_list = p->next;
        free(p);
        p = function_list;
    }
}

/* convert a flag definition to the new style
 * oldstyle:  Flags { <flags> }
 * newstyle:  Flags = <flag> [, <flags>]
 */
char *make_flag_line(char *line, char *buffer,char *head)
{   char token[120];
    char *s = token;
    char *p = line;
    int first=1;
    int comment=0;
    int aftercomment = 0;
    int flagc = 0;

    while (*p != '{' && *p != '\0')
       p++;

    if (*p == '\0')
    {   printf("Opening bracket not found in line %d\n",linenr);
        return "";
    }
    p++;

    while (isspace(*p) && *p !='\0' && *p != '}')
       p++;

    strcpy(buffer,head);
    while (*p != '\0' && *p != '}')
    {   while (!isspace(*p) && *p != '}')
        {   *s = *p;
            p++;
            s++;
        }
        *s = '\0';

        if (strstr(token,"/*") != NULL)
           comment = 1;

        if (!comment)
          flagc++;

        if (strstr(token,"*/") != NULL)
        {   comment = 0;
            aftercomment = 1;
        }

        if (first)
        {  strcat(buffer,token);
           first = 0;
        }
        else
        {  if (aftercomment)
           {   strcat(buffer," ");
               aftercomment = 0;
           }
           else
              strcat(buffer,", ");
           strcat(buffer,token);
        }

        while (isspace(*p) && *p != '}' && *p != '\0')
           p++;
        s= token;
    }

    if (flagc != 0)
       strcat(buffer,"\n");
    else
       strcpy(buffer,"");
    return buffer;
}

char *find_translation(char *token)
{   int i;
    static char s[120];

    if (strlen(token) <= 2)
       return token;

    for (i=0; segmentIds[i] != TABLE_END; i+= 1)
    {   if (strncasecmp(segmentIds[i],token,strlen(token)) == 0)
        {   if (this_segment == ZONSEGMENT && i == DATSEGMENT)
            {   sprintf(s,"Data\n@");
                write_zone_start = 1;
            }
            else if (this_segment == DATSEGMENT && i != DATSEGMENT)
            {   sprintf(s,"@\nEndData");
                write_zone_end = 1;
            }
            else if (this_segment == ZONSEGMENT && i != ZONSEGMENT)
            {   write_zone_start = write_zone_end = 1;
                strcpy(s,"");
            }
            else 
               strcpy(s,"");

            this_segment = i;
            return s;
        }
    }

    if (strcasecmp(token,"Name") == 0)
    {   if (this_segment != ZONSEGMENT)
           return StartTokens[this_segment];
        else
           return "###@";
    }
    else if (strcasecmp(token,"End") == 0)
    {   return EndTokens[this_segment];
    }

    for (i = 0; conversionTable[i] != TABLE_END; i+=2)
    {   if (strncasecmp(conversionTable[i],token,strlen(token)) == 0)
           return conversionTable[i+1];
    }
    return token;
}

char *convert_line(char *line,char *buffer)
{   char linebuf[1100];
    char buildbuf[1000];
    char first_token[255];
    char this_name[100];
    char *p = first_token;
    int  i=0;

    while(!isspace(line[i]) && line[i] != '=' && line[i] != '{') 
    {   *p = line[i++];
        p++;
    }
    *p = '\0';

    if (lookup(first_token,flags))
    {  sprintf(buildbuf,"%s\t\t= ",find_translation(first_token));

       (void)make_flag_line(line,linebuf,buildbuf);
    }
    else
    {
       if (strcasecmp(first_token,"name") == 0)
       {  char *t = index(line,'=');
          t++;
          while (isspace(*t))
               t++;
          strcpy(this_name,t);
       }

       p = find_translation(first_token);

       if (strcasecmp(p,"Trap") == 0) 
       {  char *t = index(line,'=');
          t++;
          while (isspace(*t))
               t++;
          addFunctionCall(this_name,t);

          sprintf(linebuf,"%s\t\t= all\n@\n",p);
       }
       else if (strcasecmp(p,"EndTrap") == 0)
          sprintf(linebuf,"@\n%s\n",p);
       else if (strcasecmp(p,"UseTrap") == 0)
       {  char *t = index(line,'=');
          t++;
          while (isspace(*t))
               t++;
          sprintf(linebuf,"%s\t\t= all:%s",p,findObjectByFunction(t));
       } 
       else if (strcasecmp(p,"Location") == 0)
       {   char *ats = NULL; 
           char *s;
           char locname[128];
           char cflags[20];

           if (this_segment == OBJSEGMENT)
           {  p = rindex(line,':');
              s = index(line,'=');
              ats = index(line,'@');
              if (p == NULL || s == NULL)
              {   printf("An object in this zone has an invalid format.\n"
                         "Check out this line: %d\n>%s",linenr,line);
                  return NULL;
              }
              else 
              {   s++;
                  while(isspace(*s))
                      s++;
                  *p = '\0';
                  sprintf(cflags,"%s:",s);
                  s = cflags;
                  p++;
               }
           }
           else
           {  s = "";
              p = index(line,'=');
              p++;
              while (isspace(*p))
                p++; 
              ats = index(p,'@');
           }

           while (p[strlen(p) -1] == ' ' || p[strlen(p) -1] == '\t' ||
                  p[strlen(p) -1] == '\n')
              p[strlen(p) -1] = '\0';

           if (isdigit(*p) || lookup(p,Exits))
           {   char *ext = rindex(p,'@');
               if (ext == NULL)
                  sprintf(locname,"%s_%s",this_zone.zonename,p);
               else
                  sprintf(locname,"%s_%s",ext+1,p);
           }   
           else
           {   sprintf(locname,"%s",p);
               if (ats == NULL)
               {  strcat(locname,"@");
                  strcat(locname,this_zone.zonename);
               }
           }
          sprintf(linebuf,"Location\t= %s%s\n",s,locname);      
       }
/*
       else if (strcasecmp(p,"ZoneName") == 0)
           return "";
*/
       else if (this_segment == ZONSEGMENT && strcasecmp(p,"Quest") == 0)
       {   p = index(line,'=');

           if (p == NULL)
              return "";
           p++;
           while(isspace(*p))
             p++;

           strcpy(this_zone.quest,p);
           return "";
       }
       else if (this_segment == ZONSEGMENT && strcasecmp(p,"Author") == 0)
       {   p = index(line,'=');
           if (p == NULL)
              return "";
           p++;
           while(isspace(*p))
              p++;
           strcpy(this_zone.author,p);
           return "";
       }
       else if (strcasecmp(p,"Altname") == 0)
       {   p = index(line,'=');
           if (p == NULL)
              return "";
           p++;
           while(isspace(*p))
              p++;
           if (*p != '"')    
           {  p[strlen(p)-1] = '\0'; 
              sprintf(linebuf,"Altname\t= \"%s\"\n",p);
           }
           else
              sprintf(linebuf,"Altname\t= %s\n",p);
       }
       else if (this_segment == ZONSEGMENT && strcasecmp(p,"Name") == 0)
       {   p = index(line,'=');
           if (p == NULL)
              return "";
           p++;
           while(isspace(*p))
              p++;
           strcpy(this_zone.zonename,p);
           return "";
       }
       else if (strcasecmp(p,"Name") == 0)
       {   p = index(line,'=');
           if (p == NULL)
              return "";
           p++;
           while(isspace(*p))
              p++;
           if (*p != '"')    
           {  p[strlen(p)-1] = '\0'; 
              sprintf(linebuf,"Name\t= \"%s\"\n",p);
           }
           else
              sprintf(linebuf,"Name\t= %s",p);
       }
       else if (write_zone_start)
       {   if (index(this_zone.author,'\n') != NULL)
              this_zone.author[strlen(this_zone.author)-1] = '\0';

           sprintf(buildbuf,"Zone\t\t= %s\n"
                            "Author\t\t= %s%s%s\n",
                            this_zone.zonename,
                            index(this_zone.author,'"') == NULL ? "\"" : "",
                            this_zone.author,
                            index(this_zone.author,'"') == NULL ? "\"" : "");

            if (this_zone.quest[0] != '\0')
            {   strcat(buildbuf,"Quest\t\t= ");
                strcat(buildbuf,this_zone.quest);
            }

            sprintf(linebuf,"%s%s%s",buildbuf,p,line+i);
            write_zone_start = 0;
       }
       else if (strcmp(p,"###@") != 0)  
          sprintf(linebuf,"%s%s",p,line+i);

       if (write_zone_end)
       {   sprintf(buildbuf,"EndZone\t\t= %s\n\n",this_zone.zonename);
           strcat(linebuf,buildbuf);
           write_zone_end = 0;
       }
    }
    strcpy(buffer,linebuf);
    return buffer;
}

void convert_locs(FILE *inf,FILE *outf,char *lineb)
{   char line[1024];
    char buffer[1025];
    char symbol[120];
    char locname[120];
    char *s,*p;
    int  i,raw = 0;

    if (index(lineb,';') == NULL)
        fgets(line,1023,inf);
    else
       strcpy(line,lineb);

    while (!feof(inf))
    {   while (index(line,';') == NULL && !feof(inf))
        {  fputs(line,outf);
           fgets(line,1023,inf);
        }
        p = line;
        s = symbol;

        if (feof(inf))
           return;

        while (!isspace(*p) && *p != ';') 
        {  *s = *p;
           p++;
           s++;
        }

        *s = '\0';

        while (isspace(*p) && *p != ';')
          p++;

        if (!isdigit(symbol[0]) && !lookup(symbol,Exits))
           strcpy(locname,symbol);
        else
           sprintf(locname,"%s_%s",this_zone.zonename,symbol);
      
        fprintf(outf,"Location\t= \"%s\"\n",locname);

        while (*p != ';')
        {   while (isspace(*p))
              p++;
          
            if (*p == ';')
                break;
 
            s = symbol;
            while (*p != ':')
            {  *s = *p;
               p++;
               s++;
            }
            *s = '\0';

            for (i=0; exitIds[i] != TABLE_END;i+=2)
            {   if (strcasecmp(exitIds[i],symbol) == 0)
                    break;
            }

            if (exitIds[i] == TABLE_END)
            {   printf("Unable to convert an exit for a location.\n"
                       "Check out line: %d\n>%s\n",linenr,line);
                while (*p != ';' && !isspace(*p))
                   p++;
                continue;
            }

            p++;
            s = symbol;
            while (!isspace(*p) && *p != ';')
            {   *s = *p;
                p++;
                s++;
            }
            *s = '\0';

            if (isdigit(symbol[0]) || lookup(symbol,Exits))
            {  s = index(symbol,'@');
               if (s != NULL)
                  fprintf(outf,"%s\t= %s_%s\n",exitIds[i+1],s+1,symbol);
               else
                  fprintf(outf,"%s\t= %s_%s\n",exitIds[i+1],this_zone.zonename,symbol);
            }
            else if (index(symbol,'@') == NULL && symbol[0] != '#')
               fprintf(outf,"%s\t= %s@%s\n",exitIds[i+1],symbol,this_zone.zonename);
            else
               fprintf(outf,"%s\t= %s\n",exitIds[i+1],symbol);
        }

        if (inf == NULL || feof(inf))
        {   printf("Unexpected end of file after reading the exits.\n"
                   "line: %s\n",line);
            exit(1);
        } 
        fgets(line,1023,inf);

        while (index(line,'^') == NULL)
        {   s = symbol;
            p = line;
            while (!isspace(*p) && *p != '=' && *p != '{')
            {   *s = *p;
                s++;
                p++;
            }
            *s = '\0';

            if (strncasecmp(symbol,"Lflags",strlen(symbol)) == 0 && !raw)
            {   make_flag_line(line,buffer,"LFlags\t\t= ");
                fprintf(outf,"%s",buffer);
            }
            else if (strcasecmp(symbol,"StartCode") == 0)
            {   char *t = index(line,'=');
                t++;
                while(isspace(*t))
                  t++;
                fprintf(outf,"Trap\t\t= all\n@\n");
                addFunctionCall(locname,t);
                raw = 1;
            }
            else if (strcasecmp(symbol,"EndCode") == 0)
            {   fprintf(outf,"@\nEndTrap\n");
                raw = 0;
            }
            else if (strcasecmp(symbol,"Extern") == 0)
            {   char *t = index(line,'=');
                t++;
                while(isspace(*t))
                  t++;
                fprintf(outf,"UseTrap\t= all:%s\n",findObjectByFunction(t));
            }
            else
            {   fputs(line,outf);
            }
            fgets(line,1023,inf);
        } 

        s = index(line,'^');
        *s = '"';
        fprintf(outf,"Title\t\t= \"%s",line);
        fprintf(outf,"Desc\t\t= ^\n");

        fgets(line,1023,inf);
        while (line[0] != '^' && !feof(inf))
        {   fputs(line,outf);
            fgets(line,1023,inf);
        }
        fprintf(outf,"^\nEndLocation\t= \"%s\"\n\n", locname);
        fgets(line,1023,inf);
    }
}

int convert_file(char *infn, char *outfn)
{   FILE *inf, *outf;
    char line[1024];
    char buffer[1100];
    char *s;

    if ((inf = fopen(infn,"r")) == NULL)
    {   printf("Can't find file %s\n",infn);
        return 1;
    }
    if ((outf = fopen(outfn,"w")) == NULL)
    {   fclose(inf);
        printf("Can't open target file %s\n",outfn);
        return 1;
    }

    fgets(line,1023,inf);
    while (!feof(inf))
    {  
       if (this_segment == LOCSEGMENT)
       {  convert_locs(inf,outf,line);
       }
       else if (strstr(line,"cflags.h") == NULL)
       {   s = convert_line(line,buffer);
           if (s != NULL)
             fputs(s,outf);
           fgets(line,1023,inf);
           linenr++;
       }
       else
       {   fgets(line,1023,inf);
           linenr++;
       }
    }

    fclose(inf);
    fclose(outf);
    return 0;   
}

int main(int argc, char **argv)
{   char infilename[128];
    char outfilename[128];
    char *p,*s;
    int  i;

    if (argc < 2)
    {   printf("Usage: %s [<zone>] [+<zonelistfile>]\n",argv[0]);
        return 0;
    }

    for (i = 1; i < argc; i++)
    {   
        this_segment = ZONSEGMENT;
        linenr = 1;
        if (argv[i][0] == '+')
        {   FILE *listfile;
            char *v = argv[i];
            char file[120];

            if ((listfile = fopen(++v,"r")) != NULL)
            {   fgets(file,119,listfile);
                while (!feof(listfile))
                {
                    this_segment = ZONSEGMENT;
                    linenr = 1;

                    if ((p = strstr(file,".zone")) != NULL)
                        *p = '\0';
       
                    s = rindex(file,'/');
                    if (s == NULL)
                        s = file;
                    else 
                        s++;

                    strcpy(this_zone.zonefile,file);
                    this_zone.zonename = (char *)malloc(40);
                    this_zone.author = (char *)malloc(40);
                    this_zone.quest = (char *)malloc(40);
                    strcpy(this_zone.zonename,s);
                    strcpy(this_zone.author,"Unknown\n");
                    this_zone.quest[0] = '\0';
                    sprintf(infilename,"%s.zone",file);
                    sprintf(outfilename,"%s.area",s);
                    printf("Converting %s (from: %s to: %s)\n",this_zone.zonename,infilename,outfilename);
	            if (convert_file(infilename,outfilename) != 0)
                        return 1; 
                    clearFuncList();
                    fgets(file,119,listfile);
                }
                fclose(listfile);
            }
        }
        else
        {  if ((p = strstr(argv[i],".zone")) != NULL)
              *p = '\0';
       
           s = rindex(argv[i],'/');
           if (s == NULL)
              s = argv[i];
           else 
              s++;

           strcpy(this_zone.zonefile,argv[i]);
           this_zone.zonename = (char *)malloc(40);
           this_zone.author = (char *)malloc(40);
           this_zone.quest = (char *)malloc(40);
           strcpy(this_zone.zonename,s);
           strcpy(this_zone.author,"Unknown\n");
           this_zone.quest[0] = '\0';
           sprintf(infilename,"%s.zone",argv[i]);
           sprintf(outfilename,"%s.area",s);
           printf("Converting %s\n",this_zone.zonename);
	   if (convert_file(infilename,outfilename) != 0)
              return 1; 
           clearFuncList();
        }
    }
    printf("Ready.\n");
    return 0;
}