Mercurial > pub > dyncall > dyncall
diff test/common/mk-cases.lua @ 521:a2de1d0a73f3
- more test code generator code sharing/abstraction/simplifications
author | Tassilo Philipp |
---|---|
date | Wed, 13 Apr 2022 10:06:40 +0200 |
parents | 99819b874bac |
children | f7fec6699e21 |
line wrap: on
line diff
--- a/test/common/mk-cases.lua Mon Apr 11 22:49:04 2022 +0200 +++ b/test/common/mk-cases.lua Wed Apr 13 10:06:40 2022 +0200 @@ -2,6 +2,7 @@ return s:gsub("^%s+",""):gsub("%s+$","") end + -- parse array notation, e.g. returns "a", 4 for "a[4]" function split_array_decl(s) local name = s @@ -14,6 +15,118 @@ return name, n end + +-- returns sig with return type first, and no ')' separator, e.g.: +-- 'ijf)v' -> 'vijf' +-- '){ii}' -> '{ii}' +function put_sig_rtype_first(sig) + return sig:sub(sig:find(')')+1,-1)..sig:sub(1,sig:find(')')-1) +end + + +-- aggrs: (sequential) idx => aggr-sig +-- seen_aggrs: aggr-sig => {{type0, name0, ...}, aggr_name} +-- packing: 0=off, pos values set fixed packing, neg values set a random +-- power-of-2 packing per aggregate, within [1,abs(aggrpacking)] +-- packing_seed: seed for random packing (if used) +function mkaggrdefs(aggrs, seen_aggrs, packing, packingseed) + local agg_defs = { } + local agg_sizes = { } + local agg_sigs = { } + local agg_names = { } + + math.randomseed(packingseed) + + for a = 1, #aggrs do + local k = aggrs[a] + local v = seen_aggrs[k] + local am = v[1] -- aggregate members + local at = v[2] -- aggregate type + local an = at:match('A.*') -- aggregate name (w/o struct or union) + + -- aggregate def + aggr_def = '/* '..k..' */\n' + if packing ~= 0 then + local pack = packing + if pack < 0 then + pack = math.floor(math.pow(2,math.floor(math.log(math.random(math.abs(pack)),2)))) + end + aggr_def = aggr_def..'#pragma pack(push,'..pack..')\n' + end + + aggr_def = aggr_def..at..' { ' + for i = 1, #am, 2 do + aggr_def = aggr_def..am[i]..' '..am[i+1]..'; ' + end + aggr_def = aggr_def..'};\n' + + if packing ~= 0 then + aggr_def = aggr_def..'#pragma pack(pop)\n' + end + + -- aggregate cp and cmp funcs + s = { + 'void f_cp'..an..'('..at..' *x, const '..at..' *y) { ', + 'int f_cmp'..an..'(const '..at..' *x, const '..at..' *y) { return ' + } + o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' } + for t = 1, 2 do + if t ~= 1 or aggrcpsimple == false then + aggr_def = aggr_def..s[t] + local b = {} + for i = 1, #am, 2 do + local mn, mc = split_array_decl(am[i+1]) -- aggr member name and (array) count + local fmt = '' + if mc ~= nil then -- need array suffixes? + fmt = '[%d]' + else + mc = 1 + end + + for j = 1, mc do + name = mn..fmt:format(j-1) + amn = am[i]:match('A.*') + if amn then -- is aggr? + b[#b+1] = o[t+2]..amn..'(&x->'..name..', &y->'..name..')' + else + b[#b+1] = 'x->'..name..' '..o[t]..' y->'..name + end + end + end + if #b == 0 then -- to handle empty aggregates + b[1] = o[t+6] + end + aggr_def = aggr_def..table.concat(b,o[t+4])..'; };\n' + end + end + + -- write convenient dcNewAggr() helper/wrapper funcs + aggr_def = aggr_def..'DCaggr* f_touch'..an..'() {\n\tstatic DCaggr* a = NULL;\n\tif(!a) {\n\t\ta = dcNewAggr('..(#am>>1)..', sizeof('..at..'));\n\t\t' + for i = 1, #am, 2 do + local mn, mc = split_array_decl(am[i+1]) + if mc == nil then + mc = 1 + end + amn = am[i]:match('A.*') + if amn then -- is aggr? + --aggr_def = aggr_def..'dcAggrField(at, DC_SIGCHAR_AGGREGATE, offsetof('..at..', '..mn..'), '..mc..', f_touch'..amn..'());\n\t\t' + aggr_def = aggr_def.."AFa("..at..','..mn..','..mc..','..amn..')\n\t\t' + else + --aggr_def = aggr_def.."dcAggrField(at, '"..am[i].."', offsetof("..at..', '..mn..'), '..mc..');\n\t\t' + aggr_def = aggr_def.."AF('"..am[i].."',"..at..','..mn..','..mc..')\n\t\t' + end + end + + agg_defs [#agg_defs + 1] = aggr_def..'dcCloseAggr(a);\n\t}\n\treturn a;\n};' + agg_sizes[#agg_sizes + 1] = 'sizeof('..at..')' + agg_sigs [#agg_sigs + 1] = k + agg_names[#agg_names + 1] = an + end + + return agg_defs, agg_sizes, agg_sigs, agg_names +end + + function mkfuntab(n, prefix, t, array_name, with_cast) local s = { t.." "..array_name.."[] = {\n"} local cast = '' @@ -27,6 +140,7 @@ return table.concat(s,"") end + -- @@@ sigprefix should be added by generators, not here function mksigtab(sigs, sigprefix, array_name) local s = { "const char * "..array_name.."[] = {\n"}