cleanup, add support for vxbuild-cross build system

This commit is contained in:
Mikhail Kochegarov
2022-12-20 14:50:29 +10:00
parent a0130edbbe
commit d04c833f9e
58 changed files with 1075 additions and 5597 deletions
-22
View File
@@ -1,22 +0,0 @@
winapi License
-----------
Copyright (C) 2011 Steve Donovan.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
-3
View File
@@ -1,3 +0,0 @@
REM building documentation with ldoc
REM http://github.com/stevedonovan/LDoc
ldoc winapi.l.c -o api && lua markdown.lua readme.md -s doc.css -l
-6
View File
@@ -1,6 +0,0 @@
REM compiling for mingw against msvcrt
set LUA_DIR=D:\dev\lua\lua-5.2.0\src
set CFLAGS=-c -g -DPSAPI_VERSION=1 -I"%LUA_DIR%"
gcc %CFLAGS% winapi.c
gcc %CFLAGS% wutils.c
gcc -g -shared winapi.o wutils.o "%LUA_DIR%\lua52.dll" -lpsapi -lMpr -o winapi.dll
-6
View File
@@ -1,6 +0,0 @@
REM building with mingw for LfW
set LUA_DIR=C:\Program Files\Lua\5.1
set CFLAGS=-Os -DPSAPI_VERSION=1 -I"%LUA_DIR%\include"
gcc -c %CFLAGS% winapi.c
gcc -c %CFLAGS% wutils.c
gcc -Wl,-s -shared winapi.o wutils.o -L"%LUA_DIR%/lib" -lpsapi -lMpr -llua5.1 -lmsvcr80 -o winapi.dll
-8
View File
@@ -1,8 +0,0 @@
REM compiling for mingw against msvcrt
# set LUA_DIR=D:\dev\lua\luajit-2.0\src
set LUA_INCLUDE=c:\users\steve\luadist\include
set LUA_LIB=c:\users\steve\luadist\lib\liblua51.dll.a
set CFLAGS=-c -O1 -DPSAPI_VERSION=1 -I"%LUA_INCLUDE%"
gcc %CFLAGS% winapi.c
gcc %CFLAGS% wutils.c
gcc -Wl,-s -shared winapi.o wutils.o "%LUA_LIB%" -lpsapi -lMpr -o winapi.dll
-1
View File
@@ -1 +0,0 @@
luam -C -llc winapi.l.c > winapi.c
-5
View File
@@ -1,5 +0,0 @@
set LUA_DIR=C:\Program Files\Lua\5.1
set CFLAGS= /O1 /DPSAPI_VERSION=1 /I"%LUA_DIR%\include"
cl /nologo -c %CFLAGS% winapi.c
cl /nologo -c %CFLAGS% wutils.c
link /nologo winapi.obj wutils.obj /EXPORT:luaopen_winapi /LIBPATH:"%LUA_DIR%\lib" msvcrt.lib kernel32.lib user32.lib psapi.lib advapi32.lib shell32.lib Mpr.lib lua5.1.lib /DLL /OUT:winapi.dll
-6
View File
@@ -1,6 +0,0 @@
REM convert the markdown to HTML
lua markdown.lua readme.md -s doc.css -l
copy readme.html docs\index.html
copy doc.css docs\default.css
del readme.html
-1
View File
@@ -1 +0,0 @@
del *.manifest *.o *.obj *.exp *.lib *.d *.spec
-18
View File
@@ -1,18 +0,0 @@
-- ldoc configuration file
file = "winapi.l.c"
output = "api"
title = "Winapi documentation"
project = "winapi"
readme = "readme.md"
--one = true
-- no_summary = true
examples = {'examples', exclude = {'examples/slow.lua'}}
description = [[
A minimal but useful binding to the Windows API.
]]
--manual_url 'file:///D:/dev/lua/projects/lua-5.1.4/doc/manual.html'
format = 'discount'
+3
View File
@@ -0,0 +1,3 @@
[ `uname` = Linux ] && { export X=i686-w64-mingw32-; }
P=mingw32 C="-DPSAPI_VERSION=1 -fPIC" L="-s -static-libgcc -lpsapi -lmpr ../../bin/$P/luajit.a" \
D=winapi.dll A=winapi.a ./build.sh
+3
View File
@@ -0,0 +1,3 @@
[ `uname` = Linux ] && { export X=x86_64-w64-mingw32-; }
P=mingw64 C="-DPSAPI_VERSION=1 -fPIC" L="-s -static-libgcc -lpsapi -lmpr ../../bin/$P/luajit.a" \
D=winapi.dll A=winapi.a ./build.sh
+7
View File
@@ -0,0 +1,7 @@
[ "$CC" ] || CC=gcc
mkdir -p ../../bin/$P
${X}${CC} -c -O2 $C *.c -Wall -I. -I../lua-headers
${X}${CC} *.o -shared -o ../../bin/$P/$D $L
rm -f ../../bin/$P/$A
${X}ar rcs ../../bin/$P/$A *.o
rm *.o
File diff suppressed because it is too large Load Diff
+44
View File
@@ -392,3 +392,47 @@ LPCSTR mb_result (int res) {
}
}
/// create job for child process control.
// @param hJob handle to the windows job
// @param ... looks like CreateProcessW
// @return a boolean (is it was successful?)
// @function create_process_in_job
BOOL create_process_in_job(
HANDLE hJob,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION ppi)
{
BOOL fRc = CreateProcessW(
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags | CREATE_SUSPENDED,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
ppi);
if (fRc) {
fRc = AssignProcessToJobObject(hJob, ppi->hProcess);
if (fRc && !(dwCreationFlags & CREATE_SUSPENDED)) {
fRc = ResumeThread(ppi->hThread) != (DWORD)-1;
}
if (!fRc) {
TerminateProcess(ppi->hProcess, 0);
CloseHandle(ppi->hProcess);
CloseHandle(ppi->hThread);
ppi->hProcess = ppi->hThread = NULL;
}
}
return fRc;
}
+12
View File
@@ -39,5 +39,17 @@ int push_wstring(lua_State *L, LPCWSTR us);
HKEY split_registry_key(LPCSTR path, char *keypath);
int mb_const (LPCSTR name);
LPCSTR mb_result (int res);
BOOL create_process_in_job(
HANDLE hJob,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION ppi);
#endif
-9
View File
@@ -1,9 +0,0 @@
body {
padding-left: 2em;
}
pre {
background-color: #eeeeff
}
a:link { font-weight:bold; color: #004080; text-decoration: none; }
a:visited { font-weight:bold; color: #006699; text-decoration: none; }
a:link:hover { text-decoration:underline; }
-27
View File
@@ -1,27 +0,0 @@
require 'winapi'
fprintf = require 'pl.utils'.fprintf
stderr = io.stderr
e = winapi.event()
winapi.make_timer(500,function()
fprintf(stderr,'signal!\n')
e:signal()
end)
--[[
while true do
e:wait()
print 'ok'
end
--]]
e:wait_async(function(s)
fprintf (stderr,'finis %s\n',s)
os.exit()
end)
fprintf(stderr,'sleeping\n')
winapi.sleep(-1)
-6
View File
@@ -1,6 +0,0 @@
local W = require 'winapi'
local console = W.get_foreground_window()
console:set_text 'e???????'
W.set_clipboard 'e???????'
print 'Press enter'
io.read()
-28
View File
@@ -1,28 +0,0 @@
require 'winapi'
drives = winapi.get_logical_drives()
for _,drive in ipairs(drives) do
local free,avail = winapi.get_disk_free_space(drive)
if not free then -- call failed, avail is error
free = '('..avail..')'
else
free = math.ceil(free/1024) -- get Mb
end
local rname = ''
local dtype = winapi.get_drive_type(drive)
if dtype == 'remote' then
rname = winapi.get_disk_network_name(drive:gsub('\\$',''))
end
print(drive,dtype,free,rname)
end
--[[ output:
C:\ fixed 1785
D:\ fixed 49916
E:\ cdrom (The device is not ready.)
G:\ remote 33823 \\CARL-VFILE\SYS
I:\ remote 433682 \\CARL-VFILE\GROUPS
X:\ remote 12160 \\CARL-VFILE\APPS
Y:\ remote 33823 \\CARL-VFILE\SYS\PUBLIC
Z:\ remote 33823 \\CARL-VFILE\SYS\PUBLIC
]]
-19
View File
@@ -1,19 +0,0 @@
local W = require 'winapi'
local e = W.event()
local count = 1
local finished
W.make_timer(500,function()
print 'tick'
if count == 5 then
print 'finished!'
finished = true
end
e:signal()
count = count + 1
end)
while not finished do
e:wait()
print 'gotcha'
end
-12
View File
@@ -1,12 +0,0 @@
-- iterating over all files matching some pattern.
-- (this handles Unicode file names correctly)
require 'winapi'
winapi.set_encoding(winapi.CP_UTF8)
files,err = winapi.files ('*.txt',false)
if not files then return print(err) end
for f in files do
print(f)
end
-3
View File
@@ -1,3 +0,0 @@
Τη γλώσσα μου έδωσαν ελληνική
το σπίτι φτωχικό στις αμμουδιές του Ομήρου.
Μονάχη έγνοια η γλώσσα μου στις αμμουδιές του Ομήρου.
-12
View File
@@ -1,12 +0,0 @@
-- this shows how @{Process:wait_for_input_idle} means that there's no need for
-- a random wait until an application is ready to go.
-- Note, if we use @{spawn_process} then the window is initially invisible,
-- and needs to be shown explicitly.
require 'winapi'
P = winapi.spawn_process 'notepad'
P:wait_for_input_idle()
w = winapi.find_window_match 'Untitled'
w:show()
w:set_foreground()
winapi.send_to_window 'hello dammit'
-10
View File
@@ -1,10 +0,0 @@
local W = require 'winapi'
print(W.show_message("Message","stuff"))
print(W.show_message("Message","stuff\nand nonsense","yes-no","warning"))
-16
View File
@@ -1,16 +0,0 @@
require 'winapi'
function printer(msec,msg)
local i = 1
return winapi.make_timer(500,function()
print (msg,i)
i = i + 1
end)
end
printer(500,'bob')
printer(500,'june')
printer(500,'alice')
printer(500,'jim')
winapi.sleep(-1)
-72
View File
@@ -1,72 +0,0 @@
require 'winapi'
--[[ -- blocking version
winapi.make_pipe_server(function(f)
local res = f:read()
f:write(res:upper())
end)
-- ]]
--[[ 'node.js' style
winapi.make_pipe_server(function(f)
f:read_async(function(res)
f:write(res:upper())
end)
end)
--]]
local wrap, yield, resume = coroutine.wrap, coroutine.yield, coroutine.resume
--[[
winapi.make_pipe_server(function(f)
local fun = function(f)
while true do
local res = f:read()
if res == 'close' then break end
f:write(res:upper())
end
end
local co = coroutine.create(fun)
resume(co,fwrap(f,co))
end)
]]
--~ f:read_async(function(txt)
--~ resume(co,txt)
--~ end)
function fwrap (f,co)
local obj = {}
local started
function obj:read ()
if not started then
f:read_async(co)
started = true
end
return yield()
end
function obj:write (s)
return f:write(s)
end
return obj
end
function winapi.make_pipe_server_async(fun)
winapi.make_pipe_server(function(f)
local co = coroutine.wrap(fun)
co(fwrap(f,co))
end)
end
winapi.make_pipe_server_async(function(f)
while true do
local res = f:read()
if res == 'close' then break end
f:write(res:upper())
end
print 'finis'
end)
winapi.sleep(-1)
-11
View File
@@ -1,11 +0,0 @@
require 'winapi'
t = os.clock()
n = tonumber(arg[1] or 2)
local P = {}
for i = 1,n do
P[i],f = winapi.spawn_process ('lua slow.lua '..i)
f:read_async(print)
end
winapi.wait_for_processes(P,true)
print(os.clock() - t)
-11
View File
@@ -1,11 +0,0 @@
require 'winapi'
f = winapi.get_console()
f:read_async(function(line)
f:write(line)
if line:match '^quit' then
os.exit()
end
end)
winapi.sleep(-1)
-18
View File
@@ -1,18 +0,0 @@
require 'winapi'
local f,e = winapi.open_serial 'COM4 baud=19'
if not f then return print('error',e) end
local sub = f:read()
local line = {}
local append = table.insert
while sub ~= '+' do
f:write(sub)
append(line,sub)
if sub == '\r' then
f:write '\n'
print('gotcha',table.concat(line))
line = {}
end
--print(sub,sub:byte(1))
sub = f:read()
end
f:close()
-21
View File
@@ -1,21 +0,0 @@
-- You will only get nice output from this script (like other unicode examples)
-- if executed in a properly multilingual environment like SciTE.
-- To get UTF-8 support in SciTE, edit your global properties like so:
-- # Internationalisation
-- # Japanese input code page 932 and ShiftJIS character set 128
-- #code.page=932
-- #character.set=128
-- # Unicode
-- code.page=65001 # uncomment out this line
-- #code.page=0 # and comment out this line
--
-- And restart SciTE.
require 'winapi'
winapi.setenv('greek','ελληνική')
print(os.getenv 'greek') -- this will still be nil
-- but child processes can see this variable ...
os.execute [[lua -e "print(os.getenv('greek'))"]]
-4
View File
@@ -1,4 +0,0 @@
print(arg[1])
for i = 1,1e8 do end
-4
View File
@@ -1,4 +0,0 @@
require 'winapi'
p = winapi.get_current_process()
print(os.date('%c',os.time(p:get_start_time())))
-9
View File
@@ -1,9 +0,0 @@
require 'winapi'
pids = winapi.get_processes()
for _,pid in ipairs(pids) do
local P = winapi.process_from_id(pid)
local name = P:get_process_name(true)
if name then print(pid,name) end
P:close()
end
-29
View File
@@ -1,29 +0,0 @@
require 'winapi'
k,err = winapi.open_reg_key [[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers]]
if not k then return print('bad key',err) end
print(k:get_value("1"))
k:close()
k,err = winapi.open_reg_key [[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion]]
t = k:get_keys()
--for _,k in ipairs(t) do print(_,k) end
k:close()
k,err = winapi.open_reg_key ([[HKEY_CURRENT_USER\Environment]],true)
path = k:get_value("PATH")
print(path)
print(k:get_value("TEMP"))
if #arg > 0 then
local type = winapi.REG_SZ
if arg[3] then
type = winapi[arg[3]]
end
k:set_value(arg[1],arg[2],type)
print(k:get_value(arg[1],type))
end
k:close()
-17
View File
@@ -1,17 +0,0 @@
require 'winapi'
l = 1
winapi.make_timer(400,function()
print 'bonzo'
l = l + 1
if l > 10 then os.exit() end
end)
k = 1
winapi.make_timer(300,function()
print 'alice'
k = k +1
if k > 5 then return true end
end)
winapi.sleep(-1)
-10
View File
@@ -1,10 +0,0 @@
require 'winapi'
P,W = winapi.spawn_process 'lua test-timer.lua'
stuff = W:read()
k = 1
while stuff do
io.write(stuff);
stuff = W:read()
k = k + 1
if k > 15 then P:kill() end
end
-26
View File
@@ -1,26 +0,0 @@
require 'winapi'
io.stdout:setvbuf 'no'
local t1,t2
t1 = winapi.make_timer(500,function()
print 'gotcha'
end)
local k = 1
t2 = winapi.make_timer(400,function()
k = k + 1
print(k)
if k > 5 then
print 'killing'
t1:kill() -- kill the first timer
t2 = nil
return true -- and we will end now
end
end)
winapi.make_timer(1000,function()
print 'doo'
if not t2 then os.exit(0) end -- we all finish
end)
-- sleep forever...
winapi.sleep(-1)
-8
View File
@@ -1,8 +0,0 @@
require 'winapi'
t = os.clock()
winapi.sleep(200)
for i = 1,1e8 do end
P = winapi.get_current_process()
print(P:get_working_size())
print(P:get_run_times())
print((os.clock() - t)*1000)
-33
View File
@@ -1,33 +0,0 @@
require 'winapi'
l = 1
winapi.make_timer(400,function()
print 'bonzo'
l = l + 1
--if l > 10 then os.exit() end
end)
winapi.make_timer(300,function()
print 'woo'
end)
function protected(val)
print(val)
end
-- --[[
while true do
winapi.sleep(200,true)
print 'gotcha'
end
--]]
--[[
while true do
winapi.sleep(200)
winapi.locked_eval(protected,'hello')
--protected 'hello' --> this will cause nonsense
end
--]]
-41
View File
@@ -1,41 +0,0 @@
require 'winapi'
io.stdout:setvbuf 'no'
local dir = '.'
local dir2 = dir .. '\\without_spaces'
local LAST_WRITE,FILE_NAME =
winapi.FILE_NOTIFY_CHANGE_LAST_WRITE,
winapi.FILE_NOTIFY_CHANGE_FILE_NAME
w1,err = winapi.watch_for_file_changes(dir,LAST_WRITE+FILE_NAME,false,print)
if not w1 then return print(err) end
w2,err = winapi.watch_for_file_changes(dir2,LAST_WRITE+FILE_NAME,false,print)
if not w2 then return print(err) end
-- ok, our watchers are in the background
winapi.sleep(200)
function writefile (name,text)
local f = io.open(name,'w')
f:write(text)
f:close()
end
writefile('without_spaces/out.txt','hello')
os.execute 'cd without_spaces && del frodo.txt && ren out.txt frodo.txt'
writefile ('mobo.txt','freaky')
winapi.sleep(200)
-- can stop a watcher by killing its thread
w1:kill()
writefile ('doof.txt','freaky')
winapi.sleep(200)
-17
View File
@@ -1,17 +0,0 @@
require 'winapi'
local U = winapi.uexpand
local encode = winapi.encode
local UTF8 = winapi.CP_UTF8
winapi.set_encoding(UTF8)
local short = winapi.short_path
local name = short 'ελληνική.txt'
os.remove(name)
print(name)
local f,err = io.open(name,'w')
if not f then return print(err) end
f:write 'a new file\n'
f:close()
-10
View File
@@ -1,10 +0,0 @@
require 'winapi'
local U = winapi.utf8_expand
local UTF8 = winapi.CP_UTF8
winapi.set_encoding(UTF8)
txt = U '#03BB + #03BC + C'
print(txt)
print(U '#03BD')
-32
View File
@@ -1,32 +0,0 @@
local W = require 'winapi'
local r,w = W.pipe()
local m = W.mutex()
function lprint(...)
m:lock()
print(...)
m:release()
end
function long(name)
lprint('hello',name)
for i = 1,2 do
m:lock()
w:write(name..i)
m:release()
for i = 1,1e8 do end
end
end
r:read_async(function(s)
lprint(s)
end)
T = {}
T[1] = W.thread(long,'john')
T[2] = W.thread(long,'jane')
T[3] = W.thread(long,'june')
W.wait_for_processes(T,true)
print 'finish'
Binary file not shown.
Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
c.shared{'examples/winapi',src='winapi wutils',needs='lua',
defines='PSAPI_VERSION=1',
libs = 'kernel32 user32 psapi advapi32 shell32 Mpr',
dynamic = true,
strip = true
}
target('winapi.c',{'winapi.l.c'},'luam -C -llc winapi.l.c 1>winapi.c')
-351
View File
@@ -1,351 +0,0 @@
-- Simplifying writing C extensions for Lua
-- Adds new module and class constructs;
-- see class1.lc and str.lc for examples.
local M = require 'macro'
function dollar_subst(s,tbl)
return (s:gsub('%$%((%a+)%)',tbl))
end
-- reuse some machinery from the C-skin experiments
local push,pop = table.insert,table.remove
local bstack,btop = {},{}
local function push_brace_stack (newv)
newv = newv or {}
newv.lev = 0
push(bstack,btop)
btop = newv
end
M.define('{',function()
if btop.lev then
btop.lev = btop.lev + 1
end
return nil,true --> pass-through macro
end)
M.define('}',function(get,put)
if not btop.lev then
return nil,true
elseif btop.lev == 0 then
local res
if btop.handler then res = btop.handler(get,put) end
if not res then res = put:space() '}' end
btop = pop(bstack)
return res
else
btop.lev = btop.lev - 1
return nil,true --> pass-through macro
end
end)
--------- actual implementation begins -------
local append = table.insert
local module
local function register_functions (names,cnames)
local out = {}
for i = 1,#names do
append(out,(' {"%s",l_%s},'):format(names[i],cnames[i]))
end
return table.concat(out,'\n')
end
local function finalizers (names)
local out = {}
for i = 1,#names do
append(out,names[i].."(L);")
end
return table.concat(out,'\n')
end
local typedefs
local preamble = [[
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#ifdef WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
#if LUA_VERSION_NUM > 501
#define lua_objlen lua_rawlen
#endif
]]
local finis = [[
static const luaL_Reg $(cname)_funs[] = {
$(funs)
{NULL,NULL}
};
EXPORT int luaopen_$(cname) (lua_State *L) {
#if LUA_VERSION_NUM > 501
lua_newtable(L);
luaL_setfuncs (L,$(cname)_funs,0);
lua_pushvalue(L,-1);
lua_setglobal(L,"$(cname)");
#else
luaL_register(L,"$(cname)",$(cname)_funs);
#endif
$(finalizers)
return 1;
}
]]
M.define('module',function(get)
local name = get:string()
local cname = name:gsub('%.','_')
get:expecting '{'
local out = preamble .. typedefs
push_brace_stack{
name = name, cname = cname,
names = {}, cnames = {}, finalizers = {},
handler = function()
local out = {}
local funs = register_functions(btop.names,btop.cnames)
local final = finalizers(btop.finalizers)
append(out,dollar_subst(finis, {
cname = cname,
name = name,
funs = funs,
finalizers = final
}))
return table.concat(out,'\n')
end }
module = btop
return out
end)
M.define('def',function(get)
local fname = get:name()
local cname = (btop.ns and btop.ns..'_' or '')..fname
append(btop.names,fname)
append(btop.cnames,cname)
get:expecting '('
local args = get:list():strip_spaces()
get:expecting '{'
local t,space = get()
indent = space:gsub('^%s*[\n\r]',''):gsub('%s$','')
local out = {"static int l_"..cname.."(lua_State *L) {"}
if btop.massage_arg then
btop.massage_arg(args)
end
for i,arg in ipairs(args) do
local mac = arg[1][2]..'_init'
if arg[3] and arg[3][1] == '=' then
mac = mac .. 'o'
i = i .. ',' .. arg[4][2]
end
if not arg[2] then M.error("parameter must be TYPE NAME [= VALUE]") end
append(out,indent..mac..'('..arg[2][2]..','..i..');')
end
--append(out,space)
return table.concat(out,'\n')..space
end)
M.define('constants',function(get,put)
get:expecting '{'
local consts = get:list '}' :strip_spaces()
--for k,v in pairs(btop) do io.stderr:write(k,'=',tostring(v),'\n') end
-- os.exit()
local fname = 'set_'..btop.cname..'_constants'
local out = { 'static void '..fname..'(lua_State *L) {'}
if not btop.finalizers then M.error("not inside a module") end
append(btop.finalizers,fname)
for _,c in ipairs(consts) do
local type,value,name
if #c == 1 then -- a simple int constant: CONST
name = c:pick(1)
type = 'Int'
value = name
else -- Type CONST [ = VALUE ]
type = c:pick(1)
name = c:pick(2)
if #c == 2 then
value = name
else
value = c:pick(4)
end
end
append(out,('%s_set("%s",%s);'):format(type,name,value ))
end
append(out,'}')
return table.concat(out,'\n')
end)
M.define('assign',function(get)
get:expecting '{'
local asses = get:list '}' :strip_spaces()
local out = {}
for _,c in ipairs(asses) do
append(out,('%s_set("%s",%s);\n'):format(c:pick(1),c:pick(2),c:pick(4)) )
end
return table.concat(out,'\n')
end)
local load_lua = [[
static void load_lua_code (lua_State *L) {
luaL_dostring(L,lua_code_block);
}
]]
M.define('lua',function(get)
get:expecting '{'
local block = tostring(get:upto '}')
local code_name = 'lua_code_block'
local out = {'static const char *'.. code_name .. ' = ""\\'}
for line in block:gmatch('([^\r\n]+)') do
line = line:gsub('\\','\\\\'):gsub('"','\\"')
append(out,' "'..line..'\\n"\\')
end
append(out,';')
append(out,load_lua)
out = table.concat(out,'\n')
append(module.finalizers,'load_lua_code')
return out
end)
M.define('initial',function(get)
local name = get:name()
append(module.finalizers,name)
get:expecting '{'
local body = tostring(get:upto '}')
return ('int %s(lua_State *L) {\n%s}\n'):format(name,body)
end)
typedefs = [[
typedef const char *Str;
typedef const char *StrNil;
typedef int Int;
typedef double Number;
typedef int Boolean;
]]
M.define 'Str_init(var,idx) const char *var = luaL_checklstring(L,idx,NULL)'
M.define 'Str_inito(var,idx,val) const char *var = luaL_optlstring(L,idx,val,NULL)'
M.define 'Str_set(name,value) lua_pushstring(L,value); lua_setfield(L,-2,name)'
M.define 'Str_get(var,name) lua_getfield(L,-1,name); var=lua_tostring(L,-1); lua_pop(L,1)'
M.define 'Str_geti(var,idx) lua_rawgeti(L,-1,idx); var=lua_tostring(L,-1); lua_pop(L,1)'
M.define 'StrNil_init(var,idx) const char *var = lua_tostring(L,idx)'
M.define 'Int_init(var,idx) int var = luaL_checkinteger(L,idx)'
M.define 'Int_inito(var,idx,val) int var = luaL_optinteger(L,idx,val)'
M.define 'Int_set(name,value) lua_pushinteger(L,value); lua_setfield(L,-2,name)'
M.define 'Int_get(var,name) lua_getfield(L,-1,name); var=lua_tointeger(L,-1); lua_pop(L,1)'
M.define 'Int_geti(var,idx) lua_rawgeti(L,-1,idx); var=lua_tointeger(L,-1); lua_pop(L,1)'
M.define 'Number_init(var,idx) double var = luaL_checknumber(L,idx)'
M.define 'Number_inito(var,idx,val) double var = luaL_optnumber(L,idx,val)'
M.define 'NUmber_set(name,value) lua_pushnumber(L,value); lua_setfield(L,-2,name)'
M.define 'Number_get(var,name) lua_getfield(L,-1,name); var=lua_tonumber(L,-1); lua_pop(L,1)'
M.define 'Number_geti(var,idx) lua_rawgeti(L,-1,idx); var=lua_tonumber(L,-1); lua_pop(L,1)'
M.define 'Boolean_init(var,idx) int var = lua_toboolean(L,idx)'
M.define 'Boolean_set(name,value) lua_pushboolean(L,value); lua_setfield(L,-2,name)'
M.define 'Boolean_get(var,name) lua_getfield(L,-1,name); var=lua_toboolean(L,-1); lua_pop(L,1)'
M.define 'Boolean_geti(var,idx) lua_rawgeti(L,-1,idx); var=lua_toboolean(L,-1); lua_pop(L,1)'
M.define 'Value_init(var,idx) int var = idx'
M.define('lua_tests',function(get)
get:expecting '{'
local body = get:upto '}'
local f = io.open(M.filename..'.lua','w')
f:write(tostring(body))
f:close()
end)
------ class support ----------------------
local klass_ctor = "static void $(klass)_ctor(lua_State *L, $(klass) *this, $(fargs))"
local begin_klass = [[
typedef struct {
$(fields)
} $(klass);
define_ $(klass)_init(var,idx) $(klass) *var = $(klass)_arg(L,idx)
#define $(klass)_MT "$(klass)"
$(klass) * $(klass)_arg(lua_State *L,int idx) {
$(klass) *this = ($(klass) *)luaL_checkudata(L,idx,$(klass)_MT);
luaL_argcheck(L, this != NULL, idx, "$(klass) expected");
return this;
}
$(ctor);
static int push_new_$(klass)(lua_State *L,$(fargs)) {
$(klass) *this = ($(klass) *)lua_newuserdata(L,sizeof($(klass)));
luaL_getmetatable(L,$(klass)_MT);
lua_setmetatable(L,-2);
$(klass)_ctor(L,this,$(aargs));
return 1;
}
]]
local end_klass = [[
static const struct luaL_Reg $(klass)_methods [] = {
$(methods)
{NULL, NULL} /* sentinel */
};
static void $(klass)_register (lua_State *L) {
luaL_newmetatable(L,$(klass)_MT);
#if LUA_VERSION_NUM > 501
luaL_setfuncs(L,$(klass)_methods,0);
#else
luaL_register(L,NULL,$(klass)_methods);
#endif
lua_pushvalue(L,-1);
lua_setfield(L,-2,"__index");
lua_pop(L,1);
}
]]
M.define('class',function(get)
local name = get:name()
get:expecting '{'
local fields = get:upto (function(t,v)
return t == 'iden' and v == 'constructor'
end)
fields = tostring(fields):gsub('%s+$','\n')
get:expecting '('
local out = {}
local args = get:list()
local f_args = args:strip_spaces()
local a_args = f_args:pick(2)
f_args = table.concat(args:__tostring(),',')
a_args = table.concat(a_args,',')
local subst = {klass=name,fields=fields,fargs=f_args,aargs=a_args }
local proto = dollar_subst(klass_ctor,subst)
subst.ctor = proto
append(out,dollar_subst(begin_klass,subst))
append(out,proto)
local pp = {{'iden',name},{'iden','this'}}
push_brace_stack{
names = {}, cnames = {}, ns = name, cname = name,
massage_arg = function(args)
table.insert(args,1,pp)
end,
handler = function(get,put)
append(module.finalizers,name.."_register")
local methods = register_functions(btop.names,btop.cnames)
return dollar_subst(end_klass,{methods=methods,klass=name,fargs=f_args,aargs=a_args})
end
}
return table.concat(out,'\n')
end)
-4
View File
@@ -1,4 +0,0 @@
all: build
lake
build:
build-lc
-1388
View File
File diff suppressed because it is too large Load Diff
-19
View File
@@ -1,19 +0,0 @@
require 'winapi'
-- run the program: 'fire and forget'
p,f = winapi.spawn_process 'lua52 process-wait.lua'
-- echo process output to stdout
f:read_async(print)
-- call this function when we're finished
p:wait_async(function(s)
print ('finis',s,p:get_exit_code())
os.exit()
end)
a = 0
--print 'sleeping'
winapi.sleep(-1)
-2164
View File
File diff suppressed because it is too large Load Diff
View File
+50
View File
@@ -0,0 +1,50 @@
require 'winapi'
local r,w = winapi.pipe()
local m = winapi.mutex()
local function lprint(...)
m:lock()
print(...)
m:release()
end
local function long(name)
lprint('hello',name)
for i = 1,2 do
m:lock()
w:write(name..tostring(i))
m:release()
end
end
r:read_async(function(s)
lprint(s)
end)
local T = {}
T[1] = winapi.thread(long, 'john')
T[2] = winapi.thread(long, 'jane')
T[3] = winapi.thread(long, 'june')
winapi.wait_for_processes(T, true)
print 'thread test was finished'
local e = winapi.event()
local count = 1
local finished
winapi.make_timer(500, function()
print 'tick'
if count == 5 then
print 'finished!'
finished = true
end
e:signal()
count = count + 1
end)
while not finished do
e:wait()
print 'gotcha'
end
print 'events test was finished'