Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- ctypes2.lua: implement (middle-)C types on top of peek.c. -- This file: -- http://angg.twu.net/peek/ctypes2.lua.html -- http://angg.twu.net/peek/ctypes2.lua -- (find-angg "peek/ctypes2.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- Version: 2012feb01 -- License: GPL3 -- -- See: (find-TH "peek") -- http://angg.twu.net/peek.html -- file:///home/edrx/TH/L/peek.html -- (find-dn5file "") -- This is just a skeleton at the moment. -- (find-angg "DAVINCI/peek.lua") -- (find-angg "DAVINCI/peek-luadecls-1.txt") -- (find-angg "DAVINCI/peek-luadecls-2.txt") -- (find-angg "LUA/middle-c.lua") -- To do: add pointers to several programs that understand C types... -- cdecl -- GDB (ptype) -- the LuaJIT FFI -- Fabrice Bellard's TCC -- CLisp FFIs -- All my doubts about types in C should be explained here: -- http://c-faq.com/aryptr/index.html -- http://c-faq.com/struct/index.html -- package.path = ee_expand("~/dednat5/?.lua")..";"..package.path -- require "eoo" -- (find-dn5 "eoo.lua") ee_dofile "~/dednat5/eoo.lua" ctypes = {} CType = Class { type = "CType", __tostring = function (ct) return ct:tos() end, __index = { name = function (ct) return ct.ctype end, size = function (ct) return ct.nbytes end, size_error = function (ct) error("Expected a size for: "..ct:tos()) end, size_assert = function (ct) return ct:size() or ct:size_error() end, -- canon = function (ct) local ctname = ct.ctype if ctypes[ctname] == nil then ctypes[ctname]=ct; return ct end return ctypes[ctname] end, tos = function (ct) return ct.ctype end, -- star = function (ct) local oldctname = ct.ctype local newctname = oldctname.."*" return CStarType { ctype=newctname, basetype=oldctname, what="*", nbytes=4, align=4 }:canon() end, array_u = function (ct) local oldctname = ct.ctype local ctname = oldctname.."[]" ct:size_assert() return CArrayType { ctype=ctname, basetype=oldctname, what="[]", nbytes=nil, align=ct.align }:canon() end, array_n = function (ct, n) local oldctname = ct.ctype local ctname = oldctname.."["..n.."]" local oldsize = ct:size_assert() return CArrayType { ctype=ctname, basetype=oldctname, what="[n]", nbytes=oldsize*n, align=ct.align }:canon() end, _ = function (ct, str) if str == "*" then return ct:star() end if str == "[]" then return ct:array_u() end local n = str:match("^%[([0-9]*)%]$") if n then return ct:array_n(tonumber(n)) end error("___?") end, } } CPrimType = ClassOver (CType) { type = "CPrimType", __tostring = function (ct) return ct:tos() end, __index = { }, } CStarType = ClassOver (CType) { type = "CStarType", __tostring = function (ct) return ct:tos() end, __index = { }, } CArrayType = ClassOver (CType) { type = "CArrayType", __tostring = function (ct) return ct:tos() end, __index = { }, } CPrimType {ctype="char", nbytes=1, align=1} :canon() CPrimType {ctype="uchar", nbytes=1, align=1} :canon() CPrimType {ctype="short", nbytes=2, align=2} :canon() CPrimType {ctype="ushort", nbytes=2, align=2} :canon() CPrimType {ctype="int", nbytes=4, align=4} :canon() CPrimType {ctype="uint", nbytes=4, align=4} :canon() CPrimType {ctype="void", nbytes=nil, align=nil} :canon() cty = function (str) local spl = split(str) local ct = ctypes[spl[1]] for i=2,#spl do ct = ct:_(spl[i]) end return ct end -- dump-to: tests --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ctypes2.lua" PP(cty "char [1] [2] * * [10]") -- build PP(cty "char[1][2]**[10]") -- reuse CTypeDefType = Class { type = "CTypeDefType", __init = function (c, o) ctypes[o.ctype] = o end, __index = { }, } -- More classes: -- CObj, CField, CStructType, CUnionType, CFunctionType, CTypedefType -- Methods: -- star, plus, read, write ------------------------------------------------------------ CStructType {ctype="struct{int a,char b}", nbytes=5, align=4, offsets={["a"]=CField {ctype="int", offset=0}, ["b"]=CField {ctype="char", offset=4}, }, } CUnionType {ctype="union{int a,char b}", nbytes=4, align=4, offsets={["a"]=CField {ctype="int", offset=0}, ["b"]=CField {ctype="char", offset=0}, }, } CTypedefType {ctype="sab", base="struct{int a,char b}", nbytes=5, align=4} CTypedefType {ctype="uab", base="union{int a,char b}", nbytes=4, align=4} PP(ctypes) -- (find-blogme4 "eval.lua" "parse_pattern") CObj {ctype="char", addr=1000, bytes="w"} CObj {ctype="char*", addr=1000} CObj {ctype="char*", addr=1000, bytes="!@#$"} methods: plus peek poke star -- -- __int__ __int__ c______ -- |_:_:_:_|_:_:_:_|_|_:_:_| -- \-----intintc-----/ -- 0 1 2 3 4 5 6 7 8 9 101112 -- Example: if "intintc" is a ctype with nbytes=9 and align=4, -- then it has excess=1 and miss=3, and "intintc[100]" is a ctype -- with nbytes = (9+3)*100-3 = 1200-3 = 1197. -- excess = nbytes % align miss = (excess == 0) and 0 else (nbytes - excess) fake("char*", 1000) (char*)1000 + 1 = (char*)1004 sizeof((char*)1000) = sizeof((char*)) = 4 *(char*)1000 = peek(1000, 1) = "a" (char)25 (int)1234 * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) require "ctypes" string.tonumber = tonumber printf_ = tostring(printf):match("0x([0-9a-f]+)"):tonumber(16) = peek_(printf_, 10) -- (find-es "lua5" "lua-datatypes-gdb") -- require "peek" -- (find-angg "peek/peek-0.0.1-0.rockspec" "test") buf = malloc_(20) poke_(buf, "abcd") PP(peek_(buf+2, 2)) --> "cd" = print = tostring(print) = tostring(print):match("0x([0-9A-Fa-f]+)") = tostring(print):match("0x([0-9A-Fa-f]+)") hexton = function (hexstr) return tonumber(hexstr:match("0x([0-9A-Fa-f]+)"), 16) end ntohex = function (n) return string.format("0x%x", n) end = hexton "0x2F" = ntohex(47) * (find-angg "peek/peek-0.0.1-0.rockspec" "test") --]==] -- (find-angg "peek/ctypes.lua") -- (find-angg "DAVINCI/peek.lua") -- (find-angg "DAVINCI/peek-luadecls-1.txt") -- (find-angg "DAVINCI/peek-luadecls-2.txt") -- Local Variables: -- coding: raw-text-unix -- ee-anchor-format: "«%s»" -- End: