#define SEMANTIC_C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gen.h"
#include "semantic.h"
char thetype[15];
string_record *var_list;
/*****************************************************************************
** PROTOTYPE FUNCTIONS
****************************************************************************/
Boolean check_statements(hashTable *the_hash, stmt_list_record *stmts,
char *in_name, zone_record *thezone);
Boolean check_defined(hashTable *the_hash, stmt_record *stmt, char *in_name,
zone_record *thezone);
Boolean check_stmt(hashTable *the_hash, stmt_record *stmt,
char *in_name, zone_record *thezone);
/*****************************************************************************
** UTILITY FUNCTIONS
****************************************************************************/
/********************************************************************************
**
** sem_error
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
void sem_error(char *the_err, char *thezone, char *theitem, Boolean is_warning)
{ extern Boolean supress_warnings;
if ((!supress_warnings) || (!is_warning))
printf("[%-12s] %s - in %s %s@%s\n", thezone, the_err, thetype, theitem,thezone);
return;
}
/******************************************************************************
**
** has_amperstand
**
** Parameters:
** str : a object name that needs to be checked for validity
**
** ret - True if name is valid, False if name is invalid
*****************************************************************************/
Boolean has_amperstand(char *str)
{ int i;
for (i=0; i<strlen(str); i++)
{
if (*str == '@')
return True;
str++;
}
return False;
}
/******************************************************************************
**
** verify_gamename
**
** Parameters:
** str : a object name that needs to be checked for validity
**
** ret - True if name is valid, False if name is invalid
*****************************************************************************/
Boolean verify_gamename(char *str)
{ int i;
for (i = 0; i < strlen(str); i++)
{ if (!isalpha(str[i]) && str[i] != '-')
return False;
}
return True;
}
/********************************************************************************
**
** verify_item
**
** Parameters:
** the_hash: Hashtable with all names in it
** the_loc : the item to verify.
** zone : the zone that is the owner of the item.
** type : the type of item to look up (either "mob","loc","obj"
**
** ret - True if found, False if not found
**
********************************************************************************/
Boolean verify_item(hashTable *the_hash, char *the_loc, char *zone, char *type)
{
char fullloc[(MAXNAMLEN*2)+5]; /* holds location string */
Boolean has_amper = False; /* if it has an amperstand in it */
char *check_ptr; /* used to move along the string */
char *tempstr;
char *s;
if (*the_loc == '#')
return True;
/* The way it was done first was wrong because the entries in the hashtable
* are of the format <type>@<zone>@<name>
*/
s=tempstr=xlowercase(the_loc,strlen(the_loc) + 1);
if ((check_ptr = index(tempstr,'@')) != NULL)
{ *check_ptr = '\0';
check_ptr++;
has_amper = True;
}
if (*tempstr == '^')
{ tempstr++;
type = "obj";
}
#if 0
has_amper = has_amperstand(check_ptr);
if (*the_loc == '^')
{
the_loc++;
type = "obj";
}
tempstr=xlowercase(the_loc,strlen(the_loc) + 1);
#endif
if (has_amper)
sprintf(fullloc, "%s@%s@%s", type, check_ptr, tempstr);
else
sprintf(fullloc, "%s@%s@%s", type, zone, tempstr);
xfree(s,REC_CHAR);
/*printf("Checking for \"%s\"\n",fullloc); */
if (findHashRecord(fullloc, the_hash) == NULL)
return False;
else
return True;
}
/********************************************************************************
**
** verify_location
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean verify_location(hashTable *the_hash, loc_str_record *the_loc, zone_record *thezone)
{
if ((the_loc->loc_type == T_WIELDEDBY) || (the_loc->loc_type == T_WORNBY) ||
(the_loc->loc_type == T_BOTHBY) || (the_loc->loc_type == T_CARRIEDBY))
return verify_item(the_hash, the_loc->the_loc, thezone->zonename, "mob");
if (the_loc->loc_type == T_INROOM)
return verify_item(the_hash, the_loc->the_loc, thezone->zonename, "loc");
if (the_loc->loc_type == T_INCONTAINER)
return verify_item(the_hash, the_loc->the_loc, thezone->zonename, "obj");
else
return False;
}
/********************************************************************************
**
** check_while
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_boolean(hashTable *the_hash, bool_stmt *bool_exp, char *in_name,
zone_record *thezone)
{
Boolean still_valid = True;
if (bool_exp->next_bool != NULL)
{
still_valid = still_valid && check_boolean(the_hash, bool_exp->next_bool,
in_name, thezone);
}
if (bool_exp->the_stmt != NULL)
{
still_valid = still_valid && check_stmt(the_hash, bool_exp->the_stmt,
in_name, thezone);
}
return still_valid;
}
/********************************************************************************
**
** check_arith_str
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_arith_str(hashTable *the_hash, arith_string *stmt, char *in_name,
zone_record *thezone)
{
Boolean still_good;
if (stmt->stringfunct1 != NULL)
{
still_good = check_defined(the_hash,
stmt->stringfunct1, in_name, thezone);
}
if (stmt->string2 != NULL)
still_good = still_good && check_arith_str(the_hash,
stmt->string2->stmt.arith_str_d, in_name, thezone);
return still_good;
}
/********************************************************************************
**
** check_arith_num
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_arith_num(hashTable *the_hash, arith_number *stmt, char *in_name,
zone_record *thezone)
{
Boolean still_good;
if (stmt->numberfunct != NULL)
{
still_good = check_defined(the_hash,
stmt->numberfunct, in_name, thezone);
}
if (stmt->next_number != NULL)
still_good = still_good && check_arith_num(the_hash,
stmt->next_number, in_name, thezone);
return still_good;
}
/********************************************************************************
**
** check_defined
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_assignmt(hashTable *the_hash, stmt_record *stmt, char *in_name,
zone_record *thezone)
{
hashRecord *tmp_hash;
char hashnam [(MAXNAMLEN*3)+5];
char error[80];
sprintf(hashnam, "dec@%s@%s@%s", thezone->zonename, in_name, stmt->stmt.assignmt_d->var_name);
lowercase(hashnam);
if (stmt->stmt.assignmt_d->the_stmt->stmt_type == STMT_ARITH_NUM)
{
if ((tmp_hash = findHashRecord(hashnam, the_hash)) == NULL)
{
sprintf(error, "Variable %s not defined",
stmt->stmt.assignmt_d->var_name);
sem_error(error, thezone->zonefile, in_name, False);
return False;
}
if (tmp_hash->idnumber != T_NUMBER)
{
sprintf(error, "Error with variable %s, must assign a number to a number type",
stmt->stmt.assignmt_d->var_name);
sem_error(error, thezone->zonefile, in_name, False);
return False;
}
}
else if (stmt->stmt.assignmt_d->the_stmt->stmt_type == STMT_ARITH_STR)
{
if ((tmp_hash = findHashRecord(hashnam, the_hash)) == NULL)
{
sprintf(error, "Variable %s not defined",
stmt->stmt.assignmt_d->var_name);
sem_error(error, thezone->zonefile, in_name, False);
return False;
}
if (tmp_hash->idnumber != T_STR)
{
sprintf(error, "Error with variable %s, must assign an arithmetic string to a string type",
stmt->stmt.assignmt_d->var_name);
sem_error(error, thezone->zonefile, in_name, False);
return False;
}
}
else
{
printf("BAD ERROR! Unexpected function type in assignment found!\n");
return False;
}
return True;
}
/********************************************************************************
**
** check_defined
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_defined(hashTable *the_hash, stmt_record *stmt, char *in_name,
zone_record *thezone)
{
mudfunct_param *tmp_param;
Boolean still_valid = True;
char error[80];
char holder[(MAXNAMLEN*3)+5];
if (stmt->stmt_type == STMT_IDENT)
{
if (has_amperstand(stmt->stmt.ident_d->the_ident))
strcpy(holder, stmt->stmt.ident_d->the_ident);
else
{
sprintf(holder, "dec@%s@%s@%s", thezone->zonename, in_name,
stmt->stmt.ident_d->the_ident);
lowercase(holder);
}
if ((findHashRecord(holder, the_hash) == NULL) &&
(isalpha(stmt->stmt.ident_d->the_ident[0])))
{
sprintf(error, "Identifier %s not defined",
stmt->stmt.ident_d->the_ident);
sem_error(error, thezone->zonefile, in_name, False);
return False;
}
else
return True;
}
tmp_param = stmt->stmt.mudfunct_d->parameters;
while (tmp_param != NULL)
{
if (tmp_param->the_param != NULL)
{
if (has_amperstand(tmp_param->the_param->the_string))
strcpy(holder, tmp_param->the_param->the_string);
else
{
sprintf(holder, "dec@%s@%s@%s", thezone->zonename, in_name,
tmp_param->the_param->the_string);
lowercase(holder);
}
if ((!tmp_param->has_quotes) &&
(findHashRecord(holder, the_hash) == NULL) &&
(isalpha(tmp_param->the_param->the_string[0])))
{
sprintf(error, "Identifier %s not defined", tmp_param->the_param->the_string);
sem_error(error, thezone->zonefile, in_name, False);
still_valid = False;
}
}
else
{
if (tmp_param->funct_param == NULL)
return still_valid;
if (tmp_param->funct_param->stmt_type == STMT_IDENT)
{
if (has_amperstand(tmp_param->funct_param->stmt.ident_d->the_ident))
strcpy(holder, tmp_param->funct_param->stmt.ident_d->the_ident);
else
{
sprintf(holder, "dec@%s@%s@%s", thezone->zonename, in_name,
tmp_param->funct_param->stmt.ident_d->the_ident);
lowercase(holder);
}
if ((findHashRecord(holder, the_hash) == NULL) &&
(isalpha(tmp_param->funct_param->stmt.ident_d->the_ident[0])))
{
sprintf(error, "Identifier %s not defined",
tmp_param->funct_param->stmt.ident_d->the_ident);
sem_error(error, thezone->zonefile, in_name, False);
still_valid = False;
}
/* printf("found: %s\n", tmp_param->funct_param->stmt.ident_d->the_ident); */
}
else if (tmp_param->funct_param->stmt_type == STMT_MUD_DEFINED)
{
still_valid = still_valid && check_defined(the_hash,
tmp_param->funct_param, in_name, thezone);
}
else if (tmp_param->funct_param->stmt_type == STMT_ARITH_STR)
{
still_valid = still_valid && check_arith_str(the_hash,
tmp_param->funct_param->stmt.arith_str_d, in_name, thezone);
}
else if (tmp_param->funct_param->stmt_type == STMT_ARITH_NUM)
{
still_valid = still_valid && check_arith_num(the_hash,
tmp_param->funct_param->stmt.arith_num_d, in_name, thezone);
}
else
{
printf("HHHHHHHOOOOOOOOOOOOOLYYYYYYYYYYY MOLYYYYYYYYYY!!! A BUG A BUG!!!!\n");
return False;
}
}
/* for some reason I need this here, not sure why, but it made it work right */
fflush(stdout);
tmp_param = tmp_param->more_param;
}
return still_valid;
}
/********************************************************************************
**
** check_while
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_if(hashTable *the_hash, if_decl *stmt, char *in_name,
zone_record *thezone)
{
Boolean still_good;
/* printf("checking if statement\n"); */
still_good = check_boolean(the_hash, stmt->bool_exp, in_name, thezone);
still_good = still_good && check_statements(the_hash, stmt->if_statements,
in_name, thezone) &&
check_statements(the_hash, stmt->else_statements,
in_name, thezone);
return still_good;
}
/********************************************************************************
**
** check_repeat
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_repeat(hashTable *the_hash, while_decl *stmt, char *in_name,
zone_record *thezone)
{
Boolean still_good = True;
still_good = check_statements(the_hash, stmt->while_statements,
in_name, thezone);
still_good = still_good && check_boolean(the_hash, stmt->bool_exp,
in_name, thezone);
return still_good;
}
/********************************************************************************
**
** check_while
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_while(hashTable *the_hash, while_decl *stmt, char *in_name,
zone_record *thezone)
{
Boolean still_good = True;
still_good = check_boolean(the_hash, stmt->bool_exp, in_name, thezone);
still_good = still_good && check_statements(the_hash, stmt->while_statements,
in_name, thezone);
return still_good;
}
/********************************************************************************
**
** add_const
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean add_const(hashTable *the_hash, const_decl *stmt, char *in_name,
zone_record *thezone)
{
Boolean still_valid = True;
const_decl *tmp_decl;
string_record *new_str;
hashRecord *new_hash;
char error[80];
tmp_decl = stmt;
while (tmp_decl != NULL)
{
if (new_str == NULL)
new_str = (string_record *) memAlloc(string_record, 1,REC_STRING);
new_str = var_list;
while (new_str->nextstr != NULL)
new_str = new_str->nextstr;
new_str->nextstr = (string_record *) memAlloc(string_record, 1,REC_STRING);
new_str->nextstr->the_string = (char *) memAlloc(char, strlen(tmp_decl->const_name) + 1, REC_CHAR);
new_str = new_str->nextstr;
strcpy(new_str->the_string, tmp_decl->const_name);
new_hash = createHashRecord(tmp_decl->const_name, -1);
if (!addHashRecord(new_hash, the_hash))
{
sprintf(error, "Variable %s previously declared.", tmp_decl->const_name);
sem_error(error, thezone->zonefile, in_name, False);
still_valid = False;
}
}
return still_valid;
}
/********************************************************************************
**
** add_decl
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean add_decl(hashTable *the_hash, var_decl *stmt, char *in_name,
zone_record *thezone)
{
Boolean still_valid = True;
var_decl *tmp_decl;
string_record *new_str;
hashRecord *new_hash;
char error[80];
tmp_decl = stmt;
while (tmp_decl != NULL)
{
if (new_str == NULL)
new_str = (string_record *) memAlloc(string_record, 1,REC_STRING);
new_str = var_list;
while (new_str->nextstr != NULL)
new_str = new_str->nextstr;
new_str->nextstr = (string_record *) memAlloc(string_record, 1,REC_STRING);
new_str->nextstr->the_string = (char *) memAlloc(char, strlen(tmp_decl->var_name) + 1, REC_CHAR);
new_str = new_str->nextstr;
strcpy(new_str->the_string, tmp_decl->var_name);
new_hash = createHashRecord(tmp_decl->var_name, -1);
if (!addHashRecord(new_hash, the_hash))
{
sprintf(error, "Variable %s previously declared.", tmp_decl->var_name);
sem_error(error, thezone->zonefile, in_name, False);
still_valid = False;
}
}
return still_valid;
}
/********************************************************************************
**
** check_stmt
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_stmt(hashTable *the_hash, stmt_record *stmt,
char *in_name, zone_record *thezone)
{
/* printf("checking statement\n"); */
switch(stmt->stmt_type)
{
case STMT_VAR_DECL: /* a variable declaration */
break;
/* return add_decl(the_hash, stmt->stmt.var_d, in_name, thezone); */
case STMT_CONST_DECL: /* a constant declaration */
/* return add_const(the_hash, stmt->stmt.const_d, in_name, thezone); */
break;
case STMT_FOR_LOOP: /* a for loop */
return check_statements(the_hash, stmt->stmt.for_d->for_statements,
in_name, thezone);
break;
case STMT_WHILE_LOOP: /* a while loop */
return check_while(the_hash, stmt->stmt.while_d, in_name, thezone);
break;
case STMT_REPEAT_UNTIL: /* a repeat until loop */
return check_repeat(the_hash, stmt->stmt.while_d, in_name, thezone);
break;
case STMT_IF_THEN: /* an if then segment */
return check_if(the_hash, stmt->stmt.if_d, in_name, thezone);
break;
case STMT_BLOCK: /* a begin end block */
return check_statements(the_hash, stmt->stmt.block_d->block_statements,
in_name, thezone);
break;
case STMT_RAW_CODE: /* actual raw C code */
break;
case STMT_IDENT:
case STMT_MUD_DEFINED: /* mudcode defined in the mudcode.lib file */
return check_defined(the_hash, stmt, in_name, thezone);
break;
case STMT_ASSIGNMT:
return check_assignmt(the_hash, stmt, in_name, thezone);
break;
default:
printf("BAD ERROR ENCOUNTERED!!! ARGH!!! SAVE YOURSELVES!!!\n");
return False;
}
return True;
}
/********************************************************************************
**
** check_statements
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_statements(hashTable *the_hash, stmt_list_record *stmts,
char *in_name, zone_record *thezone)
{
stmt_list_record *tmp_stmt;
stmt_list_record *last_stmt;
Boolean still_good = True;
string_record *tmp_str;
string_record *prev_str;
tmp_stmt = stmts;
last_stmt = NULL;
while (tmp_stmt != NULL)
{
if (tmp_stmt->the_statement == NULL)
{
xfree(tmp_stmt,REC_STMTLIST);
if (last_stmt != NULL)
last_stmt->more_statements = NULL;
return still_good;
}
still_good = still_good && check_stmt(the_hash, tmp_stmt->the_statement,
in_name, thezone);
last_stmt = tmp_stmt;
tmp_stmt = tmp_stmt->more_statements;
}
tmp_str = var_list;
/* remove declarations from the hash table */
while (tmp_str != NULL)
{
deleteHashRecord(tmp_str->the_string, the_hash);
prev_str = tmp_str;
tmp_str = tmp_str->nextstr;
xfree(prev_str,REC_STRING);
}
return still_good;
}
/********************************************************************************
**
** check_code
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_code(hashTable *the_hash, trap_record *the_traps,
char *in_name, zone_record *thezone)
{
trap_record *tmp_trap;
Boolean still_good = True;
char errstr[80];
tmp_trap = the_traps;
if ((the_traps != NULL) && (the_traps->trap_verb->trap_location[0] != '\0'))
{
if (!verify_item(the_hash, the_traps->trap_verb->trap_location,
thezone->zonename, "trap"))
{
sprintf(errstr, "Unknown extern pointer, trap %s does not exist",
the_traps->trap_verb->trap_location);
sem_error(errstr, thezone->zonename, in_name, False);
still_good = False;
}
}
while (tmp_trap != NULL)
{
still_good = still_good && check_statements(the_hash,
the_traps->the_statements, in_name, thezone);
tmp_trap = tmp_trap->more_traps;
}
if (!still_good)
{
sem_error("Error in code",thezone->zonename,in_name, False);
}
return still_good;
}
/********************************************************************************
**
** check_locations
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_locations(hashTable *the_hash, location_record *theloc, zone_record *thezone)
{
Boolean still_valid = True; /* if the location is still valid */
location_record *loc_ptr;
char error[80];
loc_ptr = theloc;
strcpy(thetype, "location");
while (loc_ptr != NULL)
{
if (loc_ptr->north != NULL)
{
if (!verify_item(the_hash, loc_ptr->north, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in north decl.", loc_ptr->north);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->south != NULL)
{
if (!verify_item(the_hash, loc_ptr->south, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in south decl.",
loc_ptr->south);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->east != NULL)
{
if (!verify_item(the_hash, loc_ptr->east, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in east decl",
loc_ptr->east);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->west != NULL)
{
if (!verify_item(the_hash, loc_ptr->west, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in west decl.",
loc_ptr->west);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->up != NULL)
{
if (!verify_item(the_hash, loc_ptr->up, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in up decl.",
loc_ptr->up);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->down != NULL)
{
if (!verify_item(the_hash, loc_ptr->down, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in down decl.",
loc_ptr->down);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->northeast != NULL)
{
if (!verify_item(the_hash, loc_ptr->northeast, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in northeast decl.",
loc_ptr->northeast);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->northwest != NULL)
{
if (!verify_item(the_hash, loc_ptr->northwest, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in northwest decl.",
loc_ptr->northwest);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->southeast != NULL)
{
if (!verify_item(the_hash, loc_ptr->southeast, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in southeast decl.",
loc_ptr->southeast);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
if (loc_ptr->southwest != NULL)
{
if (!verify_item(the_hash, loc_ptr->southwest, thezone->zonename, "loc"))
{
sprintf(error, "Location %s not defined, located in southwest.",
loc_ptr->southwest);
sem_error(error, thezone->zonefile, loc_ptr->name, False);
still_valid = False;
}
}
still_valid = still_valid && check_code(the_hash, loc_ptr->loc_code,
loc_ptr->name, thezone);
loc_ptr = loc_ptr->next_loc;
}
return still_valid;
}
/********************************************************************************
**
** check_objects
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_objects(hashTable *the_hash, object_record *theobj, zone_record *thezone)
{
Boolean still_valid = True; /* if the location is still valid */
object_record *obj_ptr;
char error[80];
loc_str_record *locptr;
obj_ptr = theobj;
strcpy(thetype, "object");
while (obj_ptr != NULL)
{
locptr = obj_ptr->location;
while (locptr != NULL)
{
if (!verify_location(the_hash, locptr, thezone))
{
sprintf(error, "Location %s not defined.", locptr->the_loc);
sem_error(error, thezone->zonefile, obj_ptr->oname, False);
still_valid = False;
}
locptr = locptr->nextloc;
}
if (obj_ptr->name == NULL)
{ if (!verify_gamename(obj_ptr->oname))
{ sprintf(error,"Object has an invalid gamename: %s.",obj_ptr->oname);
sem_error(error,thezone->zonefile, obj_ptr->oname, False);
still_valid = False;
}
}
else if (!verify_gamename(obj_ptr->name))
{ sprintf(error,"Object has an invalid gamename: %s.",obj_ptr->name);
sem_error(error,thezone->zonefile, obj_ptr->oname, False);
still_valid = False;
}
if (obj_ptr->altname != NULL)
{ if (!verify_gamename(obj_ptr->altname))
{ sprintf(error,"Object has an invalid gamename: %s.",obj_ptr->altname);
sem_error(error,thezone->zonefile, obj_ptr->oname, False);
still_valid = False;
}
}
if (obj_ptr->linked != NULL)
{
if (!verify_item(the_hash, obj_ptr->linked, thezone->zonename, "obj"))
{
sprintf(error, "object %s not defined, located in linked.",
obj_ptr->linked);
sem_error(error, thezone->zonefile, obj_ptr->oname, False);
still_valid = False;
}
}
#if 0
/* Check to see if the current state is allowed considering the maxstate.
* For very strict checking yes, for the mud.. no ;)
*/
if (obj_ptr->state > obj_ptr->maxstate)
{
sprintf(error, "object state %d greater than maxstate %d",
obj_ptr->state, obj_ptr->maxstate);
sem_error(error, thezone->zonefile, obj_ptr->oname, False);
still_valid = False;
}
#endif
if (obj_ptr->basevalue > MAX_OBJ_BASEVALUE)
{
sprintf(error, "Warning: basevalue is %d", obj_ptr->basevalue);
sem_error(error, thezone->zonefile, obj_ptr->oname, True);
}
if (obj_ptr->maxstate > MAX_OBJ_MAXSTATE)
{
sprintf(error, "Warning: maxstate is %d", obj_ptr->maxstate);
sem_error(error, thezone->zonefile, obj_ptr->oname, True);
}
if (obj_ptr->armor > MAX_OBJ_ARMOR)
{
sprintf(error, "Warning: armor is %d", obj_ptr->armor);
sem_error(error, thezone->zonefile, obj_ptr->oname, True);
}
if (obj_ptr->damage > MAX_OBJ_DAMAGE)
{
sprintf(error, "Warning: damage is %d", obj_ptr->damage);
sem_error(error, thezone->zonefile, obj_ptr->oname, True);
}
if (obj_ptr->weight > MAX_OBJ_WEIGHT)
{
sprintf(error, "Warning: weight is %d", obj_ptr->basevalue);
sem_error(error, thezone->zonefile, obj_ptr->oname, True);
}
still_valid = still_valid && check_code(the_hash, obj_ptr->obj_code,
obj_ptr->oname, thezone);
obj_ptr = obj_ptr->next_obj;
}
return still_valid;
}
/********************************************************************************
**
** check_mobiles
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean check_mobiles(hashTable *the_hash, mobile_record *themob, zone_record *thezone)
{
Boolean still_valid = True; /* if the location is still valid */
mobile_record *mob_ptr;
char error[80];
loc_str_record *locptr;
mob_ptr = themob;
strcpy(thetype, "mobile");
while (mob_ptr != NULL)
{
locptr = mob_ptr->location;
while (locptr != NULL)
{
if (!verify_location(the_hash, locptr, thezone))
{
sprintf(error, "Location %s not defined.", locptr->the_loc);
sem_error(error, thezone->zonefile, mob_ptr->mname, False);
still_valid = False;
}
locptr = locptr->nextloc;
}
if (mob_ptr->strength > MAX_MOB_STRENGTH)
{
sprintf(error, "Warning: strength is %d", mob_ptr->strength);
sem_error(error, thezone->zonefile, mob_ptr->mname, True);
}
if (mob_ptr->damage > MAX_MOB_DAMAGE)
{
sprintf(error, "Warning: damage is %d", mob_ptr->damage);
sem_error(error, thezone->zonefile, mob_ptr->mname, True);
}
if (mob_ptr->armor > MAX_MOB_ARMOR)
{
sprintf(error, "Warning: armor is %d", mob_ptr->armor);
sem_error(error, thezone->zonefile, mob_ptr->mname ,True);
}
still_valid = still_valid && check_code(the_hash, mob_ptr->mob_code,
mob_ptr->mname, thezone);
mob_ptr = mob_ptr->next_mob;
}
return still_valid;
}
/*********************************************************************************
** MAIN SEMANTIC CHECK FUNCTION
********************************************************************************/
/********************************************************************************
**
** semantic_check
**
** Parameters: filename - the filename string to open
**
** ret - returns a zone record with all zone data stored in it or attached to it
**
********************************************************************************/
Boolean semantic_check(hashTable *the_hash, zone_record *thezone)
{
Boolean is_good = True; /* stores if the zones are still good */
zone_record *zone_ptr; /* used to move along zones */
zone_ptr = thezone;
while (zone_ptr != NULL)
{
if (!(check_locations(the_hash, zone_ptr->location_data, zone_ptr) &&
check_objects(the_hash, zone_ptr->object_data, zone_ptr) &&
check_mobiles(the_hash, zone_ptr->mobile_data, zone_ptr)))
{ printf("Error occured in zone %s\n",zone_ptr->zonename);
is_good = False;
}
zone_ptr = zone_ptr->next_zone;
}
return is_good;
}