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/
#define CODEGEN_C

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "gen.h"
#include "codegen.h"
#include "cflags.h"
#include "questnames.h"
#include "events.h"
#include "config.h"
#include "exits.h"

static FILE *obj_file = NULL;
static FILE *mob_file = NULL;
static FILE *loc_file = NULL;
static FILE *zon_file = NULL;
static FILE *proto_file = NULL;
static Boolean has_zone_header = False;
static Boolean is_first = True;

/**************************************************************************
 **                            PROTOTYPE FUNCTIONS
 **************************************************************************/

void gen_statements(stmt_list_record *the_stmt, FILE *the_file, 
                                              hashTable *the_hash);

void gen_stmt(stmt_record *the_stmt, FILE *the_file, 
                            hashTable *the_hash, Boolean print_semicolon);

/**************************************************************************
 **                            UTILITY FUNCTIONS
 **************************************************************************/

void compile_panic(char *str, char *fn, int linenr)
{   printf("\nPanic: %s (File: %s, Line: %d)\n",str,fn,linenr);
    exit(2);
}

FILE *safe_open(char *the_filename,char *the_directory,char *mode)
{   char temp_filename[255];
    FILE *thefp;

    sprintf(temp_filename,"%s/%s",the_directory,the_filename);
    if ((thefp = fopen(temp_filename,mode)) == NULL)
    {   printf("Could not open targetfile %s.\n",temp_filename);
    }
    return thefp;
}

/*************************************************************************
 **
 ** get_cflag - 
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - 
 **
 *************************************************************************/

int get_cflag(int the_flag)
{

   int TokenTable[] = {T_INROOM, T_INCONTAINER, T_CARRIEDBY, T_WORNBY, 
                       T_WIELDEDBY, T_BOTHBY, T_LAST};

   int CflagTable[] = {IN_ROOM, IN_CONTAINER, CARRIED_BY, WORN_BY, 
                       WIELDED_BY, BOTH_BY, T_LAST};
   int i;

   for (i=0; TokenTable[i] != T_LAST; i++)
   {
      if (TokenTable[i] == the_flag)
         return CflagTable[i];
   }
   return -1;
}


/*************************************************************************
 **
 ** get_quest - 
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

int get_quest(char *the_quest)
{
   int i = 0;

   fflush(stdout);
   for (i = 0; Quests[i] != TABLE_END; i++)
   {
      if (!strcasecmp(the_quest, Quests[i]))
         return i;
   }
   return -1;
} 

/**************************************************************************
 **
 ** convert_item - 
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 **************************************************************************/

char *convert_item(hashTable *the_hash, char *the_item, char *thezone, 
                                                          char *the_type)
{
   char *nextchar;
   char *tmp_char;

   int  num_amper = 0;
   char holder[(MAXNAMLEN*2)+5];
   Boolean has_carrot = False;

   nextchar = the_item;
   while (*nextchar != '\0')
   {
      if (*nextchar == '@')
      {         
         num_amper++;
      }
      if (*nextchar == '^')
         has_carrot = True;

      nextchar++;
   }
   if (has_carrot)
   {
      nextchar = the_item;
      while (*nextchar != '^')
      {
         nextchar++;
      }
      tmp_char = nextchar+1;
      while (*tmp_char != '\0')
      {
         *nextchar = *tmp_char;
         nextchar++;
         tmp_char++;
      }
      *nextchar = '\0';
      the_type = "obj";
   }

   if (num_amper == 0)
   {
      sprintf(holder, "%s@%s@%s", the_type, thezone, the_item);
      strcpy(the_item, holder);
   }
   else if (num_amper == 1)
   {  char tempstr[120];
      char *nameptr = tempstr;
      char *zoneptr;
    
      strcpy(tempstr,the_item);
      zoneptr = index(tempstr,'@');
      if (zoneptr == NULL)
        panicError("Cannot convert location properly, no ampersand found\n");

      *zoneptr = '\0';
      zoneptr++;
      sprintf(holder, "%s@%s@%s", the_type, zoneptr, nameptr);
      strcpy(the_item, holder);
   }
   lowercase(the_item);
   return the_item;
}


/**************************************************************************
 **                             MUDCODE GENERATION FUNCTIONS
 *************************************************************************/

/**************************************************************************
 **
 ** gen_zon_header
 **
 ** Parameters: thezone - zone to create a header file for.
 **
 *************************************************************************/

void gen_zon_header(zone_record *thezone)
{  char   upzonename[FILENAMESIZE];
   char   filename[MAXNAMLEN];
   time_t t = time(0);

   if (zon_file == NULL)
   {
      sprintf(filename, "%s.h", thezone->zonefile);
      if ((zon_file = safe_open(filename, request_char_value("GLOBALS_DIR"),"w")) == NULL)
      {   printf("Warning: could not open code file %s\n",filename);
          return;
      }
      strcpy(upzonename,thezone->zonefile);
      (void)uppercase(upzonename);

      fprintf(zon_file, 
"/***********************************************************************\n"
" ** ZONE: %s\n"
" ** Automatically created header file. Do not change things here, it will\n"
" ** go away. The Original code can be found in %s.area\n"
" ** last update: %s"
" **********************************************************************/\n"
"#ifndef ZON_%s_H_\n"
"#define ZON_%s_H_\n"
"\n\n", thezone->zonefile, thezone->zonefile, ctime(&t),upzonename,upzonename);

   }
}


/**************************************************************************
 **
 ** gen_loc_mudcode
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_loc_header(zone_record *thezone)
{
   char   filename[MAXNAMLEN];
   time_t t = time(0);

   if (loc_file == NULL)
   {
      sprintf(filename, "%s.c", thezone->zonefile);
      if ((loc_file = safe_open(filename, request_char_value("LOCATIONS_DIR"),"w")) == NULL)
      {   printf("Warning: could not open code file %s\n",filename);
          return;
      }
      fprintf(loc_file, 
"/***********************************************************************\n"
" ** ZONE: %s\n"
" ** Automatically created code file. Do not change things here, it will\n"
" ** go away. The Original code can be found in %s.area\n"
" ** last update: %s"
" **********************************************************************/\n"
"\n\n", thezone->zonefile, thezone->zonefile, ctime(&t));

      if (has_zone_header)
         fprintf(loc_file,"#include \"../Globals/%s.h\"\n\n",thezone->zonefile);
   }
}

