tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
/*
 * compiler.c [virtual object compiler]
 * description: a generic object description language parser.  This is meant
 *              to be the base object that other ODL compilers inherit from.
 * history:
 *    07/01/92 [huthar] - created
 *    12/08/92 [wayfarer] - cleaned up, added // comment support
 *                          multiple line variables, subgroups
 *    12/09/92 [wayfarer] - bug fixing for items, objects, etc.
 *    12/10/92 [wayfarer] - allowed a non-fixed base object to be used
 */

// history: this object comes from the Portals mudlib.  It is a nice
// abstraction of the room description language originally done by Truilkan.

#undef DEBUG

#include <config.h>
#include <uid.h>

private static string opcode, error_string;
private static int line_done;
private static object target;
static string subgroup, filename;
#define YES 1
#define NO 0

void end_subgroup()
{
  string fun;
  if (subgroup)
    {
      fun = subgroup+"_done";
      call_other (this_object(), fun);
    }
}

string parse_line (string line)
{
  string op, val;
  int i;
  
  if (!line || line[0] == '#' || line == "" || line[0..1] == "//")
    return "";
  
  if (sscanf(line, "%s: %s",op,val) == 2)
    {
       opcode = op;
       line_done = YES;
    }
  else if (sscanf(line, "%s:",op) == 1)
    {
      opcode = op;
      line_done = NO;
      return "";
    }
  else
    {
      val = line;
      if (line_done)
	line_done = NO;
      if (val[0..1] == "**" || val == "." || val == "---")
	{
	  line_done = YES;
	  return "";
	}
      else if (val == "{")
	{
	  if (!subgroup)
	    {
	      subgroup = opcode;
	      return "";
	    }
	  else
	    {
	      error_string = "Can't have multiply nested subgroups.";
	      return 0;
	    }
	}
      else if (val == "}")
	{
	  if (subgroup)
	    {
	      end_subgroup();
	      subgroup = NO;
	      opcode = NO;
	      line_done = YES;
	      return "";
	    }
	  else
	    {
	      error_string = "End subgroup found when no subgroup started.";
	      return 0;
	    }
	}
      else
	val += "\n";

    }
  
  for(i = 0; i < strlen(val); i++)
    if(i != ' ' && i != '\t')
      break;
  
  if(i == strlen(val))
    {
      opcode = op;
      line_done = NO;
      return "";
    }
  
  return val[i .. -1];
}

void set_target(object ob)
{
   target = ob;
   ob->set_file_name (filename);
}

object query_target()
{
   return target;
}


int make_target (string name)
{
  object ob;
  
  if (!name)
     name = (string)this_object()->default_base_object();
  if (name)
  {
     seteuid(creator_file(filename));
     ob = new (name);
     set_target(ob);
  }
  if (!target)
     return 0;
  export_uid(target);
  return 1;
}

void error (string val)
{
  write (val);
  if (target)
     target->remove();
}

object compile_object (string file)
{
  string *lines;
  string tmp, value, ret;
  int i;
 
  file = file + (string)this_object()->extension();
  if (file_size(file) == -1)
  {
    write ("No such file or directory: "+ file + "\n");
    return 0;
  }
  seteuid(ROOT_UID);
  tmp = read_file("/"+file);
  if(!tmp || tmp == "")
  {
    write ("File is empty: "+ file + "\n");
    return 0;
  }
  lines = explode(tmp,"\n");

  target = 0;
  filename = file;
  subgroup = NO;
  error_string = 0;

  for(i = 0; i < sizeof(lines); i++)
    {
      line_done = YES;
      value = "";
      tmp = parse_line(lines[i]);
      if (tmp == 0)
	{
	  error ("Error Compiling '"+filename+"': "+error_string+"\n");
	  return 0;
	}
      if ((tmp == "") && line_done)
        continue;
      value = tmp;
      while (line_done == NO)
	{
	  if (i >= (sizeof(lines)-1))
	    break;
	  value += parse_line(lines[++i]);
	}
      if(!opcode)
	{
	  error("Error Compiling '"+filename+"': Opcode missing in line #"+i+"\n");
	  return 0;
	}
      if (subgroup)
	opcode = subgroup + "_" + opcode;
#ifdef DEBUG
      printf ("<final> %s = %s\n",opcode,value);
#endif
      if (!target && opcode != "base_object")
        {
	  if (!make_target(0))
	  {
     	     error ("Error Compiling '"+filename+"': No base object defined.\n");
	     return 0;
	  }
	}
      switch(call_other(this_object(),opcode,value,target))
	{
	case 0:
	  write("Warning Compiling '"+filename+"': Unknown opcode '"+opcode+
		"' in line #"+i+"\n");
	  break;
	case 2:                // Fatal Compile Error
	  error("Fatal compile error: " + filename + "\n");
	  return 0;
	  break;
	}
    }
  if (function_exists("compilation_finished",this_object()) &&
    	!((int)this_object()->compilation_finished()))
    return 0;
  
  return target;
}

/*
 * no shadowing of ODL compilers!
 */
int query_prevent_shadow ()
{
  return 1;
}