require("import")	-- the import fn
import("template_default_arg")	-- import code
--for k,v in pairs(template_default_arg) do _G[k]=v end -- move to global

helloInt = template_default_arg.Hello_int()
assert(template_default_arg.Hello_int_hi ~= nil)
helloInt:foo(template_default_arg.Hello_int_hi)

x = template_default_arg.X_int()
assert(x:meth(20.0, 200) == 200,"X_int test 1 failed")
assert(x:meth(20) == 20,"X_int test 2 failed")
assert(x:meth() == 0,"X_int test 3 failed")

y = template_default_arg.Y_unsigned()
assert(y:meth(20.0, 200) == 200,"Y_unsigned test 1 failed")
assert(y:meth(20) == 20,"Y_unsigned test 2 failed")
assert(y:meth() == 0,"Y_unsigned test 3 failed")

x = template_default_arg.X_longlong()
x = template_default_arg.X_longlong(20.0)
x = template_default_arg.X_longlong(20.0, 200) -- note: long longs just treated as another number

x = template_default_arg.X_int()
x = template_default_arg.X_int(20.0)
x = template_default_arg.X_int(20.0, 200)

x = template_default_arg.X_hello_unsigned()
x = template_default_arg.X_hello_unsigned(20.0)
x = template_default_arg.X_hello_unsigned(20.0, template_default_arg.Hello_int())

y = template_default_arg.Y_hello_unsigned()
y:meth(20.0, template_default_arg.Hello_int())
y:meth(template_default_arg.Hello_int())
y:meth()

fz = template_default_arg.Foo_Z_8()
x = template_default_arg.X_Foo_Z_8()
fzc = x:meth(fz)

-- Templated functions

-- plain function: int ott(Foo<int>)
assert(template_default_arg.ott(template_default_arg.Foo_int()) == 30,"ott test 1 failed")

-- %template(ott) ott<int, int>
assert(template_default_arg.ott() == 10,"ott test 2 failed")
assert(template_default_arg.ott(1) == 10,"ott test 3 failed")
assert(template_default_arg.ott(1, 1) == 10,"ott test 4 failed")

assert(template_default_arg.ott("hi") == 20,"ott test 5 failed")
assert(template_default_arg.ott("hi", 1) == 20,"ott test 6 failed")
assert(template_default_arg.ott("hi", 1, 1) == 20,"ott test 7 failed")

-- %template(ott) ott<const char *>
assert(template_default_arg.ottstring(template_default_arg.Hello_int(), "hi") == 40,"ott test 8 failed")
assert(template_default_arg.ottstring(template_default_arg.Hello_int()) == 40,"ott test 9 failed")

-- %template(ott) ott<int>
assert(template_default_arg.ottint(template_default_arg.Hello_int(), 1) == 50,"ott test 10 failed")
assert(template_default_arg.ottint(template_default_arg.Hello_int()) == 50,"ott test 11 failed")

-- %template(ott) ott<double>
assert(template_default_arg.ott(template_default_arg.Hello_int(), 1.0) == 60,"ott test 12 failed")
assert(template_default_arg.ott(template_default_arg.Hello_int()) == 60,"ott test 13 failed")


require("import")	-- the import fn
import("primitive_ref")	-- import code
pr=primitive_ref --alias

assert(pr.ref_int(3)==3)

assert(pr.ref_uint(3) == 3)

assert(pr.ref_short(3) == 3)

assert(pr.ref_ushort(3) == 3)

assert(pr.ref_long(3) == 3)

assert(pr.ref_ulong(3) == 3)

assert(pr.ref_schar(3) == 3)

assert(pr.ref_uchar(3) == 3)

assert(pr.ref_float(3.5) == 3.5)

assert(pr.ref_double(3.5) == 3.5)

assert(pr.ref_bool(true) == true)

assert(pr.ref_char('x') == 'x')

assert(pr.ref_over(0) == 0)

a=pr.A(12)
assert(pr.ref_over(a)==12)


require("import")	-- the import fn
import("keyword_rename_c")	-- import lib into global
kn=keyword_rename_c--alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- Check renaming of Lua keywords
assert(kn.c_end(5) == 5)
assert(kn.c_nil(7) == 7)


-- demo of lua swig capacilities (operator overloading)
require("import")	-- the import fn
import("exception_order")	-- import lib into global
eo=exception_order --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

a = eo.A()

function try1()
	a:foo()
end

function try2()
	a:bar()
end

function try3()
	a:foobar()
end

-- the following code used to work
-- but now no longer works, as the lua bindings don't throw objects any more
-- all objects are converted to string & thrown
-- it could be made to work, if E1 & E2 were thrown by value (see lua.swg)
--[[
ok,ex=pcall(try1)
print(ok,ex)
assert(ok==false and swig_type(ex)==swig_type(eo.E1()))

ok,ex=pcall(try2)
assert(ok==false and swig_type(ex)==swig_type(eo.E2()))
]]
-- this new code does work, but has to look at the string
ok,ex=pcall(try1)
assert(ok==false and ex=="object exception:E1")

ok,ex=pcall(try2)
assert(ok==false and ex=="object exception:E2")

-- the SWIG_exception is just an error string
ok,ex=pcall(try3)
assert(ok==false and type(ex)=="string")


require("import")	-- the import fn
import("rename_simple")	-- import lib
rs = rename_simple

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(rs.NewStruct ~= nil)
assert(rs.NewStruct.NewStaticVariable == 444)
assert(rs.NewStruct_NewStaticVariable == 444)

assert(rs.NewStruct.NewStaticMethod() == 333)
assert(rs.NewStruct_NewStaticMethod() == 333)

assert(rs.NewStruct.ONE == 1)
assert(rs.NewStruct_ONE == 1)

assert(rs.NewFunction() == 555)

assert(rs.OldStruct == nil)
assert(rs.OldFunction == nil)
assert(rs.OldGlobalVariable == nil)
assert(rs.OldStruct_ONE == nil)


-- demo of lua swig capacities (operator overloading)
require("import")	-- the import fn
import("operator_overload")	-- import lib

for k,v in pairs(operator_overload) do _G[k]=v end -- move to global

-- first check all the operators are implemented correctly from pure C++ code
Op_sanity_check()

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- test routine:
a=Op()
b=Op(5)
c=Op(b) -- copy construct
d=Op(2)
dd=d; -- assignment operator

-- test equality
assert(a~=b)
assert(b==c)
assert(a~=d)
assert(d==dd)

-- test <
assert(a<b)
assert(a<=b)
assert(b<=c)
assert(b>=c)
assert(b>d)
assert(b>=d)

-- lua does not support += operators: skipping

-- test +
f=Op(1)
g=Op(1)
assert(f+g==Op(2))
assert(f-g==Op(0))
assert(f*g==Op(1))
assert(f/g==Op(1))
--assert(f%g==Op(0))	-- lua does not support %

-- test unary operators
--assert((not a)==true) -- lua does not allow overloading for not operator
--assert((not b)==false) -- lua does not allow overloading for not operator

--lua 5.0.2 defines that unary - is __unm(self,nil)
--lua 5.1.2 defines that unary - is __unm(self,self)
--C++ expects unary - as operator-()
--however the latest version of SWIG strictly checks the number of args
--and will complain if too many args are provided
--therefore disabling these tests for now
-- (solution will to be not to check args for this test case)
assert(-a==a)
assert(-b==Op(-5))

-- test []
h=Op(3)
assert(h[0]==3)
assert(h[1]==0)
h[0]=2	-- set
assert(h[0]==2)
h[1]=2	-- ignored
assert(h[0]==2)
assert(h[1]==0)

-- test ()
i=Op(3)
assert(i()==3)
assert(i(1)==4)
assert(i(1,2)==6)

-- plus add some code to check the __str__ fn
assert(tostring(Op(1))=="Op(1)")
assert(tostring(Op(-3))=="Op(-3)")

-- check that operator overloads are correctly propagated down inheritance hierarchy

a_d=OpDerived()
b_d=OpDerived(5)
c_d=OpDerived(5)
d_d=OpDerived(2)
-- test equality
assert(a_d~=b_d)
assert(b_d==c_d)
assert(a_d~=d_d)

-- test <
assert(a_d<b_d)
assert(a_d<=b_d)
assert(b_d<=c_d)
assert(b_d>=c_d)
assert(b_d>d_d)
assert(b_d>=d_d)
--
-- test + inheritance
f_d=OpDerived(1)
g_d=OpDerived(1)
assert(f_d+g_d==Op(2))
assert(f_d-g_d==Op(0))
assert(f_d*g_d==Op(1))
assert(f_d/g_d==Op(1))
--
-- plus add some code to check the __str__ fn inheritance
assert(tostring(OpDerived(1))=="Op(1)")
assert(tostring(OpDerived(-3))=="Op(-3)")

--[[
/* Sample test code in C++

#include <assert.h>
#include <stdio.h>

int main(int argc,char** argv)
{
	// test routine:
	Op a;
	Op b=5;
	Op c=b;	// copy construct
	Op d=2;

	// test equality
	assert(a!=b);
	assert(b==c);
	assert(a!=d);

	// test <
	assert(a<b);
	assert(a<=b);
	assert(b<=c);
	assert(b>=c);
	assert(b>d);
	assert(b>=d);

	// test +=
	Op e=3;
	e+=d;
	assert(e==b);
	e-=c;
	assert(e==a);
	e=Op(1);
	e*=b;
	assert(e==c);
	e/=d;
	assert(e==d);
	e%=c;
	assert(e==d);

	// test +
	Op f(1),g(1);
	assert(f+g==Op(2));
	assert(f-g==Op(0));
	assert(f*g==Op(1));
	assert(f/g==Op(1));
	assert(f%g==Op(0));

	// test unary operators
	assert(!a==true);
	assert(!b==false);
	assert(-a==a);
	assert(-b==Op(-5));

	// test []
	Op h=3;
	assert(h[0]==3);
	assert(h[1]==0);
	h[0]=2;	// set
	assert(h[0]==2);
	h[1]=2;	// ignored
	assert(h[0]==2);
	assert(h[1]==0);

	// test ()
	Op i=3;
	assert(i()==3);
	assert(i(1)==4);
	assert(i(1,2)==6);

	// plus add some code to check the __str__ fn
	//assert(str(Op(1))=="Op(1)");
	//assert(str(Op(-3))=="Op(-3)");

	printf("ok\n");
}
*/
]]


require("import")	-- the import fn
import("global_namespace")	-- import lib into global
gn=global_namespace --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

k1 = gn.Klass1()
k2 = gn.Klass2()
k3 = gn.Klass3()
k4 = gn.Klass4()
k5 = gn.Klass5()
k6 = gn.Klass6()
k7 = gn.Klass7()