/**************************************************************************
 **
 ** gen_obj_mudcode
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_obj_header(zone_record *thezone)
{
   char   filename[MAXNAMLEN];
   time_t t = time(0);

   if (obj_file == NULL)
   {
      sprintf(filename, "%s.c", thezone->zonefile);
      if ((obj_file = safe_open(filename, request_char_value("OBJECTS_DIR"), "w")) == NULL)
      {   printf("Warning: could not open code file %s\n",filename);
          return;
      }
      fprintf(obj_file, 
"/***********************************************************************\n"
" ** ZONE: %s\n"
" ** Automatically created code file. Do not change things here, it will\n"
" ** go away. The Original code can be found in %s.area\n"
" ** last update: %s"
" **********************************************************************/\n"
"\n\n", thezone->zonefile, thezone->zonefile, ctime(&t));

      if (has_zone_header)
         fprintf(obj_file,"#include \"../Globals/%s.h\"\n\n",thezone->zonefile);
   }
}

/**************************************************************************
 **
 ** gen_mob_mudcode
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_mob_header(zone_record *thezone)
{
   char   filename[MAXNAMLEN];
   time_t t = time(0);

   if (mob_file == NULL)
   {
      sprintf(filename, "%s.c", thezone->zonefile);
      if ((mob_file = safe_open(filename, request_char_value("NPC_DIR"), "w")) == NULL)
      {    printf("Warning: Could not open codefile: %s\n",filename);
           return;
      }
      fprintf(mob_file, 
"/***********************************************************************\n"
" ** ZONE: %s\n"
" ** Automatically created code file. Do not change things here, it will\n"
" ** go away. The Original code can be found in %s.area\n"
" ** last update: %s"
" **********************************************************************/\n"
"\n\n", thezone->zonefile, thezone->zonefile, ctime(&t));

      if (has_zone_header)
         fprintf(mob_file,"#include \"../Globals/%s.h\"\n\n",thezone->zonefile);
   }
}


/**************************************************************************
 **
 ** xgen_identifiers
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void xgen_identifiers(stmt_list_record *the_stmt, FILE *the_file)
{
   stmt_list_record  *tmp_stmt;  
   var_decl          *tmp_var;
   const_decl        *tmp_const;
 
   tmp_stmt = the_stmt;

   /* Marty: had to add the tmp_stmt here, dunno anything about
    *        this part though :/
    */
   while (tmp_stmt != NULL &&
          ((tmp_stmt->the_statement->stmt_type == STMT_VAR_DECL) ||
          (tmp_stmt->the_statement->stmt_type == STMT_CONST_DECL)))
   {
      if (tmp_stmt->the_statement->stmt_type == STMT_VAR_DECL)
      {
         tmp_var = tmp_stmt->the_statement->stmt.var_d;
         while (tmp_var != NULL)
	   {
            if (tmp_var->var_type == T_STR)
	      {
               fprintf(the_file, "   char %s[%d];\n", tmp_var->var_name, tmp_var->str_len); 
            }
            else if (tmp_var->var_type == T_BOOL)
	      {
               fprintf(the_file, "   Boolean %s;\n", tmp_var->var_name);
            }
            else if (tmp_var->var_type == T_NUMBER)
	      {
               fprintf(the_file, "   int %s;\n", tmp_var->var_name);
            }
            else
               printf("blah\n");
            tmp_var = tmp_var->more_var;
         }
      }
      else if (tmp_stmt->the_statement->stmt_type == STMT_CONST_DECL)
	{
         tmp_const = tmp_stmt->the_statement->stmt.const_d;
         if (tmp_const->const_type == T_STR)
	   {
            fprintf(the_file, "   const char %s = \"%s\";\n", 
                              tmp_const->const_name, tmp_const->assign); 
         }
         else if (tmp_const->const_type == T_NUMBER)
         {
            fprintf(the_file, "   const int %s = %s;\n", 
                               tmp_const->const_name, tmp_const->assign);
         }
         else
            printf("blah2\n");
      }
      tmp_stmt = tmp_stmt->more_statements;
   }

}

/**************************************************************************
 **
 ** gen_identifiers
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_identifiers(trap_record *the_trap, FILE *the_file)
{
   trap_record       *tmp_trap;

   tmp_trap = the_trap;
   while (tmp_trap != NULL)
   {
      xgen_identifiers(tmp_trap->the_statements, the_file);
      tmp_trap = tmp_trap->more_traps;
   }
}


/**************************************************************************
 **
 ** gen_assignmt
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_assignmt(assignmt *the_stmt, FILE *the_file, hashTable *the_hash)
{
   arith_number  *tmp_num;
   arith_string  *tmp_arith_str;
   string_record *tmp_str;

   if (the_stmt->the_stmt->stmt_type == STMT_ARITH_NUM)
   {
      fprintf(the_file, "\t%s = ", the_stmt->var_name);

      tmp_num = the_stmt->the_stmt->stmt.arith_num_d;

      while (tmp_num != NULL)
      {
         fprintf(the_file, "%s", tmp_num->arith_str);
         if (tmp_num->numberfunct != NULL)
            gen_stmt(tmp_num->numberfunct, the_file, the_hash, False);
         tmp_num = tmp_num->next_number;
      }
      fprintf(the_file, ";\n");
      return;
   }
   else if (the_stmt->the_stmt->stmt_type == STMT_ARITH_STR)
   {
      tmp_arith_str = the_stmt->the_stmt->stmt.arith_str_d;
      fprintf(the_file, "\t%s[0] = '\\0';\n", the_stmt->var_name);
      while (tmp_arith_str != NULL)
      {
         fprintf(the_file, "\tstrcat(%s, ", the_stmt->var_name);
         if (tmp_arith_str->stringfunct1 != NULL)
            gen_stmt(tmp_arith_str->stringfunct1, the_file, the_hash, False);
         else
         {
            tmp_str = tmp_arith_str->string1;
            while (tmp_str != NULL)
            {
               fprintf(the_file, "\"%s\"", tmp_str->the_string);
               if (tmp_str->nextstr != NULL)
                  fprintf(the_file, "\n");
               tmp_str = tmp_str->nextstr;
            }
         }
         fprintf(the_file, ");\n");

         if (tmp_arith_str->string2 != NULL)
            tmp_arith_str = tmp_arith_str->string2->stmt.arith_str_d;
         else
             tmp_arith_str = NULL;
      }
   }
   else
   {
      printf("ERROR!!!!! Unexpected assignment after =!!!\n");
      return;
   }
}


/**************************************************************************
 **
 ** gen_ident
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_ident(ident_decl *the_stmt, FILE *the_file, hashTable *the_hash)
{
   int     i;
   Boolean has_amper = False;
   char    holder[TOKENSTRLEN];

   /* see if it has an amperstand, meaning it would be an identifier of type 
      <TYPE>_<ZONE>_<ITEMNAME> */
   for (i=0; i < strlen(the_stmt->the_ident); i++)
   {
      if (the_stmt->the_ident[i] == '@')
         has_amper = True;
   }
 
   /* if it has an amperstand, convert it to proper form */
   if (has_amper)
   {
      for (i=0; i < strlen(the_stmt->the_ident); i++)
      {
         if (the_stmt->the_ident[i] == '@')
               holder[i] = '_';
         else
            holder[i] = toupper(the_stmt->the_ident[i]);
      }
      holder[i] = '\0';

      /* Add a + max_players when we're dealing with a mobile id */
      if (strncmp(the_stmt->the_ident,"mob",3) == 0)
         fprintf(the_file, "(%s + max_players)", holder);
      else      
         fprintf(the_file, "%s", holder);
   }
   
   /* else just display it */
   else
   {
      lowercase(the_stmt->the_ident);
      fprintf(the_file, "%s", the_stmt->the_ident);
   }
}

