Lots of work done with xml parsing.

develop
Warmist 2012-03-04 20:45:15 +08:00 committed by Petr Mrázek
parent f83db86258
commit 7d2b6b4583
7 changed files with 269 additions and 77 deletions

@ -19,6 +19,7 @@
#include "lua_VersionInfo.h"
#include "functioncall.h"
#include "lua_FunctionCall.h"
#include "lua_Offsets.h"
using std::vector;
using std::string;
@ -48,6 +49,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
lua::RegisterMisc(st);
lua::RegisterVersionInfo(st);
lua::RegisterFunctionCall(st);
lua::RegisterEngine(st);
#ifdef LINUX_BUILD
st.push(1);

@ -3,6 +3,9 @@ STD_STRING=0
DWORD=1
WORD=2
BYTE=3
QWORD=4
DOUBLE=5
FLOAT=6
function printd(...)
if DEBUG then
print(...)
@ -94,6 +97,7 @@ function SetExecute(pos)
end
-- engine bindings
engine=engine or {}
--[=[ use default peek/pokes for now
engine.peekd=Process.readDWord
engine.poked=Process.writeDWord
engine.peekb=Process.readByte
@ -106,7 +110,7 @@ engine.peekstr=Process.readCString
--engine.pokestr=Process.readCString
engine.peekarb=Process.read
engine.pokearb=Process.write
--]=]
function engine.peek(offset,rtype)
if type(rtype)=="table" then
@ -117,13 +121,19 @@ function engine.peek(offset,rtype)
end
end
if rtype==STD_STRING then
return engine.peekstr(offset)
return engine.peekstr2(offset)
elseif rtype==DWORD then
return engine.peekd(offset)
elseif rtype==WORD then
return engine.peekw(offset)
elseif rtype==BYTE then
return engine.peekb(offset)
elseif rtype==QWORD then
return engine.peekq(offset)
elseif rtype==FLOAT then
return engine.peekfloat(offset)
elseif rtype==DOUBLE then
return engine.peekdouble(offset)
else
error("Invalid peek type")
return
@ -138,13 +148,19 @@ function engine.poke(offset,rtype,val)
end
end
if rtype==STD_STRING then
return engine.pokestr(offset,val)
return engine.pokestr2(offset,val)
elseif rtype==DWORD then
return engine.poked(offset,val)
elseif rtype==WORD then
return engine.pokew(offset,val)
elseif rtype==BYTE then
return engine.pokeb(offset,val)
elseif rtype==QWORD then
return engine.pokeq(offset,val)
elseif rtype==FLOAT then
return engine.pokefloat(offset,val)
elseif rtype==DOUBLE then
return engine.pokedouble(offset,val)
else
error("Invalid poke type:"..tostring(rtype))
return

@ -60,12 +60,12 @@ table.insert(plugins,{"onfunction","run lua on some df function"})
loadall(plugins)
dofile_silent("dfusion/initcustom.lua")
print("Locating saves...")
--[=[print("Locating saves...")
local str=engine.peekstr(0x1447A40+offsets.base())
print("Current region:"..str)
str="data/save/"..str.."/dfusion/init.lua"
dofile_silent(str)
--]=]
if not INIT then
mainmenu(plugins)
end

@ -170,11 +170,11 @@ end
]]--
ptr_Creature={}
local posoff=VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("position")
local posoff=0 --VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("position")
ptr_Creature.x={off=posoff,rtype=WORD} --ok
ptr_Creature.y={off=posoff+2,rtype=WORD} --ok
ptr_Creature.z={off=posoff+4,rtype=WORD} --ok
ptr_Creature.flags={off=VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("flags1"),rtype=ptt_dfflag.new(10)}
ptr_Creature.flags={off=0,rtype=ptt_dfflag.new(10)}
ptr_Creature.name={off=0,rtype=ptt_dfstring}
ptr_Creature.ID={off=252,rtype=DWORD} --ok i guess
ptr_Creature.followID={off=592,rtype=DWORD} --ok