gn.KlassMethods.methodA(k1,k2,k3,k4,k5,k6,k7)
gn.KlassMethods.methodB(k1,k2,k3,k4,k5,k6,k7)

k1 = gn.getKlass1A()
k2 = gn.getKlass2A()
k3 = gn.getKlass3A()
k4 = gn.getKlass4A()
k5 = gn.getKlass5A()
k6 = gn.getKlass6A()
k7 = gn.getKlass7A()

gn.KlassMethods.methodA(k1,k2,k3,k4,k5,k6,k7)
gn.KlassMethods.methodB(k1,k2,k3,k4,k5,k6,k7)

k1 = gn.getKlass1B()
k2 = gn.getKlass2B()
k3 = gn.getKlass3B()
k4 = gn.getKlass4B()
k5 = gn.getKlass5B()
k6 = gn.getKlass6B()
k7 = gn.getKlass7B()

gn.KlassMethods.methodA(k1,k2,k3,k4,k5,k6,k7)
gn.KlassMethods.methodB(k1,k2,k3,k4,k5,k6,k7)

x1 = gn.XYZ1()
x2 = gn.XYZ2()
x3 = gn.XYZ3()
x4 = gn.XYZ4()
x5 = gn.XYZ5()
x6 = gn.XYZ6()
x7 = gn.XYZ7()

gn.XYZMethods.methodA(x1,x2,x3,x4,x5,x6,x7)
gn.XYZMethods.methodB(x1,x2,x3,x4,x5,x6,x7)

gn.AnEnumMethods.methodA(gn.anenum1, gn.anenum2, gn.anenum3)
gn.AnEnumMethods.methodB(gn.anenum1, gn.anenum2, gn.anenum3)

gn.TheEnumMethods.methodA(gn.theenum1, gn.theenum2, gn.theenum3)
gn.TheEnumMethods.methodB(gn.theenum1, gn.theenum2, gn.theenum3)


require("import")	-- the import fn
import("smart_pointer_simple")	-- import lib into global
sps=smart_pointer_simple --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo1 = sps.Foo()
foo1.x = 5
assert(foo1.x == 5)
assert(foo1:getx() == 5)

bar1 = sps.Bar(foo1)
bar1.x = 3
assert(bar1.x == 3)
assert(bar1:getx() == 3)

bar1.x = 5
assert(bar1.x == 5)
assert(bar1:getx() == 5)


require("import")	-- the import fn
import("enum_plus")	-- import lib
ep=enum_plus

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(ep.iFoo_Phoo == 50) -- Old variant of enum bindings
assert(ep.iFoo.Phoo == 50) -- New variant of enum bindings


require("import")	-- the import fn
import("smart_pointer_rename")	-- import lib into global
spr=smart_pointer_rename --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo = spr.Foo()
assert(foo:ftest1(1) == 1)
assert(foo:ftest2(1,2) == 2)

bar = spr.Bar(foo)
assert(bar:test() == 3)
assert(bar:ftest1(1) == 1)
assert(bar:ftest2(1,2) == 2)


require("import")	-- the import fn
import("extend_template")	-- import lib into global
et=extend_template--alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo1 = et.Foo_0()
assert(foo1:test1(5) == 5)
assert(foo1:test2(7) == 7)


require("import")	-- the import fn
import("refcount")	-- import lib
r=refcount

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

a = r.A()
assert(a:ref_count() == 1)

b1 = r.B(a)
assert(a:ref_count() == 2)

b2 = r.B.create(a)
assert(a:ref_count() == 3)

b3 = b2:cloner()
assert(a:ref_count() == 4)

rca = b1:get_rca() -- RCPtr<A> is not wrapped
assert(a:ref_count() == 5)

b4 = r.global_create(a)
assert(a:ref_count() == 6)


require("import")	-- the import fn
import("enums")	-- import lib

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- check values
assert(enums.CSP_ITERATION_FWD==0)
assert(enums.CSP_ITERATION_BWD==11)
assert(enums.ABCDE==0)
assert(enums.FGHJI==1)
assert(enums.boo==0)
assert(enums.hoo==5)
assert(enums.globalinstance1==0)
assert(enums.globalinstance2==1)
assert(enums.globalinstance3==30)
assert(enums.AnonEnum1==0)
assert(enums.AnonEnum2==100)

-- In C enums from struct are exported into global namespace (without prefixing with struct name)
-- In C++ they are prefixed (as compatibility thing).
-- We are emulating xor :)
assert(enums.BAR1 ~= enums.Foo_BAR1) -- It is either C style, or C++ style, but not both
assert((enums.BAR1 ~= nil ) or (enums.Foo_BAR1 ~= nil))

assert(enums.Phoo ~= enums.iFoo_Phoo)
assert((enums.Phoo == 50) or (enums.iFoo_Phoo == 50))
-- no point in checking fns, C will allow any value


require("import")	-- the import fn
import("fvirtual")	-- import lib into global
f=fvirtual --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

n1 = f.Node()
n2 = f.Node()
assert(n1:addChild(n2) == 1)

ns = f.NodeSwitch()
assert(ns:addChild(n2) == 2)
assert(ns:addChild(ns) == 2)
assert(ns:addChild(n1, false) == 3)


require("import")	-- the import fn
import("template_extend2")	-- import lib into global
te=template_extend2 --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

lb = te.lBaz()
assert(lb:foo() == "lBaz::foo")

db = te.dBaz()
assert(db:foo() == "dBaz::foo")


--Example using pointers to member functions
require("import")	-- the import fn
import("member_pointer")	-- import code
mp = member_pointer

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

function check(what, expected, actual)
	assert(expected == actual,"Failed: "..what.." Expected: "..expected.." Actual: "..actual)
end

-- Get the pointers
area_pt = mp.areapt()
perim_pt = mp.perimeterpt()

-- Create some objects
s = mp.Square(10)

-- Do some calculations
check ("Square area ", 100.0, mp.do_op(s,area_pt))
check ("Square perim", 40.0, mp.do_op(s,perim_pt))

-- Try the variables
-- these have to still be part of the 'member_pointer' table
memberPtr = mp.areavar
memberPtr = mp.perimetervar

check ("Square area ", 100.0, mp.do_op(s,mp.areavar))
check ("Square perim", 40.0, mp.do_op(s,mp.perimetervar))

-- Modify one of the variables
mp.areavar = perim_pt

check ("Square perimeter", 40.0, mp.do_op(s,mp.areavar))

-- Try the constants
memberPtr = mp.AREAPT
memberPtr = mp.PERIMPT
memberPtr = mp.NULLPT

check ("Square area ", 100.0, mp.do_op(s,mp.AREAPT))
check ("Square perim", 40.0, mp.do_op(s,mp.PERIMPT))


require("import")	-- the import fn
import("disown")	-- import code

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

for x=0,100 do
    a=disown.A()
    b=disown.B()
    b:acquire(a)
end
collectgarbage() -- this will double delete unless the memory is managed properly

a=disown.A()
a:__disown()
b:remove(a)
a=nil
collectgarbage() -- this will double delete unless the manual disown call worked


require("import")	-- the import fn
import("dynamic_cast")	-- import code

f = dynamic_cast.Foo()
b = dynamic_cast.Bar()

x = f:blah()
y = b:blah()

-- swig_type is a swiglua specific function which gets the swig_type_info's name
assert(swig_type(f)==swig_type(x))
assert(swig_type(b)==swig_type(y))

-- the real test: is y a Foo* or a Bar*?
assert(dynamic_cast.do_test(y)=="Bar::test")


require("import")	-- the import fn
import("extend")	-- import lib into global
e=extend --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

base1 = e.Base()
assert(base1.value == 0)
base2 = e.Base(10)
assert(base2.value == 10)

assert(base1:method(5) == 5)
assert(e.Base.zeroVal() == 0)
assert(base2:currentValue() == 10)
assert(base2:extendmethod(7) == 14)

der1 = e.Derived(0)
assert(der1.value == 0)
assert(der1:method(5) == 10)

der2 = e.Derived(17)
assert(der2.value == 34)
der2.extendval = 200.0
assert(math.abs(der2.actualval - 2.0) < 0.001)
assert(math.abs(der2.extendval - 200.0) < 0.001)


require("import")	-- the import fn
import("li_carrays")	-- import code
lc = li_carrays

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- Testing for %array_functions(int,intArray)
ary = lc.new_intArray(2)
lc.intArray_setitem(ary, 0, 0)
lc.intArray_setitem(ary, 1, 1)
assert(lc.intArray_getitem(ary, 0)==0)
assert(lc.intArray_getitem(ary, 1)==1)
lc.delete_intArray(ary)

-- Testing for %array_class(double, doubleArray)
d = lc.doubleArray(10)
d[0] = 7
d[5] = d[0] + 3
assert(d[5] + d[0] == 17)
--print(d[5] + d[0])

ptr = d:cast()	-- to ptr
d2 = lc.doubleArray_frompointer(ptr) -- and back to array
assert(d2[5] + d2[0] == 17)
--print(d2[5] + d2[0])


require("import")	-- the import fn
import("varargs")	-- import lib
v=varargs

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(v.test("Hello") == "Hello")
assert(v.test_def("Hello",0) == "Hello")

assert(v.Foo.statictest("Hello") == "Hello")
assert(v.Foo.statictest("Hello",1) == "Hello")

assert(v.test_plenty("Hello") == "Hello")
assert(v.test_plenty("Hello",1) == "Hello")
assert(v.test_plenty("Hello",1,2) == "Hello")


require("import")	-- the import fn
import("global_vars")	-- import lib
gv = global_vars

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

gv.b = "abcde"
assert(gv.b == "abcde")

gv.a.x = 7
assert(gv.a.x == 7)

a1 = gv.A()
a1.x = 11
gv.a = a1
assert(gv.a.x == 11)

gv.x = 10
assert(gv.x == 10)

assert(gv.Hi ~= nil)
assert(gv.Hola ~= nil)

gv.h = gv.Hi
assert(gv.h == gv.Hi)

-- It is not clear whether these tests should work or not
-- Currently they don't.
--
-- assert(gv.c_member == 10)
--
-- gv.c_member = 5
-- assert(gv.x == 5)
--
-- gv.h = gv.Hi
-- assert(gv.hr == gv.Hi)
--
-- gv.hr = gv.Hola
-- assert(gv.h == gv.Hola)
-- assert(gv.hr == gv.Hola)


require("import")	-- the import fn
import("extend_variable")	-- import lib into global
ev=extend_variable --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

e1 = ev.ExtendMe()
answ = 1.0
assert(e1:set(7.0))
--assert(e1:get(answ)) -- doesn't work. Lua can't pass primitive type by non-const reference
--assert(answ == 7.0)

e1.ExtendVar = 5.0
assert(e1.ExtendVar == 5.0)

