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/
/*****************************************************************************
 ** Module     : events.c
 ** Author     : Peter Eussen
 ** Description: These functions read in the events library and has search
 **              routines which can be used from other modules to find events
 **              by name or id and a routine to give the c-format check which
 **              is needed to check if that specific event has occured.
 **
 **              It uses the config variable MAX_EVENTS to specify the maximum
 **              amount of events it can store. (See config.c for specifics on
 **              how config variables can be retrieved and used.
 *****************************************************************************/
#define EVENTS_C
#include <stdlib.h>
#include "events.h"
#include "gen.h"
#include "hash.h"
#include "lexer.h"
#include "config.h"

/******************************************************************************
 **                                VARIABLES
 *****************************************************************************/
static event_record *events= NULL;
static last_in_table = -1;

/******************************************************************************
 **
 ** last_event - returns the number of the last event that has been read from 
 **              the event library file.
 **
 ** Parameters: none.
 ** Returns: -1 if table is empty, value between 0 and MAX_EVENTS if table is
 **          filled.
 *****************************************************************************/
int last_event(void)
{   return last_in_table;
}

/******************************************************************************
 **
 ** find_event_name - Finds the name of a specific event when a eventid is 
 **                   given.
 **
 ** Parameters: num - Event number of an event that is in the table.
 ** Returns   : NULL if the number is out of range.
 **             string with the name of the event.
 *****************************************************************************/
char *find_event_name(int num)
{   if (num < 0 || num > last_in_table)
        return "<Illegal event>";

    return events[num].event;
}

/******************************************************************************
 **
 ** find_event_num - Finds the eventid of an event.
 **
 ** Parameters: event - a string with the name of an event.
 ** Returns   : -1 if event is not found, integer value >= 0 if value is found.
 *****************************************************************************/
int find_event_num(char *event)
{   int i;

    for (i=0;i <= last_in_table; i++)
    {   if (strcasecmp(events[i].event,event) == 0)
            return i;
    }
    return -1;
}

/****************************************************************************
 ** 
 ** find_event_check - Finds an boolean-check-statement that can be used in
 **                    an c-style if-statement.
 ** 
 ** Parameters: event - a number that indicates the desired event.
 ** Returns: NULL if event was invalid,
 **          string containing the boolean statement.
 ***************************************************************************/
char *find_event_check(int event)
{   if (event > last_in_table || event < 0)
       return NULL;
    return events[event].event_check;
}

void cleanup_events(void)
{   int i,l;

    l = last_event();

    for (i=0; i <= l; i++)
    {   xfree(events[i].event_check,REC_CHAR);
    }
    xfree(events,REC_EVENT);
}

/*****************************************************************************
 ** 
 ** load_events - Loads the events from file.
 **
 ** Parameters: event_file - Filename of the event library.
 ** Returns   : < 0 if an error occured. 0 if everything went ok.
 ****************************************************************************/
int load_events(char *event_file)
{   FILE         *fp;			/* File pointer for the opened lib file */
    token_record *current_token;	/* For reading of the file */
    int          event_counter =0;	/* Counts how many events we have read */
    char         read_until;		/* Needed to read out the value behind
                                         * the equal sign.
                                         */

    /* Try opening the file with the lexer 
     */
    fp = xfopen(event_file);

    if (fp == NULL)
    {   fprintf(stderr,"Unable to find event code file %s.\n",event_file);
        return -1;
    }

    printf(" [2] Loading Events Library... ");

    /* Request the MAX_EVENTS value and allocate the table
     */
    events = memAlloc(event_record,request_int_value("MAX_EVENTS"),REC_EVENT);

    if (events == NULL)
    {   fprintf(stderr,"Unable to allocate event table.\n");
        return -1;
    }

    /* Main readout routine.
     * 
     * The format should be so that you can have comments (which start with
     * the '#' sign) before and after a definition.
     */
    current_token = get_token(fp,'\n',False);
    while (current_token->token_type > 0)
    {   
        /* Check for comment */
        if (current_token->token_type == T_POUND)
            next_line(fp);
        else
        {   /* We should have an event name here, but not a duplicate */
            if (find_event_num(current_token->the_string) >= 0) 
            {   fprintf(stderr,"Duplicate definition of event %s.\n",
                        current_token->the_string);
                fclose(fp);
                return -1;
            }

            /* Okay it wasnt a duplicate, so add it */
            strcpy(events[event_counter].event,current_token->the_string);

            /* Next in line should be an '=' sign */
            current_token = get_token(fp,'\n',False);

            if (current_token->token_type != T_EQUALS)
            {    fprintf(stderr,"Error in event file, expected an equals sign after %s\n",
                              events[event_counter].event);
                 fclose(fp);
                 return -1;
            }

            /* Check the value after the equal sign */
            current_token = get_token(fp,'\n',False);

            /* If its a " a ' or an `, then we assume its a start of a quoted
             * string, so we should read one more token.
             */
            if (current_token->token_type != T_QUOTE && 
                current_token->token_type != T_APOST &&
                current_token->token_type != T_RIGHTAPOST)
            {   fprintf(stderr,"Error in event file, expected an \", ' or ` in event %s\n",
                        events[event_counter].event);
                fclose(fp);
                return -1;
            }

            read_until = current_token->the_string[0];
            current_token = get_token(fp,read_until,False);

            if (current_token->token_type != T_STRING)
            {   fprintf(stderr,"Error in event file, expected an identifier for event %s, found %d\n",
                        events[event_counter].event,current_token->token_type);
                fclose(fp);
                return -1;
            }

            events[event_counter].event_check = memAlloc(char,strlen(current_token->the_string) +1,REC_CHAR);

            if (events[event_counter].event_check == NULL)
            {  fclose(fp);
               return -1;
            }
            strcpy(events[event_counter].event_check,current_token->the_string);
            event_counter++;
        }
        current_token = get_token(fp,'\n',False);
    }
    printf("Succesful.\n");
    last_in_table = event_counter-1;
    fclose(fp);
    return 0;
}