@ -24,47 +24,96 @@ types.building=sometype
]=]
function parseTree(t)
for k,v in ipairs(t) do
if v.xarg~=nil and v.xarg["type-name"]~=nil and v.label=="ld:global-type" then
local name=v.xarg["type-name"];
print("Parsing:"..name)
for kk,vv in pairs(v.xarg) do
print("\t"..kk.." "..tostring(vv))
end
if(types[name]==nil) then
--print("Parsing:"..name)
--for kk,vv in pairs(v.xarg) do
-- print("\t"..kk.." "..tostring(vv))
--end
types[name]=makeType(v)
print("found "..name.." or type:"..v.xarg.meta or v.xarg.base)
--print("found "..name.." or type:"..v.xarg.meta or v.xarg.base)
end
end
end
end
function parseTreeGlobals(t)
local glob={}
print("Parsing global-objects")
for k,v in ipairs(t) do
if v.xarg~=nil and v.label=="ld:global-object" then
local name=v.xarg["name"];
--print("Parsing:"..name)
local subitem=v[1]
if subitem==nil then
error("Global-object subitem is nil:"..name)
end
local ret=makeType(subitem)
if ret==nil then
error("Make global returned nil!")
end
glob[name]=ret
end
end
--print("Printing globals:")
--for k,v in pairs(glob) do
-- print(k)
--end
return glob
end
function findAndParse(tname)
for k,v in ipairs(main_tree) do
local name=v.xarg["type-name"];
if v.xarg~=nil and v.xarg["type-name"]~=nil and v.label=="ld:global-type" then
if(name ==tname) then
print("Parsing:"..name)
for kk,vv in pairs(v.xarg) do
print("\t"..kk.." "..tostring(vv))
end
--print("Parsing:"..name)
--for kk,vv in pairs(v.xarg) do
-- print("\t"..kk.." "..tostring(vv))
--end
types[name]=makeType(v)
end
--print("found "..name.." or type:"..v.xarg.meta or v.xarg.base)
end
end
end
df={}
df.types=rawget(df,"types") or {} --temporary measure for debug
local df_meta={}
function df_meta:__index(key)
local addr=VersionInfo.getAddress(key)
local vartype=rawget(df,"types")[key];
if addr==nil then
error("No such global address exist")
elseif vartype==nil then
error("No such global type exist")
else
return type_read(vartype,addr)
end
end
function df_meta:__newindex(key,val)
local addr=VersionInfo.getAddress(key)
local vartype=rawget(df,"types")[key];
if addr==nil then
error("No such global address exist")
elseif vartype==nil then
error("No such global type exist")
else
return type_write(vartype,addr,val)
end
end
setmetatable(df,df_meta)
--------------------------------
types=types or {}
dofile("dfusion/patterns/xml_angavrilov.lua")
-- [=[
main_tree=parseXmlFile("dfusion/patterns/supplementary.xml")[1]
parseTree(main_tree)
main_tree=parseXmlFile("dfusion/patterns/codegen.out.xml")[1]
parseTree(main_tree)
rawset(df,"types",parseTreeGlobals(main_tree))
--]=]
--[=[labels={}
for k,v in ipairs(t) do
labels[v.label]=labels[v.label] or {meta={}}

@ -1,15 +1,16 @@
function type_read(valtype,address)
if type(valtype)~= "table" then
return engine.peek(valtype,address)
if valtype.issimple then
print("Simple read:"..tostring(valtype.ctype))
return engine.peek(address,valtype.ctype)
else
return valtype:makewrap(address)
end
end
function type_write(valtype,address,val)
if type(valtype)~= "table" then
engine.poke(valtype,address,val)
if altype.issimple then
engine.poke(address,valtype.ctype,val)
else
engine.poke(DWORD,address,rawget(val,"ptr"))
engine.poke(address,DWORD,rawget(val,"ptr"))
end
end
function first_of_type(node,labelname)
@ -65,6 +66,9 @@ xtypes["static-array"]=sarr
simpletypes={}
simpletypes["s-float"]={FLOAT,4}
simpletypes.int64_t={QWORD,8}
simpletypes.uint32_t={DWORD,4}
simpletypes.uint16_t={WORD,2}
simpletypes.uint8_t={BYTE,1}
@ -78,6 +82,7 @@ function getSimpleType(typename)
local o={}
o.ctype=simpletypes[typename][1]
o.size=simpletypes[typename][2]
o.issimple=true
return o
end
local type_enum={}
@ -130,7 +135,7 @@ function type_class.new(node)
local t_name=""
local name=v.xarg.name or v.xarg["anon-name"] or ("unk_"..k)
print("\t"..k.." "..name.."->"..v.xarg.meta.." ttype:"..v.label)
--print("\t"..k.." "..name.."->"..v.xarg.meta.." ttype:"..v.label)
local ttype=makeType(v)
--for k,v in pairs(ttype) do
@ -206,11 +211,49 @@ xtypes["pointer"]=type_class
--stl-vector (beginptr,endptr,allocptr)
--df-flagarray (ptr,size)
xtypes.containers={}
local dfarr={}
dfarr.__index=dfarr
function dfarr.new(node)
local o={}
setmetatable(o,dfarr)
o.size=8
return o
end
function dfarr:makewrap(address)
local o={}
o.mtype=self
o.ptr=address
setmetatable(o,self.wrap)
return o
end
dfarr.wrap={}
function dfarr.wrap:__index(key)
local num=tonumber(key)
local mtype=rawget(self,"mtype")
local size=type_read(rawget(self,"ptr")+4,DWORD)
error("TODO make __index for dfarray")
if num~=nil and num<sizethen then
return type_read(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"))
else
error("invalid key to df-flagarray")
end
end
function dfarr.wrap:__newindex(key,val)
local num=tonumber(key)
error("TODO make __index for dfarray")
if num~=nil and num<rawget(self,"mtype").count then
return type_write(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"),val)
else
error("invalid key to static-array")
end
end
xtypes.containers["df-array"]=dfarr
local farr={}
farr.__index=farr
function farr.new(node)
local o={}
setmetatable(o,sarr)
setmetatable(o,farr)
o.size=8
return o
end
@ -246,10 +289,10 @@ end
xtypes.containers["df-flagarray"]=farr
local stl_vec={}
stl_vec.__index=farr
stl_vec.__index=stl_vec
function stl_vec.new(node)
local o={}
setmetatable(o,sarr)
setmetatable(o,stl_vec)
o.size=12
local titem=first_of_type(node,"ld:item")
if titem~=nil then
@ -290,8 +333,58 @@ function stl_vec.wrap:__newindex(key,val)
error("invalid key to static-array")
end
end
xtypes.containers["stl-vector"]=stl_vec
local stl_vec_bit={}
stl_vec_bit.__index=stl_vec_bit
function stl_vec_bit.new(node)
local o={}
setmetatable(o,stl_vec_bit)
o.size=20
return o
end
function stl_vec_bit:makewrap(address)
local o={}
o.mtype=self
o.ptr=address
setmetatable(o,self.wrap)
return o
end
stl_vec_bit.wrap={}
function stl_vec_bit.wrap:__index(key)
local num=tonumber(key)
local mtype=rawget(self,"item_type")
local ptr=rawget(self,"ptr")
local p_begin=type_read(ptr,DWORD)
local p_end=type_read(ptr+4,DWORD)
--allocend=type_read(ptr+8,DWORD)
error("TODO make __index for stl_vec_bit")
if num~=nil and num<sizethen then
return type_read(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"))
else
error("invalid key to df-flagarray")
end
end
function stl_vec_bit.wrap:__newindex(key,val)
local num=tonumber(key)
error("TODO make __index for stl_vec_bit")
if num~=nil and num<rawget(self,"mtype").count then
return type_write(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"),val)
else
error("invalid key to static-array")
end
end
xtypes.containers["stl-bit-vector"]=stl_vec_bit
--------------------------------------------
local bytes_pad={}
bytes_pad.__index=bytes_pad
function bytes_pad.new(node)
local o={}
setmetatable(o,bytes_pad)
o.size=tonumber(node.xarg.size)
return o
end
xtypes["bytes"]=bytes_pad
--------------------------------------------
parser={}
parser["ld:global-type"]=function (node)
@ -332,7 +425,7 @@ parser["ld:field"]=function (node)
elseif meta=="pointer" then
return xtypes["pointer"].new(node)
elseif meta=="bytes" then
error("TODO make bytes")
return xtypes["bytes"].new(node)
else
error("Unknown meta:"..meta)
end
@ -341,7 +434,7 @@ parser["ld:item"]=parser["ld:field"]
function makeType(node,overwrite)
local label=overwrite or node.label
if parser[label] ~=nil then
print("Make Type with:"..label)
--print("Make Type with:"..label)
local ret=parser[label](node)
if ret==nil then
error("Error parsing:"..label.." nil returned!")

@ -1,19 +1,19 @@
#include "lua_Offsets.h"
#include <string.h>
#include <stdint.h>
//TODO make a seperate module with peeks/pokes and page permisions (linux/windows spec)
//TODO maybe remove alltogether- use DFHack::Process instead?
unsigned char peekb(size_t offset)
{
return *((unsigned char*)(offset));
}
unsigned short peekw(size_t offset)
template <typename T>
T engine_peek(size_t offset)
{
return *((unsigned short*)(offset));
return *(reinterpret_cast<T*>(offset));
}
unsigned peekd(size_t offset)
template <typename T>
void engine_poke(size_t offset,T val)
{
return *((unsigned*)(offset));
*(reinterpret_cast<T*>(offset))=val;
}
void peekarb(size_t offset, void *mem,size_t size)
{
memcpy(mem,(void*)offset,size);
@ -22,18 +22,6 @@ void peekstr(size_t offset, char* buf, size_t maxsize)
{
strncpy(buf,(char*)offset,maxsize);
}
void pokeb(size_t offset,unsigned char val)
{
*((unsigned char*)(offset))=val;
}
void pokew(size_t offset,unsigned short val)
{
*((unsigned short*)(offset))=val;
}
void poked(size_t offset,unsigned val)
{
*((unsigned*)(offset))=val;
}
void pokearb(size_t offset, void *mem,size_t size)
{
memcpy((void*)offset,mem,size);
@ -42,31 +30,42 @@ void pokestr(size_t offset, char* buf, size_t maxsize)
{
strncpy((char*)offset,buf,maxsize);
}
template <typename T>
T peek(size_t offset) //prob lower performance
{
T tmp;
peekarb(offset,&tmp,sizeof(T));
return tmp;
}
//// lua stuff here
static int lua_peekb(lua_State *L)
{
lua::state st(L);
st.push(peekb(st.as<size_t>(1)));
st.push(engine_peek<uint8_t>(st.as<size_t>(1)));
return 1;
}
static int lua_peekw(lua_State *L)
{
lua::state st(L);
st.push(engine_peek<uint16_t>(st.as<size_t>(1)));
return 1;
}
static int lua_peekd(lua_State *L)
{
lua::state st(L);
st.push(peekd(st.as<size_t>(1)));
st.push(engine_peek<uint32_t>(st.as<size_t>(1)));
return 1;
}
static int lua_peekw(lua_State *L)
static int lua_peekq(lua_State *L)
{
lua::state st(L);
st.push(engine_peek<uint64_t>(st.as<size_t>(1)));
return 1;
}
static int lua_peekfloat(lua_State *L)
{
lua::state st(L);
st.push(engine_peek<float>(st.as<size_t>(1)));
return 1;
}
static int lua_peekdouble(lua_State *L)
{
lua::state st(L);
st.push(peekw(st.as<size_t>(1)));
st.push(engine_peek<double>(st.as<size_t>(1)));
return 1;
}
static int lua_peekarb(lua_State *L)
@ -88,38 +87,53 @@ static int lua_peekstr(lua_State *L)
delete [] buf;
return 1;
}
/*static int lua_peekarb(lua_State *L)
static int lua_peekstr2(lua_State *L)
{
lua::state st(L);
st.push(peekarb(st.as<DWORD>(1)));
st.push(engine_peek<std::string>(st.as<size_t>(1)));
return 1;
}*/
}
static int lua_pokeb(lua_State *L)
{
lua::state st(L);
pokeb(st.as<size_t>(1),st.as<size_t>(2));
engine_poke<uint8_t>(st.as<size_t>(1),st.as<uint8_t>(2));
return 0;
}
static int lua_pokew(lua_State *L)
{
lua::state st(L);
engine_poke<uint16_t>(st.as<size_t>(1),st.as<uint16_t>(2));
return 0;
}
static int lua_poked(lua_State *L)
{
lua::state st(L);
poked(st.as<size_t>(1),st.as<size_t>(2));
engine_poke<uint32_t>(st.as<size_t>(1),st.as<uint32_t>(2));
return 0;
}
static int lua_pokew(lua_State *L)
static int lua_pokeq(lua_State *L)
{
lua::state st(L);
pokew(st.as<size_t>(1),st.as<size_t>(2));
engine_poke<uint64_t>(st.as<size_t>(1),st.as<uint64_t>(2));
return 0;
}
static int lua_pokefloat(lua_State *L)
{
lua::state st(L);
engine_poke<float>(st.as<size_t>(1),st.as<float>(2));
return 0;
}
static int lua_pokedouble(lua_State *L)
{
lua::state st(L);
engine_poke<double>(st.as<size_t>(1),st.as<double>(2));
return 0;
}
static int lua_pokearb(lua_State *L)
{
lua::state st(L);
void *p=(void *)lua_touserdata(L, 2);//st.as<lua::userdata>(2);
size_t size=st.as<size_t>(3);
pokearb(st.as<size_t>(1),p,size);
return 0;
}
@ -130,18 +144,36 @@ static int lua_pokestr(lua_State *L)
pokestr(st.as<size_t>(1),(char*)trg.c_str(),trg.size());
return 0;
}
static int lua_pokestr2(lua_State *L)
{
lua::state st(L);
std::string trg=st.as<std::string>(2);
engine_poke<std::string>(st.as<size_t>(1),trg);
return 0;
}
const luaL_Reg lua_engine_func[]=
{
{"peekb",lua_peekb},
{"peekw",lua_peekw},
{"peekd",lua_peekd},
{"peekq",lua_peekq},
{"peekfloat",lua_peekfloat},
{"peekdouble",lua_peekdouble},
{"peekarb",lua_peekarb},
{"peekstr",lua_peekstr},
{"peekstr2",lua_peekstr2},
{"pokeb",lua_pokeb},
{"pokew",lua_pokew},
{"poked",lua_poked},
{"pokeq",lua_pokeq},
{"pokefloat",lua_pokefloat},
{"pokedouble",lua_pokedouble},
{"pokearb",lua_pokearb},
{"pokestr",lua_pokestr},
{"pokestr2",lua_pokestr2},
{NULL,NULL}
};