assert(ev.Foo.Bar == 42)
assert(ev.Foo.AllBarOne == 4422)

assert(ev.Foo.StaticInt == 1111)
ev.Foo.StaticInt = 3333
assert(ev.Foo.StaticInt == 3333)

assert(ev.Foo.StaticConstInt == 2222)

b1 = ev.Bar()
assert(b1.x == 1)


require("import")	-- the import fn
import("nspace")	-- import lib

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

ns = nspace

-- Inheritance
blue1 = ns.Outer.Inner3.Blue()

-- blue1:blueInstanceMethod()
blue1:colorInstanceMethod(60.0)
blue1.instanceMemberVariable = 4
assert( blue1.instanceMemberVariable == 4 )

-- Constructors
color1 = ns.Outer.Inner1.Color()
color2 = ns.Outer.Inner1.Color.create()
color = ns.Outer.Inner1.Color(color1)
color3 = ns.Outer.Inner2.Color.create()
color4 = ns.Outer.Inner2.Color.create()
color5 = ns.Outer.Inner2.Color.create()
mwp2 = ns.Outer.MyWorldPart2()
gc = ns.GlobalClass()

nnsp = ns.NoNSpacePlease()

-- Class methods
color:colorInstanceMethod(20.0)
ns.Outer.Inner1.Color.colorStaticMethod(30.0)
color3:colorInstanceMethod(40.0)
ns.Outer.Inner2.Color.colorStaticMethod(50.0)
color3:colors(color1, color2, color3, color4, color5)

gc:gmethod()

-- Class variables
color.instanceMemberVariable = 5
color1.instanceMemberVariable = 7
assert( color.instanceMemberVariable == 5 )
assert( color1.instanceMemberVariable == 7 )
assert(ns.Outer.Inner1.Color.staticMemberVariable == 0 )
assert(ns.Outer.Inner2.Color.staticMemberVariable == 0 )
ns.Outer.Inner1.Color.staticMemberVariable = 9
ns.Outer.Inner2.Color.staticMemberVariable = 11
assert(ns.Outer.Inner1.Color.staticMemberVariable == 9)
assert(ns.Outer.Inner2.Color.staticMemberVariable == 11)

-- Class constants
assert( ns.Outer.Inner1.Color.Specular == 0x20 )
assert( ns.Outer.Inner2.Color.Specular == 0x40 )
assert( ns.Outer.Inner1.Color.staticConstMemberVariable == 222 )
assert( ns.Outer.Inner2.Color.staticConstMemberVariable == 333 )
assert( ns.Outer.Inner1.Color.staticConstEnumMemberVariable ~= ns.Outer.Inner2.Color.staticConstEnumMemberVariable )

-- Aggregation
sc = ns.Outer.SomeClass()
assert( sc:GetInner1ColorChannel() ~= sc:GetInner2Channel() )
assert( sc:GetInner1Channel() ~= sc:GetInner2Channel() )

-- Backward compatibility
assert(ns.Outer.Inner1.Diffuse ~= nil)
-- Enums within class within namespace shouldn't have backward compatible name. Same for static methods
assert(ns.Outer.Inner1.Color_Diffuse == nil)
assert(ns.Outer.Inner1.Color_colorStaticMethod == nil)

-- Enums and static methods of class marked as %nonspace should have backward compatible name
assert(ns.NoNSpacePlease_noNspaceStaticFunc() == 10)
assert(ns.Outer.Inner2.NoNSpacePlease_NoNspace == nil)
-- ReallyNoNSpaceEnum is wrapped into %nonspace and thus handled correctly.
-- NoNSpaceEnum is not (although both of them are in %nonspace-wrapped class) and thus
-- handled rather unexpectedly
assert(ns.NoNSpacePlease_ReallyNoNspace1 == 1)
assert(ns.NoNSpacePlease.ReallyNoNspace2 == 10)


require("import")	-- the import fn
import("argcargvtest")	-- import lib
v = argcargvtest

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

largs = {"hi", "hola", "hello"}
assert(v.mainc(largs) == 3, "bad main typemap")

targs = {"hi", "hola"}
assert(v.mainv(targs, 0) == "hi", "bad main typemap")
assert(v.mainv(targs, 1) == "hola", "bad main typemap")

errorVal = 0
function try()
    mainv("hello", 1)
    errorVal = 1
end
assert(not pcall(try) and errorVal == 0, "bad main typemap")

v.initializeApp(largs)


-- demo of lua swig capacilities (operator overloading)
require("import")	-- the import fn
import("cpp_static")	-- import lib into global
cs=cpp_static --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

cs.StaticMemberTest.static_int = 5;
assert(cs.StaticMemberTest.static_int == 5);

cs.StaticFunctionTest.static_func()
cs.StaticFunctionTest.static_func_2(2)
cs.StaticFunctionTest.static_func_3(3,3)


require("import")	-- the import fn
import("overload_template_fast")	-- import code
for k,v in pairs(overload_template_fast) do _G[k]=v end -- move to global

-- lua has only one numeric type, so maximum(int,int) and maximum(double,double) are the same
-- whichever one was wrapper first will be used (which is int)

f = foo()

a = maximum(3,4)

-- mix 1
assert(mix1("hi") == 101)
assert(mix1(1.0, 1.0) == 102)
assert(mix1(1.0) == 103)

-- mix 2
assert(mix2("hi") == 101)
assert(mix2(1.0, 1.0) == 102)
assert(mix2(1.0) == 103)

-- mix 3
assert(mix3("hi") == 101)
assert(mix3(1.0, 1.0) == 102)
assert(mix3(1.0) == 103)

-- Combination 1
assert(overtparams1(100) == 10)
assert(overtparams1(100.0, 100) == 20)

-- Combination 2
assert(overtparams2(100.0, 100) == 40)

-- Combination 3
assert(overloaded() == 60)
assert(overloaded(100.0, 100) == 70)

-- Combination 4
assert(overloadedagain("hello") == 80)
assert(overloadedagain() == 90)

-- specializations
assert(specialization(10) == 202 or specialization(10.0) == 203) -- only one works
assert(specialization(10, 10) == 204 or specialization(10.0, 10.0) == 205) -- ditto
assert(specialization("hi", "hi") == 201)

-- simple specialization
xyz()
xyz_int()
xyz_double()

-- a bit of everything
assert(overload("hi") == 0)
assert(overload(1) == 10)
assert(overload(1, 1) == 20)
assert(overload(1, "hello") == 30)

k = Klass()
assert(overload(k) == 10)
assert(overload(k, k) == 20)
assert(overload(k, "hello") == 30)
-- this one is incorrect: it mactches overload(10.0, "hi") with int overload(T t, const char *c)
--print(overload(10.0, "hi"))
--assert(overload(10.0, "hi") == 40)
assert(overload() == 50)

-- everything put in a namespace
assert(nsoverload("hi") == 1000,"nsoverload()")
assert(nsoverload(1) == 1010,"nsoverload(int t)")
assert(nsoverload(1, 1) == 1020,"nsoverload(int t, const int &)")
assert(nsoverload(1, "hello") == 1030,"nsoverload(int t, const char *)")
assert(nsoverload(k) == 1010,"nsoverload(Klass t)")
assert(nsoverload(k, k) == 1020,"nsoverload(Klass t, const Klass &)")
assert(nsoverload(k, "hello") == 1030,"nsoverload(Klass t, const char *)")
-- again this one fails
--assert(nsoverload(10.0, "hi") == 1040,"nsoverload(double t, const char *)")
assert(nsoverload() == 1050,"nsoverload(const char *)")

A_foo(1)
b = B()
b:foo(1)


require("import")	-- the import fn
import("extend_typedef_class")	-- import lib into global
etc=extend_typedef_class --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

function test_obj(obj, const)
  obj.membervar = const
  assert(obj:getvar() == const)
end

a1 = etc.AClass()
test_obj(a1,1)

b1 = etc.BClass()
test_obj(b1,2)

c1 = etc.CClass()
test_obj(c1,3)

d1 = etc.DClass()
test_obj(d1,4)

a2 = etc.AStruct()
test_obj(a2,5)

b2 = etc.BStruct()
test_obj(b2,6)

c2 = etc.CStruct()
test_obj(c2,7)

d2 = etc.DStruct()
test_obj(d2,8)


require("import")	-- the import fn
import("abstract_access")	-- import code

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- trying to instantiate pure virtual classes
-- should fail
assert(pcall(abstract_access.A)==false)
assert(pcall(abstract_access.B)==false)
assert(pcall(abstract_access.C)==false)

-- instantiate object
d=abstract_access.D()

--call fn
assert(d:do_x()==1)


require("import")	-- the import fn
import("li_std_pair")	-- import code

for k,v in pairs(li_std_pair) do _G[k]=v end -- move to global

intPair = makeIntPair(7, 6)
assert(intPair.first==7 and intPair.second==6)

intPairPtr = makeIntPairPtr(7, 6)
assert(intPairPtr.first==7 and intPairPtr.second==6)

intPairRef = makeIntPairRef(7, 6)
assert(intPairRef.first == 7 and intPairRef.second == 6)

intPairConstRef = makeIntPairConstRef(7, 6)
assert(intPairConstRef.first == 7 and intPairConstRef.second == 6)

-- call fns
assert(product1(intPair) == 42)
assert(product2(intPair) == 42)
assert(product3(intPair) == 42)

-- also use the pointer version
assert(product1(intPairPtr) == 42)
assert(product2(intPairPtr) == 42)
assert(product3(intPairPtr) == 42)

-- or the other types
assert(product1(intPairRef) == 42)
assert(product2(intPairRef) == 42)
assert(product3(intPairRef) == 42)
assert(product1(intPairConstRef) == 42)
assert(product2(intPairConstRef) == 42)
assert(product3(intPairConstRef) == 42)


require("import")	-- the import fn
import("overload_null")	-- import lib into global

o = overload_null.Overload()
x = overload_null.X()

assert(1 == o:byval1(x))
assert(2 == o:byval1(nil))

assert(3 == o:byval2(nil))
assert(4 == o:byval2(x))

assert(5 == o:byref1(x))
assert(6 == o:byref1(nil))

assert(7 == o:byref2(nil))
assert(8 == o:byref2(x))

assert(9 == o:byconstref1(x))
assert(10 == o:byconstref1(nil))

assert(11 == o:byconstref2(nil))
assert(12 == o:byconstref2(x))

-- const pointer references
assert(13 == o:byval1cpr(x))
assert(14 == o:byval1cpr(nil))

assert(15 == o:byval2cpr(nil))
assert(16 == o:byval2cpr(x))

-- fwd class declaration
assert(17 == o:byval1fwdptr(x))
assert(18 == o:byval1fwdptr(nil))

assert(19 == o:byval2fwdptr(nil))
assert(20 == o:byval2fwdptr(x))