/**************************************************************************
 **
 ** gen_bool_exp
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_bool_exp(bool_stmt *the_stmt, FILE *the_file, hashTable *the_hash)
{
   bool_stmt *tmp_bool;

   tmp_bool = the_stmt;
   while (tmp_bool != NULL)
   {
      fprintf(the_file, "%s", tmp_bool->bool_string);
      if (tmp_bool->the_stmt != NULL)
         gen_stmt(tmp_bool->the_stmt, the_file, the_hash, False);
      tmp_bool = tmp_bool->next_bool;
   }
   return;
}

/**************************************************************************
 **
 ** gen_mud_defined
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_mud_defined(mudfunct_decl *the_stmt, FILE *the_file, 
                          hashTable *the_hash, Boolean print_semicolon)
{
   thecode_record *template;         /* reads the template for the code */
   string_record  *tmp_str;          /* used to read all strings in the linked list */
   mudfunct_param *param;
   param_record   *param_finder;            
   Boolean        has_amper = False;
   char           holder[TOKENSTRLEN];
   int            i;

   template = the_stmt->the_funct->the_code;

   fprintf(the_file, "\t");

   /* follow the template, printing out the appropriate code for each block */
   while (template->next_code != NULL)
   {

      /* print out the raw code from the template */
      tmp_str = template->code_str;
      while (tmp_str->nextstr != NULL)
      {
         fprintf(the_file, "%s\n", tmp_str->the_string);
         tmp_str = tmp_str->nextstr;
      }
      fprintf(the_file, "%s", tmp_str->the_string);      

      /* print out the user entered parameters */   
      if (template->param_type != -1)
      {
         param_finder = the_stmt->the_funct->parameters;
         param = the_stmt->parameters;

         while (!((param_finder->param_type == template->param_type) && 
                  (param_finder->param_num == template->param_num)))
         {
            param_finder = param_finder->next_param;
            param = param->more_param;
            if ((param_finder == NULL) || (param == NULL))
            {
               printf("Error in compiler code found! Statement not generated correctly\n"
                      "because parameter not found. Please inform Slate or Marty about\n"
                      "this.\n");
               return;
            }
         }
         /* if the parameter is a function, print that out */
         if (param->funct_param != NULL)
         {
            gen_stmt(param->funct_param, the_file, the_hash, False); 
         }

         /* else it is a string or an identifier */
         else
         {
            /* see if it has an amperstand, meaning it would be an identifier of type 
               <TYPE>_<ZONE>_<ITEMNAME> */
            for (i=0; i < strlen(param->the_param->the_string); i++)
            {
               if (param->the_param->the_string[i] == '@')
                  has_amper = True;
            }
 
            /* if it has an amperstand, convert it to proper form */
            if (has_amper)
            {
               for (i=0; i < strlen(param->the_param->the_string); i++)
               {
                  if (param->the_param->the_string[i] == '@')
                     holder[i] = '_';
                  else
                     holder[i] = toupper(param->the_param->the_string[i]);
               }
               fprintf(the_file, "%s", holder);
            }
       
            /* else just display it */
            else
            {
               tmp_str = param->the_param;
               while (tmp_str->nextstr != NULL)
               {
                  if (param->has_quotes)
                     fprintf(the_file, "\"");
                  fprintf(the_file, "%s", tmp_str->the_string);
                  if (param->has_quotes)
                     fprintf(the_file, "\"\n");
                  else
                     fprintf(the_file, "\n");
                  tmp_str = tmp_str->nextstr;
               }
               if (param->has_quotes)
                  fprintf(the_file, "\"");
               fprintf(the_file, "%s", tmp_str->the_string);
               if (param->has_quotes)
                  fprintf(the_file, "\"");
            }
         }
      }
      template = template->next_code;     
   }
   tmp_str = template->code_str;
    while (tmp_str->nextstr != NULL)
   {
      fprintf(the_file, "%s\n", tmp_str->the_string);
      tmp_str = tmp_str->nextstr;
   }
   fprintf(the_file, "%s", tmp_str->the_string);

   if (print_semicolon)
      fprintf(the_file, ";\n");
}

/**************************************************************************
 **
 ** gen_raw
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_raw(raw_decl *the_stmt, FILE *the_file)
{
   string_record *tmp_str;

   tmp_str = the_stmt->the_code;
 
   while (tmp_str != NULL)
   {
      fprintf(the_file, "\t%s\n", tmp_str->the_string);
      tmp_str = tmp_str->nextstr;
   }
   /*fprintf(the_file,"\tbreak;\n");*/
}


