1-- $Id: testes/vararg.lua $
  2-- See Copyright Notice in file all.lua
  3
  4print('testing vararg')
  5
  6local function f (a, ...)
  7  local x = {n = select('#', ...), ...}
  8  for i = 1, x.n do assert(a[i] == x[i]) end
  9  return x.n
 10end
 11
 12local function c12 (...)
 13  assert(arg == _G.arg)    -- no local 'arg'
 14  local x = {...}; x.n = #x
 15  local res = (x.n==2 and x[1] == 1 and x[2] == 2)
 16  if res then res = 55 end
 17  return res, 2
 18end
 19
 20local function vararg (...) return {n = select('#', ...), ...} end
 21
 22local call = function (f, args) return f(table.unpack(args, 1, args.n)) end
 23
 24assert(f() == 0)
 25assert(f({1,2,3}, 1, 2, 3) == 3)
 26assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5)
 27
 28assert(vararg().n == 0)
 29assert(vararg(nil, nil).n == 2)
 30
 31assert(c12(1,2)==55)
 32local a,b = assert(call(c12, {1,2}))
 33assert(a == 55 and b == 2)
 34a = call(c12, {1,2;n=2})
 35assert(a == 55 and b == 2)
 36a = call(c12, {1,2;n=1})
 37assert(not a)
 38assert(c12(1,2,3) == false)
 39local a = vararg(call(next, {_G,nil;n=2}))
 40local b,c = next(_G)
 41assert(a[1] == b and a[2] == c and a.n == 2)
 42a = vararg(call(call, {c12, {1,2}}))
 43assert(a.n == 2 and a[1] == 55 and a[2] == 2)
 44a = call(print, {'+'})
 45assert(a == nil)
 46
 47local t = {1, 10}
 48function t:f (...) local arg = {...}; return self[...]+#arg end
 49assert(t:f(1,4) == 3 and t:f(2) == 11)
 50print('+')
 51
 52local lim = 20
 53local i, a = 1, {}
 54while i <= lim do a[i] = i+0.3; i=i+1 end
 55
 56function f(a, b, c, d, ...)
 57  local more = {...}
 58  assert(a == 1.3 and more[1] == 5.3 and
 59         more[lim-4] == lim+0.3 and not more[lim-3])
 60end
 61
 62local function g (a,b,c)
 63  assert(a == 1.3 and b == 2.3 and c == 3.3)
 64end
 65
 66call(f, a)
 67call(g, a)
 68
 69a = {}
 70i = 1
 71while i <= lim do a[i] = i; i=i+1 end
 72assert(call(math.max, a) == lim)
 73
 74print("+")
 75
 76
 77-- new-style varargs
 78
 79local function oneless (a, ...) return ... end
 80
 81function f (n, a, ...)
 82  local b
 83  assert(arg == _G.arg)   -- no local 'arg'
 84  if n == 0 then
 85    local b, c, d = ...
 86    return a, b, c, d, oneless(oneless(oneless(...)))
 87  else
 88    n, b, a = n-1, ..., a
 89    assert(b == ...)
 90    return f(n, a, ...)
 91  end
 92end
 93
 94a,b,c,d,e = assert(f(10,5,4,3,2,1))
 95assert(a==5 and b==4 and c==3 and d==2 and e==1)
 96
 97a,b,c,d,e = f(4)
 98assert(a==nil and b==nil and c==nil and d==nil and e==nil)
 99
100
101-- varargs for main chunks
102local f = load[[ return {...} ]]
103local x = f(2,3)
104assert(x[1] == 2 and x[2] == 3 and x[3] == undef)
105
106
107f = load[[
108  local x = {...}
109  for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end
110  assert(x[select('#', ...)+1] == undef)
111  return true
112]]
113
114assert(f("a", "b", nil, {}, assert))
115assert(f())
116
117a = {select(3, table.unpack{10,20,30,40})}
118assert(#a == 2 and a[1] == 30 and a[2] == 40)
119a = {select(1)}
120assert(next(a) == nil)
121a = {select(-1, 3, 5, 7)}
122assert(a[1] == 7 and a[2] == undef)
123a = {select(-2, 3, 5, 7)}
124assert(a[1] == 5 and a[2] == 7 and a[3] == undef)
125pcall(select, 10000)
126pcall(select, -10000)
127
128
129-- bug in 5.2.2
130
131function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
132p11, p12, p13, p14, p15, p16, p17, p18, p19, p20,
133p21, p22, p23, p24, p25, p26, p27, p28, p29, p30,
134p31, p32, p33, p34, p35, p36, p37, p38, p39, p40,
135p41, p42, p43, p44, p45, p46, p48, p49, p50, ...)
136  local a1,a2,a3,a4,a5,a6,a7
137  local a8,a9,a10,a11,a12,a13,a14
138end
139
140-- assertion fail here
141f()
142
143-- missing arguments in tail call
144do
145  local function f(a,b,c) return c, b end
146  local function g() return f(1,2) end
147  local a, b = g()
148  assert(a == nil and b == 2)
149end
150print('OK')
151