assert(21 == o:byval1fwdref(x))

assert(22 == o:byval2fwdref(x))


require("import")	-- the import fn
import("li_std_auto_ptr")	-- import code

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

function checkCount(expected_count)
  -- call gc to make unused objects are collected
  collectgarbage()
  actual_count = li_std_auto_ptr.Klass.getTotal_count()
  if not (actual_count == expected_count) then
    error("Counts incorrect, expected:"..expected_count.." actual:"..actual_count)
  end
end

--Test raw pointer handling involving virtual inheritance
kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
checkCount(1)
s = li_std_auto_ptr.useKlassRawPtr(kini)
if not (s == "KlassInheritanceInput") then
  error("Incorrect string: "..s)
end
kini = nil
checkCount(0)

-- auto_ptr as input
kin = li_std_auto_ptr.Klass("KlassInput")
checkCount(1)
s = li_std_auto_ptr.takeKlassAutoPtr(kin)
checkCount(0)
if not (s == "KlassInput") then
  error("Incorrect string: "..s)
end
if not (li_std_auto_ptr.is_nullptr(kin)) then
  error("is_nullptr failed")
end
kin = nil -- Should not fail, even though already deleted
checkCount(0)

kin = li_std_auto_ptr.Klass("KlassInput")
checkCount(1)
s = li_std_auto_ptr.takeKlassAutoPtr(kin)
checkCount(0)
if not (s == "KlassInput") then
  error("Incorrect string: "..s)
end
if not (li_std_auto_ptr.is_nullptr(kin)) then
  error("is_nullptr failed")
end
s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(kin) end)
assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")

kin = nil -- Should not fail, even though already deleted
checkCount(0)

kin = li_std_auto_ptr.Klass("KlassInput")
notowned = li_std_auto_ptr.get_not_owned_ptr(kin)
s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(notowned) end)
assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")
checkCount(1)
kin = nil
checkCount(0)

kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
checkCount(1)
s = li_std_auto_ptr.takeKlassAutoPtr(kini)
checkCount(0)
if not (s == "KlassInheritanceInput") then
  error("Incorrect string: "..s)
end
if not (li_std_auto_ptr.is_nullptr(kini)) then
  error("is_nullptr failed")
end
kini = nil -- Should not fail, even though already deleted
checkCount(0)

li_std_auto_ptr.takeKlassAutoPtr(nil);
li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
checkCount(0);

-- overloaded parameters
if not (li_std_auto_ptr.overloadTest() == 0) then
  error("overloadTest failed")
end
if not (li_std_auto_ptr.overloadTest(nil) == 1) then
  error("overloadTest failed")
end
if not (li_std_auto_ptr.overloadTest(li_std_auto_ptr.Klass("over")) == 1) then
  error("overloadTest failed")
end
checkCount(0)

-- auto_ptr as output
k1 = li_std_auto_ptr.makeKlassAutoPtr("first")
k2 = li_std_auto_ptr.makeKlassAutoPtr("second")
checkCount(2)

k1 = nil
checkCount(1)

if not (k2:getLabel() == "second") then
  error("wrong object label")
end

k2 = nil
checkCount(0)

assert(li_std_auto_ptr.makeNullAutoPtr() == nil)


require("import")	-- the import fn
import("smart_pointer_not")	-- import lib into global
spn=smart_pointer_not --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo = spn.Foo()
foo.x = 7
assert(foo:getx() == 7)

bar = spn.Bar(foo)
success = pcall(bar.getx, bar) -- Bar is not a smart pointer. Call should fail
assert(not success)

spam = spn.Spam(foo)
success = pcall(spam.getx, spam) -- Spam is not a smart pointer. Call should fail
assert(not success)

grok = spn.Grok(foo)
success = pcall(grok.getx, grok) -- Spam is not a smart pointer. Call should fail
assert(not success)


require("import")	-- the import fn
import("li_carrays_cpp")	-- import code
lc = li_carrays_cpp

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- Testing for %array_functions(int,intArray)
ary = lc.new_intArray(2)
lc.intArray_setitem(ary, 0, 0)
lc.intArray_setitem(ary, 1, 1)
assert(lc.intArray_getitem(ary, 0)==0)
assert(lc.intArray_getitem(ary, 1)==1)
lc.delete_intArray(ary)

-- Testing for %array_class(double, doubleArray)
d = lc.doubleArray(10)
d[0] = 7
d[5] = d[0] + 3
assert(d[5] + d[0] == 17)
--print(d[5] + d[0])

ptr = d:cast()	-- to ptr
d2 = lc.doubleArray_frompointer(ptr) -- and back to array
assert(d2[5] + d2[0] == 17)
--print(d2[5] + d2[0])


require("import")	-- the import fn
import("overload_simple")	-- import code
for k,v in pairs(overload_simple) do _G[k]=v end -- move to global

-- lua has only one numeric type, foo(int) and foo(double) are the same
-- whichever one was wrapper first will be used

assert(foo(3)=="foo:int" or foo(3)=="foo:double") -- could be either
assert(foo("hello")=="foo:char *")

f=Foo()
b=Bar()

assert(foo(f)=="foo:Foo *")
assert(foo(b)=="foo:Bar *")

v = malloc_void(32)

assert(foo(v) == "foo:void *")

s = Spam()

assert(s:foo(3) == "foo:int" or s:foo(3.0) == "foo:double") -- could be either
assert(s:foo("hello") == "foo:char *")
assert(s:foo(f) == "foo:Foo *")
assert(s:foo(b) == "foo:Bar *")
assert(s:foo(v) == "foo:void *")

assert(Spam_bar(3) == "bar:int" or Spam_bar(3.0) == "bar:double")
assert(Spam_bar("hello") == "bar:char *")
assert(Spam_bar(f) == "bar:Foo *")
assert(Spam_bar(b) == "bar:Bar *")
assert(Spam_bar(v) == "bar:void *")

-- Test constructors

s = Spam()
assert(s.type == "none")

s = Spam(3)
assert(s.type == "int" or s.type == "double")

s = Spam("hello")
assert(s.type == "char *")

s = Spam(f)
assert(s.type == "Foo *")

s = Spam(b)
assert(s.type == "Bar *")

s = Spam(v)
assert(s.type == "void *")

free_void(v)


require("import")	-- the import fn
import("mod_a")	-- import lib
import("mod_b")	-- import lib
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
c = mod_b.C()
d = mod_b.D()


require("import")	-- the import fn
import("smart_pointer_overload")	-- import code
for k,v in pairs(smart_pointer_overload) do _G[k]=v end -- move to global

f = Foo()
b = Bar(f)

assert(f:test(3) == 1)
--assert(f:test(3.5) == 2)	-- won't work due to being unable to overloads
assert(f:test("hello") == 3)

assert(b:test(3) == 1)
--assert(b:test(3.5) == 2)	-- won't work due to being unable to overloads
assert(b:test("hello") == 3)


require("import")	-- the import fn
import("overload_complicated")	-- import lib into global
oc=overload_complicated --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(oc.foo(1,1,"test",1) == 15)

p1 = oc.Pop(nil)
p1 = oc.Pop(nil,false)

assert(p1:hip(false) == 701)
assert(p1:hip(nil) == 702)

assert(p1:hop(false) == 801)
assert(p1:hop(nil) == 805)

assert(oc.muzak(false) == 3001)
assert(oc.muzak(nil) == 3002)


require("import")	-- the import fn
import("smart_pointer_multi")	-- import lib into global
spm=smart_pointer_multi --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo = spm.Foo()
foo.x = 5
assert(foo:getx() == 5)

bar = spm.Bar(foo)
spam = spm.Spam(bar)
grok = spm.Grok(bar)

assert(bar:getx() == 5)
assert(spam:getx() == 5)
spam.x = 7
assert(grok:getx() == 7)
grok.x = 10
assert(foo:getx() == 10)


-- demo of lua swig
require("import")	-- the import fn
import("voidtest")	-- import lib

-- test calling functions
voidtest.globalfunc()
f = voidtest.Foo()
f:memberfunc()  -- member fns must have : not a .

voidtest.Foo_staticmemberfunc() -- static member fns are still a little messy

v1 = voidtest.vfunc1(f)
v2 = voidtest.vfunc2(f)

assert(swig_equals(v1,v2)) -- a raw equals will not work, we look at the raw pointers

v3 = voidtest.vfunc3(v1)
assert(swig_equals(v3,f))

v4 = voidtest.vfunc1(f)
assert(swig_equals(v4,v1))

v3:memberfunc()

-- also testing nil's support
-- nil, are acceptable anywhere a pointer is
n1 = voidtest.vfunc1(nil)
n2 = voidtest.vfunc2(nil)

assert(n1==nil)
assert(n2==nil)

n3 = voidtest.vfunc3(n1)
n4 = voidtest.vfunc1(nil)

assert(n3==nil)
assert(n4==nil)


require("import")	-- the import fn
import("funcptr_cpp")	-- import lib into global
fc=funcptr_cpp --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(fc.addByValue(5,10) == 15)
-- These two won't work. Lua will successfully store the answer as userdata, but there is
-- no way of accessing the insides of userdata.
-- assert(fc.addByPointer(7, 9) == 16)
-- assert(fc.addByReference(8, 9) == 17)

assert(fc.call1(fc.ADD_BY_VALUE, 5, 10) == 15)
assert(fc.call2(fc.ADD_BY_POINTER, 7, 9) == 16)
assert(fc.call3(fc.ADD_BY_REFERENCE, 8, 9) == 17)
assert(fc.call1(fc.ADD_BY_VALUE_C, 2, 3) == 5)


import

-- import
-- the lua 5.0 loading mechanism is rather poor & relies upon the loadlib() fn
-- the lua 5.1 loading mechanism is simplicity itself
-- for now we need a bridge which will use the correct version

function import_5_0(name)
	-- imports the file into the program
	-- for a module 'example'
	-- this must load 'example.dll' or 'example.so'
	-- and look for the fn 'luaopen_example()'
	if rawget(_G,name)~=nil then return end -- module appears to be loaded

	local lib=loadlib(name..'.dll','luaopen_'..name) or loadlib(name..'.so','luaopen_'..name)
	assert(lib,"error loading module:"..name)

	lib() -- execute the function: initialising the lib
	assert(rawget(_G,name)~=nil,"no module table found")
end

function import_5_1(name)
	require(name)
end

if string.sub(_VERSION,1,7)=='Lua 5.0' then
	import=import_5_0
else
	import=import_5_1
end


require("import")	-- the import fn
import("enum_scope_template")	-- import lib
est=enum_scope_template

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(est.TreeInt.Oak ~= nil)
assert(est.TreeInt_Oak ~= nil)
assert(est.TreeInt.Cedar ~= nil)