/**************************************************************************
 **
 ** gen_block
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_block(block_decl *the_stmt, FILE *the_file, 
                                                hashTable *the_hash)
{
   fprintf(the_file, "\t{\n");
   gen_statements(the_stmt->block_statements, the_file, the_hash);
   fprintf(the_file, "\t}\n");
   return;
}


/**************************************************************************
 **
 ** gen_if
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_if(if_decl *the_stmt, FILE *the_file, hashTable *the_hash)
{
   fprintf(the_file, "\tif (");
   gen_bool_exp(the_stmt->bool_exp, the_file, the_hash);
   fprintf(the_file, ")");

   fprintf(the_file, "\n\t{\n");
   gen_statements(the_stmt->if_statements, the_file, the_hash);
   fprintf(the_file, "\t}\n");

   if (the_stmt->else_statements != NULL)
   {
      fprintf(the_file, "\telse\n\t{\n");
      gen_statements(the_stmt->else_statements, the_file, the_hash);
      fprintf(the_file, "\t}\n");
   }
   return;
}


/**************************************************************************
 **
 ** gen_repeat
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_repeat(while_decl *the_stmt, FILE *the_file, 
                                                hashTable *the_hash)
{
   fprintf(the_file, "\tdo\n\t{\n");

   gen_statements(the_stmt->while_statements, the_file, the_hash);
   fprintf(the_file, "\t}\n\twhile (");
   gen_bool_exp(the_stmt->bool_exp, the_file, the_hash);
   fprintf(the_file, ");\n");
   return;
}

/**************************************************************************
 **
 ** gen_while
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_while(while_decl *the_stmt, FILE *the_file, 
                                                hashTable *the_hash)
{
   fprintf(the_file, "\twhile (");
   gen_bool_exp(the_stmt->bool_exp, the_file, the_hash);
   fprintf(the_file, ")\n\t{\n");
   gen_statements(the_stmt->while_statements, the_file, the_hash);
   fprintf(the_file, "\t}\n");
   return;
}

/**************************************************************************
 **
 ** gen_for
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_for(for_decl *the_stmt, FILE *the_file, 
                                                hashTable *the_hash)
{
   fprintf(the_file, "\t{\n"
                     "\tint gti;\n"
                     "\tfor(gti = %d; gti <= %d; gti++)\n"
                     "\t{\n", the_stmt->from, the_stmt->to);
   gen_statements(the_stmt->for_statements, the_file, the_hash);
   fprintf(the_file, "\t}\n"
                     "\t}\n");

}

/**************************************************************************
 **
 ** gen_stmt
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_stmt(stmt_record *the_stmt, FILE *the_file, 
                                              hashTable *the_hash, Boolean print_semicolon)
{
   switch(the_stmt->stmt_type)
   {
      case STMT_VAR_DECL:         
      case STMT_CONST_DECL:
         break;
      case STMT_FOR_LOOP:
         gen_for(the_stmt->stmt.for_d, the_file, the_hash);
         break;
      case STMT_WHILE_LOOP:
         gen_while(the_stmt->stmt.while_d, the_file, the_hash);
         break;
      case STMT_REPEAT_UNTIL:
         gen_repeat(the_stmt->stmt.while_d, the_file, the_hash);
         break;
      case STMT_IF_THEN:
         gen_if(the_stmt->stmt.if_d, the_file, the_hash);
         break;
      case STMT_BLOCK:
         gen_block(the_stmt->stmt.block_d, the_file, the_hash);
         break;
      case STMT_RAW_CODE: 
         gen_raw(the_stmt->stmt.raw_d, the_file);
         break;
      case STMT_MUD_DEFINED:
	   gen_mud_defined(the_stmt->stmt.mudfunct_d, the_file, the_hash, print_semicolon);
         break;
      case STMT_ARITH_STR:
      case STMT_ARITH_NUM:
         break;
      case STMT_IDENT:
         gen_ident(the_stmt->stmt.ident_d, the_file, the_hash);
         break;
      case STMT_ASSIGNMT:
         gen_assignmt(the_stmt->stmt.assignmt_d, the_file, the_hash);
         break;
      default:
         printf("Unexpected function found!\n"); 
         break;
   }

}

/**************************************************************************
 **
 ** gen_statements
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_statements(stmt_list_record *the_stmt, FILE *the_file, 
                                              hashTable *the_hash)
{
   stmt_list_record *tmp_stmt;

   tmp_stmt = the_stmt;

   if (is_first)
      is_first = False;
   else
      xgen_identifiers(the_stmt, the_file);
   
   while (tmp_stmt != NULL)
   {
      if (tmp_stmt->the_statement == NULL)
         printf("ERROR, found empty statement structure.\n");
      gen_stmt(tmp_stmt->the_statement, the_file, the_hash, True);
      tmp_stmt = tmp_stmt->more_statements;
   }

}


/**************************************************************************
 **
 ** gen_mudcode
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void gen_mudcode(trap_record *the_trap, FILE *data_file, char *type, 
                 zone_record *thezone, char *itemname, FILE *the_file,
                                                  hashTable *the_hash)
{
   char        the_item[(MAXNAMLEN*2)+5];
   char        *lower_item;  
   trap_record *tmp_trap;
   trap_desc   *tmp_verbs;
   Boolean     preceed_else = False;
   Boolean     needs_if = True;

   sprintf(the_item, "%s_%s_%s", type, thezone->zonefile, itemname); 
   lower_item = xlowercase(the_item, (MAXNAMLEN*2)+5);
   fprintf(data_file, "  { %s,  %s},\n", uppercase(the_item), 
                                         lower_item);
   
   fprintf(the_file, "EVENT_HANDLER(%s)\n"
                     "{\n", lower_item);
   fprintf(proto_file,"EVENT_HANDLER(%s);\n",lower_item);

   tmp_trap = the_trap;
   gen_identifiers(tmp_trap, the_file);

   xfree(lower_item,REC_CHAR);

   while (tmp_trap != NULL)
   {
      tmp_verbs = tmp_trap->trap_verb;
      while (tmp_verbs != NULL)
      {  if (needs_if)
            fprintf(the_file,"  %s if (",preceed_else ? "else" : "");

         fprintf(the_file, "%s(%s) ", needs_if? "" : "||\n       ",
                 find_event_check(tmp_verbs->trap_verb));

         preceed_else = True;
         needs_if = False;
         tmp_verbs = tmp_verbs->next_desc;
      }

      fprintf(the_file,")\n   {\n");

      if (tmp_trap->the_statements == NULL)
      {   if (tmp_trap->trap_verb->trap_location != '\0')
          {   /* We are dealing with an external definition */
              char extern_funcname[120];
              char *extern_item;
              char *extern_zone;

              extern_item = tmp_trap->trap_verb->trap_location;
              extern_zone = index(extern_item,'@');

              if (extern_zone == NULL)
                 extern_zone = thezone->zonefile;
              else
              {   *extern_zone = '\0';
                  extern_zone++;
              }
              /* Now we know where the original trap is, so we add a function
               * call to the code.
               */
              sprintf(extern_funcname,"%s_%s_%s",type,extern_zone,extern_item);
              fprintf(the_file,"\t  /* Trap uses external event in %s@%s */\n"
                               "\t  %s(event);\n",
                               extern_item,extern_zone,lowercase(extern_funcname));
          }
          else
             printf("Warning: trap %s defined for %s@%s, but no code found.\n",
                 find_event_name(tmp_trap->trap_verb->trap_verb),itemname, thezone->zonename);
      }
      else 
      {
          is_first = True;
          gen_statements(tmp_trap->the_statements, the_file, the_hash);
      }
      tmp_trap = tmp_trap->more_traps;
      needs_if = True;
      fprintf(the_file,"   }\n");
   }

   fprintf(the_file,"}\n\n");
}

/**************************************************************************
 **                             GENERATION FUNCTIONS
 *************************************************************************/

