#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; }