require("import")	-- the import fn
import("arrays_global")	-- import lib
ag = arrays_global

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(ag.BeginString_FIX44a == "FIX.a.a")
assert(ag.BeginString_FIX44b == "FIX.b.b")

assert(ag.BeginString_FIX44c == "FIX.c.c")
assert(ag.BeginString_FIX44d == "FIX.d.d")


require("import")	-- the import fn
import("valuewrapper")	-- import code
v=valuewrapper    -- renaming import

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(v.Xi ~= nil)
assert(v.YXi ~= nil)

x1 = v.Xi(5)

y1 =v.YXi()
assert(y1:spam(x1) == 0)
assert(y1:spam() == 0)


require("import")	-- the import fn
import("lua_inherit_getitem")	-- import lib

local t = lua_inherit_getitem;
local base = t.CBase()
local derived = t.CDerived()

assert(base.Foo ~= nil)
assert(base:Foo() == "CBase::Foo")
assert(derived.Foo == base.Foo)
assert(derived:Foo() == "CBase::Foo")


require("import")	-- the import fn
import("keyword_rename")	-- import lib into global
kn=keyword_rename--alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- Check renaming of Lua keywords
assert(kn.c_end(5) == 5)
assert(kn.c_nil(7) == 7)


require("import")	-- the import fn
import("li_std_except")	-- import code

test = li_std_except.Test()
-- under lua, all the std::exceptions are just turned to strings, so we are only checking that is fails
assert(pcall(function() test:throw_bad_exception() end)==false)
assert(pcall(function() test:throw_domain_error() end)==false)
assert(pcall(function() test:throw_exception() end)==false)
assert(pcall(function() test:throw_invalid_argument() end)==false)
assert(pcall(function() test:throw_length_error() end)==false)
assert(pcall(function() test:throw_logic_error() end)==false)
assert(pcall(function() test:throw_out_of_range() end)==false)
assert(pcall(function() test:throw_overflow_error() end)==false)
assert(pcall(function() test:throw_range_error() end)==false)
assert(pcall(function() test:throw_runtime_error() end)==false)
assert(pcall(function() test:throw_underflow_error() end)==false)


require("import")	-- the import fn
import("iadd")	-- import lib into global
i=iadd --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo1 = i.Foo()
foo1_a = foo1.AsA
assert(foo1_a.x == 5)
assert(foo1_a:get_me().x == 5)
-- Unfortunately, in Lua operator+= can't be overloaded

foo1.AsLong = 1000
assert(foo1.AsLong == 1000)


require("import")	-- the import fn
import("nspace_extend")	-- import lib

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

ne = nspace_extend

-- Inner1

-- Constructors
in1_clr1 = ne.Outer.Inner1.Color()
in1_clr2 = ne.Outer.Inner1.Color.create()
in1_clr3 = ne.Outer.Inner1.Color(in1_clr2)

-- methods
in1_clr1:colorInstanceMethod(1.0)
ne.Outer.Inner1.Color.colorStaticMethod(2.0)

-- Inner2

-- Constructors
in2_clr1 = ne.Outer.Inner2.Color()
in2_clr2 = ne.Outer.Inner2.Color.create()
in2_clr3 = ne.Outer.Inner2.Color(in2_clr2)

assert(pcall(ne.Outer.Inner2.Color, in1_clr1) == false)

-- methods
in2_clr1:colorInstanceMethod(1.0)
ne.Outer.Inner2.Color.colorStaticMethod(2.0)

in2_clr3:colors(in1_clr1, in1_clr2, in2_clr2, in2_clr2, in2_clr3)

assert(pcall(in2_clr3.colors, in2_clr3,
  in2_clr1, in2_clr2, in1_clr2, in2_clr2, in2_clr3) == false)


require("import")	-- the import fn
-- note: need to import the base class module before the derived class
-- this is because if the derived class is imported first it doesn't get the base class methods
import("multi_import_b")	-- import code
import("multi_import_a")	-- import code

x = multi_import_b.XXX()
assert(x:testx() == 0)

y = multi_import_b.YYY()
assert(y:testx() == 0)
assert(y:testy() == 1)

z = multi_import_a.ZZZ()
assert(z:testx() == 0)
assert(z:testz() == 2)


require("import")	-- the import fn
import("cpp_enum")	-- import code
ce=cpp_enum    -- renaming import

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(ce.ENUM_ONE ~= nil)
assert(ce.ENUM_TWO ~= nil)

-- Enums inside classes
assert(ce.Foo.Hi == 0)
assert(ce.Foo.Hello == 1);
-- old-style bindings
assert(ce.Foo_Hi == 0)
assert(ce.Foo_Hello == 1);

assert(ce.Hi == 0)
assert(ce.Hello == 1)


-- import
-- the lua 5.0 loading mechanism is rather poor & relies upon the loadlib() fn
-- the lua 5.1 loading mechanism is simplicity itself
-- for now we need a bridge which will use the correct version

function import_5_0(module)
	-- imports the file into the program
	-- for a module 'example'
	-- this must load 'example.dll' or 'example.so'
	-- and look for the fn 'Example_Init()' (note the capitalisation)
	if rawget(_G,module)~=nil then return end -- module appears to be loaded

	-- capitalising the first letter
	local c=string.upper(string.sub(module,1,1))
	local fnname=c..string.sub(module,2).."_Init"

	local suffix,lib
	-- note: as there seems to be no way in lua to determine the platform
	-- we will try loading all possible names
	-- providing one works, we can load
	for _,suffix in pairs{".dll",".so"} do
		lib=loadlib(module..suffix,fnname)
		if lib then -- found
			break
		end
	end
	assert(lib,"error loading module:"..module)

	lib() -- execute the function: initialising the lib
	local m=rawget(_G,module)	-- gets the module object
	assert(m~=nil,"no module table found")
end

function import_5_1(module)
	require(module)
end

if string.sub(_VERSION,1,7)=='Lua 5.0' then
	import=import_5_0
else
	import=import_5_1
end


runme

-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

print "ok, let's test Lua's ownership of C++ objects"
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")

print "\nLet's make a couple"
a=example.Square(10)
b=example.Circle(1)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 2)")

print "\nNote let's use the createX functions"
c=example.createCircle(5)
d=example.createSquare(3)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")

print "\nWe will run the garbage collector & see if they are till here"
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")

print "\nLet's get rid of them all, collect garbage & see if they are till here"
a,b,c,d=nil,nil,nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")

print "\nLet's start putting stuff into the ShapeOwner"
print "The ShapeOwner now owns the shapes, but Lua still has pointers to them"
o=example.ShapeOwner()
a=example.Square(10)
b=example.Circle(1)
o:add(a)
o:add(b)
o:add(example.createSquare(5))
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nWe will nil our references,run the garbage collector & see if they are still here"
print "they should be, as the ShapeOwner owns them"
a,b=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nWe will access them and check that they are still valid"
a=o:get(0)
b=o:get(1)
print(" Area's are",a:area(),b:area(),o:get(2):area())
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nWe will remove one from the C++ owner & pass its ownership to Lua,"
print " then check that they are still unchanged"
a,b=nil,nil
a=o:remove(0) -- a now owns it
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nDelete the ShapeOwner (this should destroy two shapes),"
print " but we have one left in Lua"
o=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 1)")

print "\nFinal tidy up "
a=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")

print "Final test, we will create some Shapes & pass them around like mad"
print "If there is any memory leak, you will see it in the memory usage"
io.flush()
sh={}
-- make some objects
for i=0,10 do
    a=example.Circle(i)
    b=example.Square(i)
    sh[a]=true
    sh[b]=true
end
o=example.ShapeOwner()
for i=0,10000 do
    for k,_ in pairs(sh) do
        o:add(k)
    end
    sh={}   -- clear it
    while true do
        a=o:remove(0)
        if a==nil then break end
        sh[a]=true
    end
    if i%100==0 then collectgarbage() end
end
print "done"
o,sh=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "that's all folks!"


-- file: example.lua

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

print("ICONST  = "..example.ICONST.." (should be 42)")
print("FCONST  = "..example.FCONST.." (should be 2.1828)")
print("CCONST  = "..example.CCONST.." (should be 'x')")
print("CCONST2 = "..example.CCONST2.." (this should be on a new line)")
print("SCONST  = "..example.SCONST.." (should be 'Hello World')")
print("SCONST2 = "..example.SCONST2.." (should be '\"Hello World\"')")
print("EXPR    = "..example.EXPR.." (should be 48.5484)")
print("iconst  = "..example.iconst.." (should be 37)")
print("fconst  = "..example.fconst.." (should be 3.14)")

-- helper to check that a fn failed
function checkfail(fn)
	if pcall(fn)==true then
		print("that shouldn't happen, it worked")
	else
		print("function failed as expected")
	end
end

-- these should fail
-- example.EXTERN is a nil value, so concatenation will make it fail
checkfail(function() print("EXTERN = "..example.EXTERN) end)
checkfail(function() print("FOO = "..example.FOO) end)


-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

a = example.intSum(0)
b = example.doubleSum(100.0)

-- Use the objects.  They should be callable just like a normal
-- lua function.

for i=0,100 do
    a(i)                -- Note: function call
    b(math.sqrt(i))     -- Note: function call
end
print("int sum 0..100 is",a:result(),"(expected 5050)")
print("double sum 0..100 is",b:result(),"(expected ~771.46)")


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- a helper to print a Lua table
function print_table(t)
    print(table.concat(t,","))
end

-- a helper to print a C array
function print_array(arr,len)
    for i=0,len-1 do
        io.write(example.int_getitem(arr,i),",")
    end
    io.write("\n")
end

math.randomseed(0)  -- init random

--[[ version 1: passing a C array to the code
let's test call sort_int()
this requires a C array, so is the hardest to use]]
ARRAY_SIZE=10
arr=example.new_int(ARRAY_SIZE)
for i=0,ARRAY_SIZE-1 do
    example.int_setitem(arr,i,math.random(1000))
end
print "unsorted"
print_array(arr,ARRAY_SIZE)
example.sort_int(arr,ARRAY_SIZE)
print "sorted"
print_array(arr,ARRAY_SIZE)
example.delete_int(arr) -- must delete it
print ""

--[[ version 2: using %luacode to write a helper
a simpler way is to use a %luacode
which is a lua function added into the module
this can do the conversion for us
so we can just add a lua table directly
(what we do is move the lua code into the module instead)
]]
t={}
for i=1,ARRAY_SIZE do
    t[i]=math.random(1000)
end
print "unsorted"
print_table(t)
example.sort_int2(t) -- calls lua helper which then calls C
print "sorted"
print_table(t)
print ""

--[[ version 3: use a typemap
this is the best way
it uses the SWIG-Lua typemaps to do the work
one item of note: the typemap creates a copy, rather than edit-in-place]]
t={}
for i=1,ARRAY_SIZE do
    t[i]=math.random(1000)/10