/**************************************************************************
 **
 ** print_loc
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

void print_loc(hashTable *the_hash, char *the_dir, zone_record *thezone, 
                                                      FILE *data_file)
{
   hashRecord      *this_hash;

   if (the_dir != NULL)
   {
      if (*the_dir == '#')
      {
         fprintf(data_file, " %d", atoi(the_dir+1));
      }
      else
      {
         this_hash = findHashRecord(convert_item(the_hash, the_dir, 
                                    thezone->zonefile, "loc"), the_hash);
         if (this_hash == NULL)
         {  printf("Error looking up %s\n",
                  convert_item(the_hash, the_dir, thezone->zonefile, "loc"));
            panicError("Code generation failed due to a lookup error.\n");
         }
         if (this_hash->idnumber >= 0)
             fprintf(data_file, " %ld ", this_hash->idnumber + DOOR); 
         else
             fprintf(data_file, " %ld ", this_hash->idnumber); 
      }
   }
   else
      fprintf(data_file, " 0 ");

}

/**************************************************************************
 **
 ** gen_zone_include
 **
 ** Creates the zone header file
 ***************************************************************************/
int gen_zone_include(hashTable *the_hash, zone_record *thezone)
{   
    if (thezone->code != NULL)
    {   if (zon_file == NULL)
        {   gen_zon_header(thezone);
        }
        gen_statements(thezone->code,zon_file,the_hash); 
        
        fprintf(zon_file,"#endif\n");
        if (zon_file)
           fclose(zon_file);
        has_zone_header = True;
        zon_file = NULL;
    }
    return 1;
}

/**************************************************************************
 **
 ** gen_locations
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

int gen_locations(hashTable *the_hash, zone_record *thezone, 
                  FILE *def_file, FILE *data_file, FILE *code_incl, 
                  FILE *code_tabl, FILE *zones_data, int zonenum)
{
   location_record *tmp_loc;
   location_record *find_last;
   char            hash_str[(MAXNAMLEN*2)+5];
   hashRecord      *this_hash;
   long            last_num;
   Boolean         first = True;
   Boolean 	   first_line = True;
   Boolean         needs_include = True;
   string_record   *tmp_str;

   tmp_loc = thezone->location_data;

   fprintf(def_file,"/* ZONE: %s\n */\n",thezone->zonefile);
   /* loop through getting the last location number */
   find_last = tmp_loc;
   while (find_last != NULL)
   {
      sprintf(hash_str, "loc@%s@%s", thezone->zonefile, find_last->name);
      lowercase(hash_str);
      this_hash = findHashRecord(hash_str, the_hash);
      if (this_hash == NULL)
      {   printf("Error looking up %s\n",hash_str);
          panicError("Code generation failed due to a lookup error.\n");
          exit(2);
      }
      last_num = this_hash->idnumber;
      find_last = find_last->next_loc;
   }

   /* loop through all locations, writing data */
   while (tmp_loc != NULL)
   {
      /* get this hash record */
      sprintf(hash_str, "loc@%s@%s", thezone->zonefile, tmp_loc->name);
      lowercase(hash_str);
      this_hash = findHashRecord(hash_str, the_hash);
      if (this_hash == NULL)
      {   printf("Error looking up %s\n",hash_str);
          panicError("Code generation failed due to a lookup error.\n");
      }

      /* write locmin and locmax info to the define file */
      if (first)
      {
         fprintf(zones_data, "%s %ld\n", thezone->zonefile, -(this_hash->idnumber)-1);

         strcpy(hash_str, thezone->zonefile);
         uppercase(hash_str);
         fprintf(def_file, "#define LOCMIN_%s %ld\n", hash_str, (this_hash->idnumber+1));
         fprintf(def_file, "#define LOCMAX_%s %ld\n", hash_str, last_num);
         first = False;
      }

      /* write this info to the define file */
      sprintf(hash_str, "loc_%s_%s", thezone->zonefile, tmp_loc->name);
      uppercase(hash_str);
      fprintf(def_file, "#define %s %ld\n", hash_str, this_hash->idnumber);

      /* write the location data to the data file */
      fprintf(data_file, "%ld %d", this_hash->idnumber, zonenum);


      print_loc(the_hash, tmp_loc->north, thezone, data_file);
      print_loc(the_hash, tmp_loc->east, thezone, data_file);
      print_loc(the_hash, tmp_loc->south, thezone, data_file);
      print_loc(the_hash, tmp_loc->west, thezone, data_file);
      print_loc(the_hash, tmp_loc->up, thezone, data_file);
      print_loc(the_hash, tmp_loc->down, thezone, data_file);
      print_loc(the_hash, tmp_loc->northeast, thezone, data_file);
      print_loc(the_hash, tmp_loc->northwest, thezone, data_file);
      print_loc(the_hash, tmp_loc->southeast, thezone, data_file);
      print_loc(the_hash, tmp_loc->southwest, thezone, data_file);


      fprintf(data_file, "\n0x%08lx:0x%08lx:0x%08lx\n"
                         "%s^\n", tmp_loc->lflags.b1, tmp_loc->lflags.b2, 
                                  tmp_loc->lflags.b3, tmp_loc->title);
            
      tmp_str = tmp_loc->desc;
      first_line = True;
      while (tmp_str != NULL && strlen(tmp_str->the_string) == 0)
            tmp_str = tmp_str->nextstr;

      while (tmp_str != NULL)
      {  if (tmp_str->the_string[0] == '\n' && first_line)
            fprintf(data_file, "%s\n", tmp_str->the_string+1);
         else
            fprintf(data_file, "%s\n", tmp_str->the_string);
         tmp_str = tmp_str->nextstr;
         first_line = False;
      }
      fprintf(data_file, "^\n");

      if (tmp_loc->loc_code != NULL)
      {
         if (loc_file == NULL)
	 {  if (needs_include)
            {   fprintf(code_incl, "#include \"%s.c\"\n", thezone->zonefile);
                needs_include = False;
            }
            gen_loc_header(thezone);
         }
         gen_mudcode(tmp_loc->loc_code, code_tabl, "loc", thezone,
                                     tmp_loc->name, loc_file, the_hash);
      }

      /* get new location */
      tmp_loc = tmp_loc->next_loc;
   }

   if (loc_file)
      fclose(loc_file);
   loc_file = NULL;
   return 1;
}

/**************************************************************************
 **
 ** gen_objects
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone data stored in it or 
 **       attached to it
 **
 *************************************************************************/

