/* $Header: /belch_a/users/rearl/tinymuck/src/RCS/sanity.c,v 1.3 90/08/09 16:27:16 rearl Exp $ */

/*
 * $Log:	sanity.c,v $
 * Revision 1.3  90/08/09  16:27:16  rearl
 * Sanity knows about TYPE_GARBAGE now.
 * 
 * Revision 1.2  90/07/29  17:43:10  rearl
 * Added dummy macro function so sanity compiles.
 * 
 * Revision 1.1  90/07/19  23:04:07  casie
 * Initial revision
 * 
 *
 */
 
#include "copyright.h"
#include "config.h"

#include "db.h"

void
violate(dbref i, const char *s)
{
  printf("Object #%d violates %s rules!\n", i, s);
  db_write_object(stdout, i);
}

void
check_common(dbref obj)
{
  int          i;

  /* check location */
  if (db[obj].location >= db_top)
    violate(obj, "location");
  /* check contents */
  for (i = db[obj].contents; i < db_top  &&  i != NOTHING; i = db[i].next)
    ;
  if (i != NOTHING)
    violate(obj, "contents rules");
}

void
check_room(dbref obj)
{
  dbref  i;

  if (db[obj].link >= db_top || (((db[db[obj].sp.room.dropto].flags & TYPE_MASK) != TYPE_ROOM) && db[obj].sp.room.dropto != NOTHING && db[obj].sp.room.dropto != HOME))
    violate(obj, "dropto");
  
  for (i = db[obj].exits; i != NOTHING && i < db_top; i = db[i].next)
    ;
  if (i != NOTHING)
    violate(obj, "exits");

  if (db[obj].sp.room.owner >= db_top || ((db[db[obj].sp.room.owner].flags & TYPE_MASK) != TYPE_PLAYER))
    violate(obj, "owner");
}

void
check_thing(dbref obj)
{
  dbref i;

  if (db[obj].link >= db_top || ((db[db[obj].sp.thing.home].flags & TYPE_MASK) != TYPE_ROOM))
    violate(obj, "home");

  for (i = db[obj].exits; i < db_top && i != NOTHING; i = db[i].next)
    ;

  if (i != NOTHING)
    violate(obj, "actions");

  if (db[obj].sp.thing.owner >= db_top || ((db[db[obj].sp.thing.owner].flags & TYPE_MASK) != TYPE_PLAYER))
    violate(obj, "owner");
}

void
check_exit(dbref obj)
{
  int      i;

  for (i = 0; i < db[obj].sp.exit.ndest; i++)
    if ((db[obj].sp.exit.dest)[i] >= db_top)
      violate(obj, "destination");
  
  if (db[obj].sp.exit.owner >= db_top || ((db[db[obj].sp.exit.owner].flags & TYPE_MASK) != TYPE_PLAYER))
    violate(obj, "owner");
}

void
check_player(dbref obj)
{
  dbref        i;

  if (db[obj].link >= db_top || ((db[db[obj].sp.player.home].flags & TYPE_MASK) != TYPE_ROOM))
    violate(obj, "home");

  for (i = db[obj].exits; i < db_top && i != NOTHING; i = db[i].next)
    ;
  if (i != NOTHING)
    violate(obj, "actions");
}

void
main(int argc, char **argv)
{
  int        i;

  db_read(stdin);

  printf("dbtop = %d\n", db_top);

  for (i = 0; i < db_top; i++)
    {
      fprintf(stderr, "Checking object %d..\n", i);
      check_common(i);
      switch( db[i].flags & TYPE_MASK )
	{
	case TYPE_ROOM:
	  check_room(i);
	  break;
	case TYPE_THING:
	  check_thing(i);
	  break;
	case TYPE_EXIT:
	  check_exit(i);
	  break;
	case TYPE_PLAYER:
	  check_player(i);
	  break;
	case TYPE_PROGRAM:
	case TYPE_GARBAGE:
	  break;
	default:
	  violate(i, "type");
	  break;
	}
    }
}

/* dummy compiler */
void
do_compile(dbref p, dbref pr)
{
}
struct macrotable
*new_macro(const char *name, const char *definition, dbref player)
{
}