end
print "unsorted"
print_table(t)
t=example.sort_double(t) -- replace t with the result
print "sorted"
print_table(t)


-- file: runme.lua

-- This file illustrates class C++ interface generated
-- by SWIG.

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

----- Object creation -----

print("Creating some objects:")
c = example.Circle(10)
print("    Created circle", c)
s = example.Square(10)
print("    Created square", s)

----- Access a static member -----

print("\nA total of",example.Shape_nshapes,"shapes were created")

----- Member data access -----

-- Set the location of the object

c.x = 20
c.y = 30

s.x = -10
s.y = 5

print("\nHere is their current position:")
print(string.format("    Circle = (%f, %f)",c.x,c.y))
print(string.format("    Square = (%f, %f)",s.x,s.y))

----- Call some methods -----

print("\nHere are some properties of the shapes:")
for _,o in pairs({c,s}) do
      print("   ", o)
      print("        area      = ", o:area())
      print("        perimeter = ", o:perimeter())
end

print("\nGuess I'll clean up now")

-- Note: this invokes the virtual destructor
c=nil
s=nil

-- call gc to make sure they are collected
collectgarbage()

print(example.Shape_nshapes,"shapes remain")
print "Goodbye"


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- Call our gcd() function
x = 42
y = 105
g = example.gcd(x,y)
print("The gcd of",x,"and",y,"is",g)

-- Manipulate the Foo global variable

-- Output its current value
print("Foo = ", example.Foo)

-- Change its value
example.Foo = 3.1415926

-- See if the change took effect
print("Foo = ", example.Foo)


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- Try to set the values of some global variables

example.ivar   =  42
example.svar   = -31000
example.lvar   =  65537
example.uivar  =  123456
example.usvar  =  61000
example.ulvar  =  654321
example.scvar  =  -13
example.ucvar  =  251
example.cvar   =  "S"
example.fvar   =  3.14159
example.dvar   =  2.1828
example.strvar =  "Hello World"
example.iptrvar= example.new_int(37)
example.ptptr  = example.new_Point(37,42)
example.name   = "Bill"

-- Now print out the values of the variables

print("Variables (values printed from Lua)")

print("ivar      =", example.ivar)
print("svar      =", example.svar)
print("lvar      =", example.lvar)
print("uivar     =", example.uivar)
print("usvar     =", example.usvar)
print("ulvar     =", example.ulvar)
print("scvar     =", example.scvar)
print("ucvar     =", example.ucvar)
print("fvar      =", example.fvar)
print("dvar      =", example.dvar)
print("cvar      =", example.cvar)
print("strvar    =", example.strvar)
print("cstrvar   =", example.cstrvar)
print("iptrvar   =", example.iptrvar)
print("name      =", example.name)
print("ptptr     =", example.ptptr, example.Point_print(example.ptptr))
print("pt        =", example.pt, example.Point_print(example.pt))

print("\nVariables (values printed from C)")

example.print_vars()

print "\nNow I'm going to try and modify some read only variables";

print "     Trying to set 'path' to 'Whoa!'";
if pcall(function() example.path = "Whoa!" end)==true then
	print "     That's funny, it didn't give an error!"
else
	print "     It gave an error, as it should"
end
print("     Just checking the value: path      =", example.path)

print "     Trying to set 'status' to '0'";
if pcall(function() example.status = 0 end)==true then
	print "     That's funny, it didn't give an error!"
else
	print "     It gave an error, as it should"
end
print("     Just checking the value: status    =", example.status)

print "\nI'm going to try and update a structure variable.\n"

example.pt = example.ptptr

print "The new value is"
example.pt_print()
print("You should see the value", example.Point_print(example.ptptr))


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

a = 37
b = 42

-- Now call our C function

print("Trying some C functions")
print("    a        =", a)
print("    b        =", b)
print("    add(a,b) =", example.add(a,b))
print("    sub(a,b) =", example.sub(a,b))
print("    mul(a,b) =", example.mul(a,b))

print("Calling them using the my_func()")
print("    add(a,b) =", example.callback(a,b,example.add))
print("    sub(a,b) =", example.callback(a,b,example.sub))
print("    mul(a,b) =", example.callback(a,b,example.mul))

print("Now let us write our own function")
function foo(a,b) return 101 end
print("    foo(a,b) =", example.callback(a,b,foo))

print("Now let us try something that will fail")
local ok,c=pcall(example.callback,a,b,print)
if ok==false then
	print("this failed as expected, error:",c)
else
	print("oops, that worked! result:",c)
end

-- part2 stored function
print("trying a stored fn")
print("the_func=",example.the_func)
print("setting to print")
example.the_func=print
print("the_func=",example.the_func)
print("call_the_func(5)")
example.call_the_func(5)

function bar(i) print("bar",i) end
print("setting to bar")
example.the_func=bar
print("call_the_func(5)")
example.call_the_func(5)


-- file: runme.lua

-- This file illustrates class C++ interface generated
-- by SWIG.

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

ex = example

-- Calling a module function ( aka global function )
assert( ex.module_function() == 7 )
print("example.module_function(): ", ex.module_function())

-- Accessing a module (aka global) variable
assert( ex.module_variable == 9 )
print("example.module_variable: ", ex.module_variable)

-- Creating an instance of the class
w1 = ex.MyWorld.World()
print("Creating class instance: w1 = ex.MyWorld.World(): ", w1)

-- Accessing class members
assert( ex.MyWorld.World():create_world() == 17 )
print( "w1:create_world() = ", w1:create_world() )
assert( w1:create_world() == 17 )
print( "w1:world_max_count = ", w1.world_max_count )
assert( w1.world_max_count == 9 )

-- Accessing enums from class within namespace
print( "Accessing enums: ex.MyWorld.Nested.Dweller.MALE = ", ex.MyWorld.Nested.Dweller.MALE )
assert( ex.MyWorld.Nested.Dweller.MALE == 0 )
print( "Accessing enums: ex.MyWorld.Nested.Dweller.FEMALE = ", ex.MyWorld.Nested.Dweller.FEMALE )
assert( ex.MyWorld.Nested.Dweller.FEMALE == 1 )

-- Accessing static member function
print( "Accessing static member function: ex.MyWorld.Nested.Dweller.count() = ", ex.MyWorld.Nested.Dweller.count() )
assert( ex.MyWorld.Nested.Dweller.count() == 19 )


print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module")

-- a test function to run the tests
function do_tests()
	print("[lua] We are now in Lua, inside the do_tests() function")
	print("[lua] We will be calling example.gcd() and changing example.Foo")
	-- Call our gcd() function
	x = 42
	y = 105
	g = example.gcd(x,y)
	print("[lua] The gcd of",x,"and",y,"is",g)

	-- Manipulate the Foo global variable

	-- Output its current value
	print("[lua] Foo = ", example.Foo)

	-- Change its value
	example.Foo = 3.1415926

	-- See if the change took effect
	print("[lua] Foo = ", example.Foo)
	print("[lua] ending the do_tests() function")
end

function call_greeting()
	print("[lua] We are now in Lua, inside the call_greeting() function")
	example.greeting()
	print("[lua] ending the call_greeting() function")
end


print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway

assert(type(example)=='table',"Don't appear to have loaded the example module. Do not run this file directly, run the embed3 executable")

print "[lua] looking to see if we have a pointer to the engine"
if type(pEngine)=="userdata" then
    print "[lua] looks good"
else
    print "[lua] nope, no signs of it"
end

-- the embedded program expects a function void onEvent(Event)
-- this is it

function onEvent(e)
    print("[Lua] onEvent with event",e.mType)
    -- let's do something with the Engine
    -- nothing clever, but ...
    if e.mType==example.Event_STARTUP then
        pEngine:start()
    elseif e.mType==example.Event_KEYPRESS then
        pEngine:accelerate(0.4)
    elseif e.mType==example.Event_MOUSEPRESS then
        pEngine:decelerate(0.4)
    elseif e.mType==example.Event_SHUTDOWN then
        pEngine:stop()
    else
        error("unknown event type")
    end
    print("[Lua] ending onEvent")
end


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

x,y = 42,105
print("add1 - simple arg passing and single return value -- ")
print(example.add1(x,y))
print("add2 - pointer arg passing and single return value through pointer arg -- ")
print(example.add2(x,y))
print("add3 - simple arg passing and double return value through return and ptr arg -- ")
print(example.add3(x,y))
print("add4 - dual use arg and return value -- ")
print(example.add4(x,y))


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end
-- First create some objects using the pointer library.
print("Testing the pointer library")
a = example.new_intp()
b = example.new_intp()
c = example.new_intp()
example.intp_assign(a,37)
example.intp_assign(b,42)
print("     a = "..tostring(a))
print("     b = "..tostring(b))
-- Now try the typemap library
-- This should be much easier. Now how it is no longer
-- necessary to manufacture pointers.
print("Trying the typemap library")
r = example.sub(37,42)
print("     37 - 42 = "..r)
-- Now try the version with multiple return values
print("Testing multiple return values")
q,r = example.divide(42,37)
print("     42/37 = "..q.." remainder "..r)


print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module")

-- note: we will copy the functions from example table into global
-- this will help us later
for k,v in pairs(example) do _G[k]=v end

-- our add function
-- we will be calling this from C
function add(a,b)
    print("[lua] this is function add(",a,b,")")
    c=a+b
    print("[lua] returning",c)
    return c
end

function append(a,b)
    print("[lua] this is function append(",a,b,")")
    c=a..b
    print("[lua] returning",c)
    return c
end


# Test various properties of classes defined in separate modules

print("Testing the %import directive")

if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	function loadit(a)
		lib=loadlib(a..'.dll','luaopen_'..a) or loadlib(a..'.so','luaopen_'..a)
		assert(lib)()
	end
	loadit('base')
	loadit('foo')
	loadit('bar')
	loadit('spam')
else
	-- lua 5.1 does
	require 'base'
	require 'foo'
	require 'bar'
	require 'spam'
end

-- Create some objects

print("Creating some objects")

a = base.Base()
b = foo.Foo()
c = bar.Bar()
d = spam.Spam()

-- Try calling some methods
print("Testing some methods")
print("Should see 'Base::A' ---> ",a:A())
print("Should see 'Base::B' ---> ",a:B())

print("Should see 'Foo::A' ---> ",b:A())
print("Should see 'Foo::B' ---> ",b:B())

print("Should see 'Bar::A' ---> ",c:A())
print("Should see 'Bar::B' ---> ",c:B())

print("Should see 'Spam::A' ---> ",d:A())
print("Should see 'Spam::B' ---> ",d:B())

-- Try some casts

print("\nTesting some casts")