int gen_objects(hashTable *the_hash, zone_record *thezone, FILE *def_file, 
                FILE *data_file, FILE *code_incl, FILE *code_tabl, 
                                                            int zonenum)
{
   object_record *tmp_obj;
   hashRecord      *this_hash;
   char            hash_str[(MAXNAMLEN*2)+5];
   string_record   *tmp_str;
   int             i;
   char            *type;
   Boolean         needs_include = True;

   tmp_obj = thezone->object_data;

   fprintf(def_file,"/* ZONE: %s\n */\n",thezone->zonefile);

   while (tmp_obj != NULL)
   {
      /* get the hash record */
      sprintf(hash_str, "obj@%s@%s", thezone->zonefile, tmp_obj->oname);
      lowercase(hash_str);
      this_hash = findHashRecord(hash_str, the_hash);
      if (this_hash == NULL)
      {   printf("Error looking up %s\n",hash_str);
          panicError("Code generation failed due to a lookup error.\n");
      }

      /* write this data to the define file */
      sprintf(hash_str, "obj_%s_%s", thezone->zonefile, tmp_obj->oname);
      uppercase(hash_str);
      fprintf(def_file, "#define %s %ld\n", hash_str, this_hash->idnumber);

      /* write this data to the data file */
      fprintf(data_file, "%s %s %d %ld %ld ",
              (tmp_obj->name == NULL) ? tmp_obj->oname : tmp_obj->name,
              (tmp_obj->altname == NULL) ? "<null>" : tmp_obj->altname,
              zonenum, this_hash->idnumber, this_hash->idnumber);

      if (tmp_obj->linked != NULL)
      {
         this_hash = findHashRecord(convert_item(the_hash, tmp_obj->linked, 
                                    thezone->zonefile, "obj"), the_hash);
         fprintf(data_file, "%ld ", this_hash->idnumber); 
      }
      else
         fprintf(data_file, "-1 ");

      fprintf(data_file, "%d %d ", tmp_obj->vis, 
                                  get_cflag(tmp_obj->location->loc_type));

      if (tmp_obj->location->loc_type == T_INROOM)
         type = "loc";
      else if (tmp_obj->location->loc_type == T_INCONTAINER) 
         type = "obj";
      else      
         type = "mob";


      this_hash = findHashRecord(convert_item(the_hash, 
                  tmp_obj->location->the_loc, thezone->zonefile, type), 
                  the_hash);
      if (this_hash == NULL)
      {   printf("Error looking up %s\n",convert_item(the_hash, 
                  tmp_obj->location->the_loc, thezone->zonefile, type));
          panicError("Code generation failed due to a lookup error.\n");
      }
      fprintf(data_file, "%ld ", this_hash->idnumber); 


      fprintf(data_file, "%d %d %d %d %d %d %d\n"
                         "0x%08lx:0x%08lx:0x%08lx", 
               tmp_obj->state, tmp_obj->damage, 
               tmp_obj->armor, tmp_obj->maxstate, tmp_obj->basevalue,
               tmp_obj->size, tmp_obj->weight, tmp_obj->oflags.b1, 
               tmp_obj->oflags.b2, tmp_obj->oflags.b3);


      for (i=0; i<4; i++)
      {
         tmp_str = tmp_obj->desc[i];

         while (tmp_str != NULL && strlen(tmp_str->the_string) == 0)
                tmp_str = tmp_str->nextstr;

         if (tmp_str == NULL)
               fprintf(data_file, "\n");

         while (tmp_str != NULL)
         {
            fprintf(data_file, "\n");
            fprintf(data_file, "%s", tmp_str->the_string);
            tmp_str = tmp_str->nextstr;
         }
         fprintf(data_file, "^");
      }
    

      fprintf(data_file, "\n");


      tmp_str = tmp_obj->examine;

      while (tmp_str != NULL && strlen(tmp_str->the_string) == 0)
             tmp_str = tmp_str->nextstr;

      while (tmp_str != NULL)
      {
         fprintf(data_file, "%s\n", tmp_str->the_string);
         tmp_str = tmp_str->nextstr;
      }
      fprintf(data_file, "^\n\n");

      if (tmp_obj->obj_code != NULL)
      {
         if (obj_file == NULL)
	 {  if (needs_include)
            {   fprintf(code_incl, "#include \"%s.c\"\n", thezone->zonefile);
                needs_include = False;
            }
            gen_obj_header(thezone);
         }
         gen_mudcode(tmp_obj->obj_code, code_tabl, "obj", thezone, 
                                 tmp_obj->oname, obj_file, the_hash);
      }

      /* go to next object */
      tmp_obj = tmp_obj->next_obj;
   }

   if (obj_file)
      fclose(obj_file);
   obj_file = NULL;
   return 1;
}


/**************************************************************************
 **
 ** gen_mobiles
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all 
 **
 *************************************************************************/

int gen_mobiles(hashTable *the_hash, zone_record *thezone, FILE *def_file, 
                FILE *data_file, FILE *code_incl, FILE *code_tabl, 
                                                             int zonenum)
{
   mobile_record *tmp_mob;
   hashRecord      *this_hash;
   char            hash_str[(MAXNAMLEN*2)+5];
   string_record   *tmp_str;
   Boolean         needs_include = True;
   tmp_mob = thezone->mobile_data;

   fprintf(def_file,"/* ZONE: %s\n */\n",thezone->zonefile);

   while (tmp_mob != NULL)
   {
      /* get this hash record */
      sprintf(hash_str, "mob@%s@%s", thezone->zonefile, tmp_mob->mname);
      lowercase(hash_str);
      this_hash = findHashRecord(hash_str, the_hash);
      if (this_hash == NULL)
      {   printf("Error looking up %s\n",hash_str);
          panicError("Code generation failed due to a lookup error.\n");
      }

      /* write this info to the define file */
      sprintf(hash_str, "mob_%s_%s", thezone->zonefile, tmp_mob->mname);
      uppercase(hash_str);
      fprintf(def_file, "#define %s %ld\n", hash_str, this_hash->idnumber);

      
      tmp_mob->mname[0] = toupper(tmp_mob->mname[0]);
      /* record mobile data in datafile */
      fprintf(data_file, "%s^\n"
                         "%ld %ld %d ", 
              (tmp_mob->name == NULL) ? tmp_mob->mname : tmp_mob->name, 
              this_hash->idnumber, this_hash->idnumber, zonenum);
      tmp_mob->mname[0] = tolower(tmp_mob->mname[0]);

      this_hash = findHashRecord(convert_item(the_hash, 
                  tmp_mob->location->the_loc, thezone->zonefile, "loc"), 
                  the_hash);
      fprintf(data_file, "%ld ", this_hash->idnumber);    

      fprintf(data_file, "%d %d %d %d %d %d %d\n"
                         "0x%08lx:0x%08lx:0x%08lx 0x%08lx:0x%08lx:0x%08lx\n"
                         "0x%08lx:0x%08lx\n", 
               tmp_mob->strength, tmp_mob->damage, 
               tmp_mob->aggr, tmp_mob->armor, tmp_mob->speed,
               tmp_mob->vis, tmp_mob->wimpy, 
               tmp_mob->sflags.b1, tmp_mob->sflags.b2, tmp_mob->sflags.b3,
               tmp_mob->pflags.b1, tmp_mob->pflags.b2, tmp_mob->pflags.b3,
               tmp_mob->mflags.h, tmp_mob->mflags.l);

      tmp_str = tmp_mob->desc;

      while (tmp_str != NULL && strlen(tmp_str->the_string) == 0)
           tmp_str = tmp_str->nextstr;

      while (tmp_str != NULL)
      {
         fprintf(data_file, "%s%s", tmp_str->the_string,
		tmp_str->nextstr == NULL ? "" : "\n");
         tmp_str = tmp_str->nextstr;
      }
      fprintf(data_file, "^\n");

      tmp_str = tmp_mob->examine;
      while (tmp_str != NULL)
      {
         fprintf(data_file, "%s\n", tmp_str->the_string);
         tmp_str = tmp_str->nextstr;
      }
      fprintf(data_file, "^\n\n");


      if (tmp_mob->mob_code != NULL)
      {
         if (mob_file == NULL)
	 {  if (needs_include)
            {   fprintf(code_incl, "#include \"%s.c\"\n", thezone->zonefile);
                needs_include = False;
            }
            gen_mob_header(thezone);
         }
         gen_mudcode(tmp_mob->mob_code, code_tabl, "mob", thezone,
                                tmp_mob->mname, mob_file, the_hash);
      }

      /* get the next mobile record */
      tmp_mob = tmp_mob->next_mob;
   }

   if (mob_file != NULL)
   {  fclose(mob_file);
      mob_file = NULL;
   }
   return 1;
}

