musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
#!/usr/bin/perl

# Mud-Lua Interface Generation
# Copyright (c) 2002 Abi Brady

print "#define i_int int\n";
print "#define i_bool int\n";
print "#define i_char char\n";
print "#define i_world World<MudObject>\n";
print "#define i_object MudObject *\n";
print "#define i_nilobject MudObject *\n";
print "#define i_player Player *\n";
print "#define i_protobject MudObject *\n";
print "#define i_string const char *\n";
print "#define i_flag Flag\n";
print "#define i_priv PFlag\n";
print "#define i_nilstring const char *\n";
print "#define i_table Table\n";

print "#define r_int int\n";
print "#define r_bool int\n";
print "#define r_char char\n";
print "#define r_world World<MudObject>\n";
print "#define r_object MudObject *\n";
print "#define r_protobject MudObject *\n";
print "#define r_string string\n";
print "#define r_nilstring const char *\n";

print "\n";

$ln = 0;

$table = "";

LINE:
while (<STDIN>) {
    s/\n//;
    $q = $_;
    $ln = $ln + 1;
    $silent = 0;

    if (substr($q, 0, 1) eq "#" || length($q)==0) {
	next LINE;
    }

    ($line, $cxx) = /(^[_A-za-z0-9\:, ()]*)= (.*)/;

    if (!$line || !$cxx) {
	next LINE;
    }

#    print STDERR "[$line] [$cxx]\n";
#    next LINE;

    if (length($cxx)==0) {
      print STDERR "mkhooks: no code\n";
      exit 1;
    }
    
    $void = 0;

    $rtype = substr($line, 0, index($line, " "));
    $fname = substr($line, index($line, " "));
    
    if ($rtype eq "void") { $void = 1; }
    
    $args = substr($fname, index($fname, "(")+1);
    $args = substr($args, 0, length($args)-2);
    
    $fname = substr($fname, 1, index($fname, "(")-1);
    
    @arg = split(',', $args);
#    print STDERR "l_$fname()\n";	
    print "int l_$fname(lua_State *L) {\n";
    print "  string args;\n";
    
    if (!$silent) {
	$table = $table . "lua_register(L, \"$fname\", l_$fname); \\\n";
    }
    
    if ($silent) {
       print "  if (lua_gettop(L)>", scalar @arg, ") return -1;\n";
    } else {
       print "  if (lua_gettop(L)>", scalar @arg, ") lua_error(L, \"bad number of args to $fname\");\n";
   }

    for ($i=0;$i<scalar @arg;$i++) {
	$idx = $i+1;
	@blah = split(' ', $arg[$i]);
	$def = 0;
	if (index($blah[1], ":")!=-1) {
	    $blah[1] = substr($blah[1], 0, index($blah[1], ":"));
	    $def = 1;
	}
	if ($blah[0] eq "nilobject") {
	    if ($def) {
		print "  if (lua_gettop(L)>=$idx)";
	    }

	    print "  if (!l_isnilobject(L, $idx)) lua_error(L, \"expected a (possibly-nil) object for arg $idx of $fname\");\n";

	    print "  i_$blah[0] $blah[1] = lua_gettop(L)>=$idx?l_getobject(L, $idx):0;\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%s, \", esc(".$blah[1].").c_str());\n";
	} elsif ($blah[0] eq "object" || $blah[0] eq "protobject" || $blah[0] eq "player") {
	    if ($def) {
		print "  if (lua_gettop(L)>=$idx)";
	    }
	    if ($silent) {
		print "  if (!l_isobject(L, $idx)) return -1;\n";
	    } else {
		print "  if (!l_isobject(L, $idx)) lua_error(L, \"expected an object for arg $idx of $fname\");\n";
	    }
	    if ($def) {
		if ($blah[0] eq "player") {
		    print "  i_$blah[0] $blah[1] = lua_gettop(L)>=$idx?dynamic_cast<Player*>(l_getobject(L, $idx)):0;\n";
		    print "  if (!$blah[1]) lua_error(L, \"expected a player for arg $idx of $fname.\");\n";
		} else {
		    print "  i_$blah[0] $blah[1] = lua_gettop(L)>=$idx?l_getobject(L, $idx):0;\n";
		}
		
	    } else {
		if ($blah[0] eq "player") {
		    print "  i_$blah[0] $blah[1] = dynamic_cast<Player*>(l_getobject(L, $idx));\n";
		    print "  if (!$blah[1]) lua_error(L, \"expected a player for arg $idx of $fname.\");\n";
		} else {
		    print "  i_$blah[0] $blah[1] = l_getobject(L, $idx);\n";
		}
	    }
	    if ($blah[0] eq "protobject") {
		print "  if (!writeaccess($blah[1])) lua_error(L, \"permission violation in $fname\");\n";
	    }
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%s, \", esc(".$blah[1].").c_str());\n";
	} elsif ($blah[0] eq "flag") {
	    if ($silent) {
		print "  if (!lua_isnumber(L, $idx)) return -1;\n";
	    } else {
		print "  if (!lua_isnumber(L, $idx)) lua_error(L, \"expected number for arg $idx of $fname\");\n";
	    }
	    print "  i_$blah[0] $blah[1] = i_flag(lua_tonumber(L, $idx)-1);\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"flag.%s, \", flag_names[$blah[1]]);\n";
	} elsif ($blah[0] eq "priv") {
	    if ($silent) {
		print "  if (!lua_isnumber(L, $idx)) return -1;\n";
	    } else {
		print "  if (!lua_isnumber(L, $idx)) lua_error(L, \"expected number for arg $idx of $fname\");\n";
	    }
	    print "  i_$blah[0] $blah[1] = i_priv(lua_tonumber(L, $idx)-1);\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"priv.%s, \", priv_names[$blah[1]]);\n";
	} elsif ($blah[0] eq "int") {
	    if ($silent) {
		print "  if (!lua_isnumber(L, $idx)) return -1;\n";
	    }  else {
		print "  if (!lua_isnumber(L, $idx)) lua_error(L, \"expected number for arg $idx of $fname\");\n";
	    }
	    print "  i_$blah[0] $blah[1] = (i_int)lua_tonumber(L, $idx);\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%i, \", $blah[1]);\n";
	} elsif ($blah[0] eq "table") {
	    if ($silent) {
		print "  if (!l_isstringtable(L, $idx)) return -1;\n";
	    }  else {
		print "  if (!l_isstringtable(L, $idx)) lua_error(L, \"expected table for arg $idx of $fname\");\n";
	    }
	    print "  i_$blah[0] $blah[1] = l_totable(L, $idx);\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%s, \", esc($blah[1]).c_str());\n";
	} elsif ($blah[0] eq "world") {
	    if ($silent) {
		print "  if (!l_isworld(L, $idx)) return -1;\n";
	    }  else {
		print "  if (!l_isworld(L, $idx)) lua_error(L, \"expected table for arg $idx of $fname\");\n";
	    }
	    print "  i_$blah[0] $blah[1] = l_toworld(L, $idx);\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%s, \", esc($blah[1]).c_str());\n";
	} elsif ($blah[0] eq "bool") {
	    if ($def) {
		print "  if (lua_gettop(L)>=$idx)";
	    }
	    if ($silent) {
		print "  if (!(lua_isnumber(L, $idx) || lua_isnil(L,$idx))) return -1;\n";
	    } else {
		print "  if (!(lua_isnumber(L, $idx) || lua_isnil(L,$idx))) lua_error(L, \"expected bool for arg $idx of $fname\");\n";
	    }
	    print "  i_$blah[0] $blah[1] = (bool)(lua_gettop(L)>=$idx?(lua_isnil(L,$idx)?0:lua_tonumber(L, $idx)):0);\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%i, \", $blah[1]);\n";
	} elsif ($blah[0] eq "string") {
	    if ($def) {
		print "  if (lua_gettop(L)>=$idx)";
	    }
	    if ($silent) {
		print "  if (!lua_isstring(L, $idx)) return -1;\n";
	    } else {
		print "  if (!lua_isstring(L, $idx)) lua_error(L, \"expected string for arg $idx of $fname\");\n";
	    }
	    print "  i_$blah[0] $blah[1] = lua_gettop(L)>=$idx?lua_tostring(L, $idx):0;\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%s, \", esc($blah[1]).c_str());\n";
	} elsif ($blah[0] eq "nilstring") {
	    if ($silent) {
		print "  if (!lua_isstring(L, $idx) && !lua_isnil(L, $idx)) return -1;\n";
	    } else {
		print "  if (!lua_isstring(L, $idx) && !lua_isnil(L, $idx)) lua_error(L, \"expected string for arg $idx of $fname\");\n";		
	    }
	    print "  i_$blah[0] $blah[1] = lua_isnil(L, $idx)?NULL:lua_tostring(L, $idx);\n";
	    print "if (lua_tracing())\n";
	    print "  args += ssprintf(\"%s, \", esc($blah[1]).c_str());\n";
	} else {
	    print STDERR "mkhooks: bad parameter type '$blah[0]'\n";
	    exit 1;
	}
    }
    
    print "#line $ln \"hookdef.txt\"\n";
    if ($void) {
	print "  $cxx;\n";
    } else {
	if (substr($cxx, 0, 1) eq "{") {
	    if ($cxx eq "{") {
		print "  r_$rtype ret;\n{\n";
		while (<STDIN>) {
		    print $_;
		    chomp $_;
		    if ($_ eq "}") {
			goto end;
		    }
		}
	      end:
	    } else {
		print "  r_$rtype ret;\n$cxx;\n";
	    }
	} else {
	    print "  r_$rtype ret = $cxx;\n";
	}
    }
    
    print "if (lua_tracing()) {args=args.substr(0, args.length()-2);log(PFL_SEELUASPAM, 0, \"lua\", \n";
    if ($void) {
	print "  \"%s(%s)\", \"$fname\", args.c_str());\n";
    } elsif ($rtype eq "int") {
	print "  \"%s(%s) == %i\", \"$fname\", args.c_str(), ret);\n";
    } elsif ($rtype eq "bool") {
	print "  \"%s(%s) == %s\", \"$fname\", args.c_str(), ret?\"1\":\"nil\");\n";
    } elsif ($rtype eq "string" || $rtype eq "nilstring") {
	print "  \"%s(%s) == %s\", \"$fname\", args.c_str(), esc(ret).c_str());\n";
    } elsif ($rtype eq "char") {
	print "  \"%s(%s) == \\\"%c\\\"\", \"$fname\", args.c_str(), ret);\n";
    } elsif ($rtype eq "object") {
	print "  \"%s(%s) == %s\", \"$fname\", args.c_str(), esc(ret).c_str());\n";
    } elsif ($rtype eq "world") {
	print "  \"%s(%s) == %s\", \"$fname\", args.c_str(), esc(&ret).c_str());\n";
    } else {
	print STDERR "mkhooks: unknown return type $rtype\n";
        exit 1;
    }
    print "}";
    
    if ($void) {
	print "  return 0;\n";
    } else {
	if ($rtype eq "world") {
	    print "  l_pushworld(L, &ret);\n";
	} elsif ($rtype eq "int") {
	    print "  lua_pushnumber(L, ret);\n";
	} elsif ($rtype eq "bool") {
	    print "  ret?lua_pushnumber(L, ret):lua_pushnil(L);\n";
	} elsif ($rtype eq "char") {
	    print "  char realret[2]={ret, 0};lua_pushstring(L, realret);\n";
	} elsif ($rtype eq "string") {
	    print "  lua_pushstring(L, ret);\n";
	} elsif ($rtype eq "nilstring") {
	    print "  ret?lua_pushstring(L, ret):lua_pushnil(L);\n";
	} else {
	    print "  l_pushobject(L, ret);\n";
	}
	print "  return 1;\n";
    }
    print "}\n\n";
}

print "#define AUTODEFINE \\\n";
print $table;
print "\n";