x = a:toBase()
print("Should see 'Base::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = b:toBase()
print("Should see 'Foo::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = c:toBase()
print("Should see 'Bar::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = d:toBase()
print("Should see 'Spam::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = d:toBar()
print("Should see 'Bar::B' ---> ",x:B())

print "\nTesting some dynamic casts\n"
x = d:toBase()

print " Spam -> Base -> Foo : "
y = foo.Foo_fromBase(x)
if y then
      print "bad swig"
else
      print "good swig"
end

print " Spam -> Base -> Bar : "
y = bar.Bar_fromBase(x)
if y then
      print "good swig"
else
      print "bad swig"
end

print " Spam -> Base -> Spam : "
y = spam.Spam_fromBase(x)
if y then
      print "good swig"
else
      print "bad swig"
end

print " Foo -> Spam : "
y = spam.Spam_fromBase(b)
if y then
      print "bad swig"
else
      print "good swig"
end


-- file: example.lua

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- throw a lot of exceptions:
-- you must catch exceptions using pcall and then checking the result

t = example.Test()

print "calling t:unknown()"
ok,res=pcall(function() t:unknown() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end

print "calling t:simple()"
ok,res=pcall(function() t:simple() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end

print "calling t:message()"
ok,res=pcall(function() t:message() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end

print "calling t:hosed()"
ok,res=pcall(function() t:hosed() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res.code,res.msg)
end

-- this is a rather strange way to perform the multiple catch of exceptions
print "calling t:multi()"
for i=1,3 do
    ok,res=pcall(function() t:multi(i) end)
    if ok then
        print "  that worked! Funny"
    else
        if swig_type(res)=="Exc *" then
            print("  call failed with Exc exception:",res.code,res.msg)
        else
            print("  call failed with error:",res)
        end
    end
end

-- this is a bit crazy, but it shows obtaining of the stacktrace
function a()
    b()
end
function b()
    t:message()
end
print [[
Now let's call function a()
 which calls b()
 which calls into C++
 which will throw an exception!]]
ok,res=pcall(a)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end
print "Now let's do the same using xpcall(a,debug.traceback)"
ok,res=xpcall(a,debug.traceback)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end
print "As you can see, the xpcall gives a nice stacktrace to work with"

ok,res=pcall(a)
print(ok,res)
ok,res=xpcall(a,debug.traceback)
print(ok,res)


console

--[[--------------------------------------------------------------------------
    This file is part of lunit 0.5.
    For Details about lunit look at: http://www.mroth.net/lunit/
--]]--------------------------------------------------------------------------
--[[
      begin()
        run(testcasename, testname)
          err(fullname, message, traceback)
          fail(fullname, where, message, usermessage)
          pass(testcasename, testname)
      done()
      Fullname:
        testcase.testname
        testcase.testname:setupname
        testcase.testname:teardownname
--]]
lunit = require "lunit"
local lunit_console
if _VERSION >= 'Lua 5.2' then
    lunit_console = setmetatable({},{__index = _ENV})
    _ENV = lunit_console

else
    module( "lunit-console", package.seeall )
    lunit_console = _M

end
local function printformat(format, ...)
  io.write( string.format(format, ...) )
end
local columns_printed = 0
local function writestatus(char)
  if columns_printed == 0 then
    io.write("    ")
  end
  if columns_printed == 60 then
    io.write("\n    ")
    columns_printed = 0
  end
  io.write(char)
  io.flush()
  columns_printed = columns_printed + 1
end
local msgs = {}
function begin()
  local total_tc = 0
  local total_tests = 0

  msgs = {} -- e
  for tcname in lunit.testcases() do
    total_tc = total_tc + 1
    for testname, test in lunit.tests(tcname) do
      total_tests = total_tests + 1
    end
  end
  printformat("Loaded testsuite with %d tests in %d testcases.\n\n", total_tests, total_tc)
end
function run(testcasename, testname)
  -- NOP
end
function err(fullname, message, traceback)
  writestatus("E")
  msgs[#msgs+1] = "Error! ("..fullname.."):\n"..message.."\n\t"..table.concat(traceback, "\n\t") .. "\n"
end
function fail(fullname, where, message, usermessage)
  writestatus("F")
  local text =  "Failure ("..fullname.."):\n"..
                where..": "..message.."\n"
  if usermessage then
    text = text .. where..": "..usermessage.."\n"
  end
  msgs[#msgs+1] = text
end
function pass(testcasename, testname)
  writestatus(".")
end
function done()
  printformat("\n\n%d Assertions checked.\n", lunit.stats.assertions )
  print()
  for i, msg in ipairs(msgs) do
    printformat( "%3d) %s\n", i, msg )
  end
  printformat("Testsuite finished (%d passed, %d failed, %d errors).\n",
      lunit.stats.passed, lunit.stats.failed, lunit.stats.errors )
end
return lunit_console


lunit

--[[--------------------------------------------------------------------------
    This file is part of lunit 0.5.
    For Details about lunit look at: http://www.mroth.net/lunit/
--]]--------------------------------------------------------------------------
local orig_assert     = assert
local pairs           = pairs
local ipairs          = ipairs
local next            = next
local type            = type
local error           = error
local tostring        = tostring
local setmetatable    = setmetatable
local pcall           = pcall
local xpcall          = xpcall
local require         = require
local loadfile        = loadfile
local string_sub      = string.sub
local string_gsub     = string.gsub
local string_format   = string.format
local string_lower    = string.lower
local string_find     = string.find
local table_concat    = table.concat
local debug_getinfo   = debug.getinfo
local _G = _G
local lunit
if _VERSION >= 'Lua 5.2' then
    lunit = {}
    _ENV = lunit

else
    module("lunit")
    lunit = _M

end
local __failure__ = {}    -- Type tag for failed assertions
local typenames = { "nil", "boolean", "number", "string", "table", "function", "thread", "userdata" }
local traceback_hide      -- Traceback function which hides lunit internals
local mypcall             -- Protected call to a function with own traceback
do
  local _tb_hide = setmetatable( {}, {__mode="k"} )
  function traceback_hide(func)
    _tb_hide[func] = true
  end
  local function my_traceback(errobj)
    if is_table(errobj) and errobj.type == __failure__ then
      local info = debug_getinfo(5, "Sl")   -- FIXME: Hardcoded integers are bad...
      errobj.where = string_format( "%s:%d", info.short_src, info.currentline)
    else
      errobj = { msg = tostring(errobj) }
      errobj.tb = {}
      local i = 2
      while true do
        local info = debug_getinfo(i, "Snlf")
        if not is_table(info) then
          break
        end
        if not _tb_hide[info.func] then
          local line = {}       -- Ripped from ldblib.c...
          line[#line+1] = string_format("%s:", info.short_src)
          if info.currentline > 0 then
            line[#line+1] = string_format("%d:", info.currentline)
          end
          if info.namewhat ~= "" then
            line[#line+1] = string_format(" in function '%s'", info.name)
          else
            if info.what == "main" then
              line[#line+1] = " in main chunk"
            elseif info.what == "C" or info.what == "tail" then
              line[#line+1] = " ?"
            else
              line[#line+1] = string_format(" in function <%s:%d>", info.short_src, info.linedefined)
            end
          end
          errobj.tb[#errobj.tb+1] = table_concat(line)
        end
        i = i + 1
      end
    end
    return errobj
  end
  function mypcall(func)
    orig_assert( is_function(func) )
    local ok, errobj = xpcall(func, my_traceback)
    if not ok then
      return errobj
    end
  end
  traceback_hide(mypcall)
end
-- Type check functions
for _, typename in ipairs(typenames) do
  lunit["is_"..typename] = function(x)
    return type(x) == typename
  end
end
local is_nil      = is_nil
local is_boolean  = is_boolean
local is_number   = is_number
local is_string   = is_string
local is_table    = is_table
local is_function = is_function
local is_thread   = is_thread
local is_userdata = is_userdata
local function failure(name, usermsg, defaultmsg, ...)
  local errobj = {
    type    = __failure__,
    name    = name,
    msg     = string_format(defaultmsg,...),
    usermsg = usermsg
  }
  error(errobj, 0)
end
traceback_hide( failure )
local function format_arg(arg)
  local argtype = type(arg)
  if argtype == "string" then
    return "'"..arg.."'"
  elseif argtype == "number" or argtype == "boolean" or argtype == "nil" then
    return tostring(arg)
  else
    return "["..tostring(arg).."]"
  end
end
local function selected(map, name)
    if not map then
        return true
    end
    local m = {}
    for k,v in pairs(map) do
        m[k] = lunitpat2luapat(v)
    end
    return in_patternmap(m, name)
end
function fail(msg)
  stats.assertions = stats.assertions + 1
  failure( "fail", msg, "failure" )
end
traceback_hide( fail )
function assert(assertion, msg)
  stats.assertions = stats.assertions + 1
  if not assertion then
    failure( "assert", msg, "assertion failed" )
  end
  return assertion
end
traceback_hide( assert )
function assert_true(actual, msg)
  stats.assertions = stats.assertions + 1
  if actual ~= true then
    failure( "assert_true", msg, "true expected but was %s", format_arg(actual) )
  end
  return actual
end
traceback_hide( assert_true )
function assert_false(actual, msg)
  stats.assertions = stats.assertions + 1
  if actual ~= false then
    failure( "assert_false", msg, "false expected but was %s", format_arg(actual) )
  end
  return actual
end
traceback_hide( assert_false )
function assert_equal(expected, actual, msg)
  stats.assertions = stats.assertions + 1
  if expected ~= actual then
    failure( "assert_equal", msg, "expected %s but was %s", format_arg(expected), format_arg(actual) )
  end
  return actual
end
traceback_hide( assert_equal )
function assert_not_equal(unexpected, actual, msg)
  stats.assertions = stats.assertions + 1
  if unexpected == actual then
    failure( "assert_not_equal", msg, "%s not expected but was one", format_arg(unexpected) )
  end
  return actual
end
traceback_hide( assert_not_equal )
function assert_match(pattern, actual, msg)
  stats.assertions = stats.assertions + 1
  if type(pattern) ~= "string" then
    failure( "assert_match", msg, "expected a string as pattern but was %s", format_arg(pattern) )
  end
  if type(actual) ~= "string" then
    failure( "assert_match", msg, "expected a string to match pattern '%s' but was a %s", pattern, format_arg(actual) )
  end
  if not string_find(actual, pattern) then
    failure( "assert_match", msg, "expected '%s' to match pattern '%s' but doesn't", actual, pattern )
  end
  return actual
end
traceback_hide( assert_match )
function assert_not_match(pattern, actual, msg)
  stats.assertions = stats.assertions + 1
  if type(pattern) ~= "string" then
    failure( "assert_not_match", msg, "expected a string as pattern but was %s", format_arg(pattern) )
  end
  if type(actual) ~= "string" then
    failure( "assert_not_match", msg, "expected a string to not match pattern '%s' but was %s", pattern, format_arg(actual) )
  end
  if string_find(actual, pattern) then
    failure( "assert_not_match", msg, "expected '%s' to not match pattern '%s' but it does", actual, pattern )
  end
  return actual
end
traceback_hide( assert_not_match )
function assert_error(msg, func)
  stats.assertions = stats.assertions + 1
  if func == nil then
    func, msg = msg, nil
  end
  if type(func) ~= "function" then
    failure( "assert_error", msg, "expected a function as last argument but was %s", format_arg(func) )
  end
  local ok, errmsg = pcall(func)
  if ok then
    failure( "assert_error", msg, "error expected but no error occurred" )
  end
end
traceback_hide( assert_error )
function assert_error_match(msg, pattern, func)
  stats.assertions = stats.assertions + 1
  if func == nil then
    msg, pattern, func = nil, msg, pattern
  end
  if type(pattern) ~= "string" then
    failure( "assert_error_match", msg, "expected the pattern as a string but was %s", format_arg(pattern) )
  end
  if type(func) ~= "function" then
    failure( "assert_error_match", msg, "expected a function as last argument but was %s", format_arg(func) )
  end
  local ok, errmsg = pcall(func)
  if ok then
    failure( "assert_error_match", msg, "error expected but no error occurred" )
  end
  if type(errmsg) ~= "string" then
    failure( "assert_error_match", msg, "error as string expected but was %s", format_arg(errmsg) )
  end
  if not string_find(errmsg, pattern) then
    failure( "assert_error_match", msg, "expected error '%s' to match pattern '%s' but doesn't", errmsg, pattern )
  end
end
traceback_hide( assert_error_match )
function assert_pass(msg, func)
  stats.assertions = stats.assertions + 1
  if func == nil then
    func, msg = msg, nil
  end
  if type(func) ~= "function" then
    failure( "assert_pass", msg, "expected a function as last argument but was %s", format_arg(func) )
  end
  local ok, errmsg = pcall(func)
  if not ok then
    failure( "assert_pass", msg, "no error expected but error was: '%s'", errmsg )
  end
end
traceback_hide( assert_pass )
-- lunit.assert_typename functions
for _, typename in ipairs(typenames) do
  local assert_typename = "assert_"..typename
  lunit[assert_typename] = function(actual, msg)
    stats.assertions = stats.assertions + 1
    if type(actual) ~= typename then
      failure( assert_typename, msg, "%s expected but was %s", typename, format_arg(actual) )
    end
    return actual
  end
  traceback_hide( lunit[assert_typename] )
end
-- lunit.assert_not_typename functions
for _, typename in ipairs(typenames) do
  local assert_not_typename = "assert_not_"..typename
  lunit[assert_not_typename] = function(actual, msg)
    stats.assertions = stats.assertions + 1
    if type(actual) == typename then
      failure( assert_not_typename, msg, typename.." not expected but was one" )
    end
  end
  traceback_hide( lunit[assert_not_typename] )
end
function lunit.clearstats()
  stats = {
    assertions  = 0;
    passed      = 0;
    failed      = 0;
    errors      = 0;
  }
end
local report, reporterrobj
do
  local testrunner
  function lunit.setrunner(newrunner)
    if not ( is_table(newrunner) or is_nil(newrunner) ) then
      return error("lunit.setrunner: Invalid argument", 0)
    end
    local oldrunner = testrunner
    testrunner = newrunner
    return oldrunner
  end
  function lunit.loadrunner(name)
    if not is_string(name) then
      return error("lunit.loadrunner: Invalid argument", 0)
    end
    local ok, runner = pcall( require, name )
    if not ok then
      return error("lunit.loadrunner: Can't load test runner: "..runner, 0)
    end
    return setrunner(runner)
  end
  function lunit.getrunner()
    return testrunner
  end
  function report(event, ...)
    local f = testrunner and testrunner[event]
    if is_function(f) then
      pcall(f, ...)
    end
  end
  function reporterrobj(context, tcname, testname, errobj)
    local fullname = tcname .. "." .. testname
    if context == "setup" then
      fullname = fullname .. ":" .. setupname(tcname, testname)
    elseif context == "teardown" then
      fullname = fullname .. ":" .. teardownname(tcname, testname)
    end
    if errobj.type == __failure__ then
      stats.failed = stats.failed + 1
      report("fail", fullname, errobj.where, errobj.msg, errobj.usermsg)
    else
      stats.errors = stats.errors + 1
      report("err", fullname, errobj.msg, errobj.tb)
    end
  end
end
local function key_iter(t, k)
    return (next(t,k))
end
local testcase
do
  -- Array with all registered testcases
  local _testcases = {}
  -- Marks a module as a testcase.
  -- Applied over a module from module("xyz", lunit.testcase).
  function lunit.testcase(m)
    orig_assert( is_table(m) )
    --orig_assert( m._M == m )
    orig_assert( is_string(m._NAME) )
    --orig_assert( is_string(m._PACKAGE) )
    -- Register the module as a testcase
    _testcases[m._NAME] = m
    -- Import lunit, fail, assert* and is_* function to the module/testcase
    m.lunit = lunit
    m.fail = lunit.fail
    for funcname, func in pairs(lunit) do
      if "assert" == string_sub(funcname, 1, 6) or "is_" == string_sub(funcname, 1, 3) then
        m[funcname] = func
      end
    end
  end

  function lunit.module(name,seeall)
    local m = {}
    if seeall == "seeall" then
      setmetatable(m, { __index = _G })
    end
    m._NAME = name
    lunit.testcase(m)
    return m
  end
  -- Iterator (testcasename) over all Testcases
  function lunit.testcases()
    -- Make a copy of testcases to prevent confusing the iterator when
    -- new testcase are defined
    local _testcases2 = {}
    for k,v in pairs(_testcases) do
        _testcases2[k] = true
    end
    return key_iter, _testcases2, nil
  end
  function testcase(tcname)
    return _testcases[tcname]
  end
end
do
  -- Finds a function in a testcase case insensitive
  local function findfuncname(tcname, name)
    for key, value in pairs(testcase(tcname)) do
      if is_string(key) and is_function(value) and string_lower(key) == name then
        return key
      end
    end
  end
  function lunit.setupname(tcname)
    return findfuncname(tcname, "setup")
  end
  function lunit.teardownname(tcname)
    return findfuncname(tcname, "teardown")
  end
  -- Iterator over all test names in a testcase.
  -- Have to collect the names first in case one of the test
  -- functions creates a new global and throws off the iteration.
  function lunit.tests(tcname)
    local testnames = {}
    for key, value in pairs(testcase(tcname)) do
      if is_string(key) and is_function(value) then
        local lfn = string_lower(key)
        if string_sub(lfn, 1, 4) == "test" or string_sub(lfn, -4) == "test" then
          testnames[key] = true
        end
      end
    end
    return key_iter, testnames, nil
  end
end
function lunit.runtest(tcname, testname)
  orig_assert( is_string(tcname) )
  orig_assert( is_string(testname) )
  if (not getrunner()) then
    loadrunner("console")
  end
  local function callit(context, func)
    if func then
      local err = mypcall(func)
      if err then
        reporterrobj(context, tcname, testname, err)
        return false
      end
    end
    return true
  end
  traceback_hide(callit)
  report("run", tcname, testname)
  local tc          = testcase(tcname)
  local setup       = tc[setupname(tcname)]
  local test        = tc[testname]
  local teardown    = tc[teardownname(tcname)]
  local setup_ok    =              callit( "setup", setup )
  local test_ok     = setup_ok and callit( "test", test )
  local teardown_ok = setup_ok and callit( "teardown", teardown )
  if setup_ok and test_ok and teardown_ok then
    stats.passed = stats.passed + 1
    report("pass", tcname, testname)
  end
end
traceback_hide(runtest)
function lunit.run(testpatterns)
  clearstats()
  report("begin")
  for testcasename in lunit.testcases() do
    -- Run tests in the testcases
    for testname in lunit.tests(testcasename) do
      if selected(testpatterns, testname) then
        runtest(testcasename, testname)
      end
    end
  end
  report("done")
  return stats
end
traceback_hide(run)
function lunit.loadonly()
  clearstats()
  report("begin")
  report("done")
  return stats
end
local lunitpat2luapat
do
  local conv = {
    ["^"] = "%^",
    ["$"] = "%$",
    ["("] = "%(",
    [")"] = "%)",
    ["%"] = "%%",
    ["."] = "%.",
    ["["] = "%[",
    ["]"] = "%]",
    ["+"] = "%+",
    ["-"] = "%-",
    ["?"] = ".",
    ["*"] = ".*"
  }
  function lunitpat2luapat(str)
    --return "^" .. string.gsub(str, "%W", conv) .. "$"
    -- Above was very annoying, if I want to run all the tests having to do with
    -- RSS, I want to be able to do "-t rss"   not "-t \*rss\*".
    return string_gsub(str, "%W", conv)
  end
end
local function in_patternmap(map, name)
  if map[name] == true then
    return true
  else
    for _, pat in ipairs(map) do
      if string_find(name, pat) then
        return true
      end
    end
  end
  return false
end
-- Called from 'lunit' shell script.
function main(argv)
  argv = argv or {}
  -- FIXME: Error handling and error messages aren't nice.
  local function checkarg(optname, arg)
    if not is_string(arg) then
      return error("lunit.main: option "..optname..": argument missing.", 0)
    end
  end
  local function loadtestcase(filename)
    if not is_string(filename) then
      return error("lunit.main: invalid argument")
    end
    local chunk, err = loadfile(filename)
    if err then
      return error(err)
    else
      chunk()
    end
  end
  local testpatterns = nil
  local doloadonly = false
  local i = 0
  while i < #argv do
    i = i + 1
    local arg = argv[i]
    if arg == "--loadonly" then
      doloadonly = true
    elseif arg == "--runner" or arg == "-r" then
      local optname = arg; i = i + 1; arg = argv[i]
      checkarg(optname, arg)
      loadrunner(arg)
    elseif arg == "--test" or arg == "-t" then
      local optname = arg; i = i + 1; arg = argv[i]
      checkarg(optname, arg)
      testpatterns = testpatterns or {}
      testpatterns[#testpatterns+1] = arg
    elseif arg == "--help" or arg == "-h" then
        print[[
lunit 0.5
]]
        return
    elseif arg == "--" then
      while i < #argv do
        i = i + 1; arg = argv[i]
        loadtestcase(arg)
      end
    else
      loadtestcase(arg)
    end
  end
  if doloadonly then
    return loadonly()
  else
    return run(testpatterns)
  end
end
clearstats()
return lunit