/**************************************************************************
 **                          MAIN CODE GENERATION FUNCTION
 *************************************************************************/

/*************************************************************************
 **
 ** gen_code
 **
 ** Parameters: filename - the filename string to open
 **
 ** ret - returns a zone record with all zone datd to it
 **
 *************************************************************************/

int gen_code(hashTable *the_hash, zone_record *thezone)
{
   FILE         *loc_def = NULL;       /* locations.h define file */
   FILE         *obj_def = NULL;       /* objects.h define file */
   FILE         *mob_def = NULL;       /* mobiles.h define file */
   FILE         *zones_data = NULL;    /* zones data file */
   FILE         *loc_data = NULL;      /* locations data file */
   FILE         *obj_data = NULL;      /* locations data file */
   FILE         *mob_data = NULL;      /* locations data file */
   FILE         *quest_data = NULL;    /* quest data file */
   FILE         *author_data = NULL;   /* gets data about the author */
   FILE         *mob_code_incl = NULL; /* mobile include file */
   FILE         *obj_code_incl = NULL; /* object include file */
   FILE         *loc_code_incl = NULL; /* location include file */
   FILE         *mob_code_tabl = NULL; /* Mobile function table file */
   FILE         *obj_code_tabl = NULL; /* Object function table file */
   FILE         *loc_code_tabl = NULL; /* Locations function table file */
   char		*INCLUDE_DIR = request_char_value("INCLUDE_DIR");
   char         *NPC_DIR     = request_char_value("NPC_DIR");
   char         *OBJECTS_DIR = request_char_value("OBJECTS_DIR");
   char         *LOCATIONS_DIR= request_char_value("LOCATIONS_DIR");
   char         *DATABASE_DIR = request_char_value("DATA_DIR");
   int          zone_num = 0;
   int          the_quest;
   time_t	t = time(0);

   zone_record  *tmp_zone; /* used to loop through zone records */

   /* open all the files for writing to */   
   if ((loc_def = safe_open("locations.h", INCLUDE_DIR, "w")) == NULL)
   {
      printf("Error opening locations.h for write. "
             "Terminating code generation.\n");
      return -1;
   }   

   if ((obj_def = safe_open("objects.h", INCLUDE_DIR, "w")) == NULL)
   {
      printf("Error opening objects.h for write. "
             "Terminating code generation.\n");
      return -1;
   }   

   if ((mob_def = safe_open("mobiles.h", INCLUDE_DIR, "w")) == NULL)
   {
      printf("Error opening mobiles.h for write. "
             "Terminating code generation.\n");
      return -1;
   }
   
   if ((zones_data = safe_open("zones", DATABASE_DIR, "w")) == NULL)
   {
      printf("Error opening data file zones for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((loc_data = safe_open("locations", DATABASE_DIR, "w")) == NULL)
   {
      printf("Error opening data file locations for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((obj_data = safe_open("objects", DATABASE_DIR, "w")) == NULL)
   {
      printf("Error opening data file locations for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((mob_data = safe_open("mobiles", DATABASE_DIR, "w")) == NULL)
   {
      printf("Error opening data file locations for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((quest_data = safe_open("zonetab.h",INCLUDE_DIR, "w")) == NULL)
   {
      printf("Error opening data file zonetab.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((author_data = safe_open("authors.h",INCLUDE_DIR, "w")) == NULL)
   {
      printf("Error opening data file zonetab.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((mob_code_incl = safe_open("includemobs.h", NPC_DIR, "w")) == NULL)
   {
      printf("Error opening data file includemobs.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((loc_code_incl = safe_open("includerooms.h", LOCATIONS_DIR, "w")) == NULL)
   {
      printf("Error opening data file includerooms.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((obj_code_incl = safe_open("includeobjects.h",OBJECTS_DIR, "w")) == NULL)
   {
      printf("Error opening data file includeobjects.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((mob_code_tabl = safe_open("mobtable.h", NPC_DIR, "w")) == NULL)
   {
      printf("Error opening data file mobtable.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((loc_code_tabl = safe_open("loctable.h", LOCATIONS_DIR, "w")) == NULL)
   {
      printf("Error opening data file loctable.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((obj_code_tabl = safe_open("objtable.h",OBJECTS_DIR, "w")) == NULL)
   {
      printf("Error opening data file objtable.h for write. \n"
             "Terminating code generation.\n");
      return -1;
   }  

   if ((proto_file = safe_open("prototypes.h",INCLUDE_DIR,"w")) == NULL)
   {   printf("Error opening include file prototypes.h for write.\n"
              "Terminating code generation.\n");
       return -1;
   }

   tmp_zone = thezone;

   /* put the header at the top of the mobiles.h file */
   fprintf(mob_def, ""
       "/*****************************************************************"
       "*********\n"
       " ** MOBILES INCLUDE - Automatically created by gen.\n"
       " ** DO NOT make any changes here, as they will go away !!!\n"
       " ** last update: %s"
       " *****************************************************************"
       "***********/\n"
       "#ifndef _MOBILES_H_\n"
       "#define _MOBILES_H_\n\n", ctime(&t));

   /* put the header at the top of the objects.h file */
   fprintf(obj_def, ""
       "/*****************************************************************"
       "*********\n"
       " ** OBJECTS INCLUDE - Automatically created by gen.\n"
       " ** DO NOT make any changes here, as they will go away !!!\n"
       " ** last update: %s\n"
       " *****************************************************************"
       "***********/\n"
       "#ifndef _OBJECTS_H_\n"
       "#define _OBJECTS_H_\n\n", ctime(&t));
           
   /* put the header at the top of the locations.h file */
   fprintf(loc_def,
       "/*****************************************************************"
       "*********\n"
       " ** LOCATIONS INCLUDE - Automatically created by gen.\n"
       " ** DO NOT make any changes here, as they will go away !!!\n"
       " ** last update: %s\n"
       " *****************************************************************"
       "***********/\n"
       "#ifndef _LOCATIONS_H_\n"
       "#define _LOCATIONS_H_\n\n", ctime(&t));
       
   fprintf(mob_data, "%d\n", cur_mob);
   fprintf(obj_data, "%d\n", cur_obj);
   fprintf(loc_data, "%d\n", -(cur_loc)-1);   
   
   /* print header at head of authors.h file */
   fprintf(author_data, ""
     "/** AUTOMATIC CREATED AUTHORS TABLE - "
     "Do not edit this file, it will go away!\n **/\n"
     "#ifndef AUTHORS_H\n"
     "#define AUTHORS_H\n\n"
     "const char *authortab[] = {\n");

   /* print header at head of zonetab.h file */
   fprintf(quest_data, ""
     "/** AUTOMATIC CREATED ZONE TABLE - "
     "Do not edit this file, it will go away!\n **/\n"
     "#ifndef ZONE_TAB_H\n"
     "#define ZONE_TAB_H\n\n"
     "#include \"quests.h\"\n"
     "const int zonetab[] = {\n");

   /* print header at head of mudcode include files */
   fprintf(obj_code_incl, "#ifndef _OBJ_INCLUDE_OBJECTS_H_\n"
                          "#define _OBJ_INCLUDE_OBJECTS_H_\n\n");

   fprintf(mob_code_incl, "#ifndef _MOB_INCLUDE_MOBS_H_\n"
                          "#define _MOB_INCLUDE_MOBS_H_\n\n");

   fprintf(loc_code_incl, "#ifndef _LOC_INCLUDE_ROOMS_H_\n"
                          "#define _LOC_INCLUDE_ROOMS_H_\n\n");

   /* print header at head of mudcode table files */
   fprintf(obj_code_tabl, "/** AUTOMATIC CREATED OBJECT TABLE - "
                          "Do not edit this file, it will go away.\n **/\n"
                          "#ifndef OBJ_TABLE_H\n"
                          "#define OBJ_TABLE_H\n\n"
                          "MAPPING(obj_table) =\n"
                          "{\n");

   fprintf(mob_code_tabl, "/** AUTOMATIC CREATED MOBILE TABLE - "
                          "Do not edit this file, it will go away.\n **/\n"
                          "#ifndef MOB_TABLE_H\n"
                          "#define MOB_TABLE_H\n\n"
                          "MAPPING(mob_table) =\n"
                          "{\n");

   fprintf(loc_code_tabl, "/** AUTOMATIC CREATED LOCATION TABLE - "
                          "Do not edit this file, it will go away.\n **/\n"
                          "#ifndef LOC_TABLE_H\n"
                          "#define LOC_TABLE_H\n\n"
                          "MAPPING(loc_table) =\n"
                          "{\n");


   fprintf(proto_file,"/** AUTOMATIC CREATED PROTOTYPES FILE - Do not edit, it will go away.\n **/\n"
           "#ifndef EVENT_PROTOTYPES_H\n"
           "#define EVENT_PROTOTYPES_H\n\n");

   /* print header at top of zones file */   
   fprintf(zones_data, "%d\n", num_zones);

   while (tmp_zone != NULL)
   {  printf("\r     Creating information for zone %-20.20s",tmp_zone->zonename);
      fflush(stdout);

      /* write quest info */
      if (tmp_zone->quest != NULL)
      {
         if ((the_quest = get_quest(tmp_zone->quest)) == -1)
            printf("Warning - Quest %s not recognized in %s zone, "
                   "leaving it out.\n", 
                   tmp_zone->quest, tmp_zone->zonefile);
         else
            fprintf(quest_data, "\t%d,\t%d,\n", zone_num, the_quest);
      }

      /* write author info */
      if (tmp_zone->author == NULL)
         fprintf(author_data, "\t\"Unknown\",\n");
      else
         fprintf(author_data, "\t\"%s\",\n", tmp_zone->author);

      /* generate location/object/mobile info */
      if ((gen_zone_include(the_hash,tmp_zone) == -1) ||
          (gen_locations(the_hash, tmp_zone, loc_def, loc_data, 
                         loc_code_incl, loc_code_tabl, zones_data, 
                                                      zone_num) == -1) ||
          (gen_objects(the_hash, tmp_zone, obj_def, 
                        obj_data, obj_code_incl, obj_code_tabl, 
                                                      zone_num) == -1) ||
          (gen_mobiles(the_hash, tmp_zone, mob_def, 
                           mob_data, mob_code_incl, mob_code_tabl, 
                                                      zone_num) == -1))
      {
         printf("Unexpected error in code generation. "
                "Terminating generate\n");
         return -1;
      }
      tmp_zone = tmp_zone->next_zone;
      zone_num++;
      has_zone_header = False;
   } 

   fprintf(loc_def, "\n#endif\n");
   fprintf(mob_def, "\n#endif\n");
   fprintf(obj_def, "\n#endif\n");

   fprintf(quest_data, "\t-1,\t-1\n" 
                       "};\n\n"
                       "#endif\n");

   fprintf(author_data, "\tTABLE_END\n" 
                       "};\n\n"
                       "#endif\n");

   fprintf(obj_code_incl, "\n#endif\n");
   fprintf(mob_code_incl, "\n#endif\n");
   fprintf(loc_code_incl, "\n#endif\n");
   fprintf(proto_file,"\n#endif\n");

   fprintf(obj_code_tabl, "  { -1, NULL }\n"
                          "};\n\n"
                          "#endif\n");

   fprintf(mob_code_tabl, "  { -1, NULL }\n"
                          "};\n\n"
                          "#endif\n");

   fprintf(loc_code_tabl, "  { -1, NULL }\n"
                          "};\n\n"
                          "#endif\n");

   
   fclose(zones_data);
   fclose(loc_def);
   fclose(loc_data);
   fclose(obj_def);
   fclose(obj_data);
   fclose(mob_def);
   fclose(mob_data);
   fclose(quest_data);
   fclose(author_data);
   fclose(loc_code_incl);
   fclose(mob_code_incl);
   fclose(obj_code_incl);
   fclose(loc_code_tabl);
   fclose(mob_code_tabl);
   fclose(obj_code_tabl);
   fclose(proto_file);
   return 1;
}