Mercurial > pub > dyncall > dyncall
comparison test/suite_aggrs/mk-cases.lua @ 461:236015fdf7a8
suite_aggrs:
- added support to gen unions in addition to structs
- regenerated struct/union-mixed and nested cases
- made rand-sig.lua ignore closing struct/union chars if not opened, effectively reducing number of empty aggregates as it now generated way too much
author | Tassilo Philipp |
---|---|
date | Mon, 31 Jan 2022 14:41:11 +0100 |
parents | e59e381b4fca |
children | 653b65580cb4 |
comparison
equal
deleted
inserted
replaced
460:0ae555528709 | 461:236015fdf7a8 |
---|---|
5 local aggrs = { } | 5 local aggrs = { } |
6 local seen_aggrs = { } | 6 local seen_aggrs = { } |
7 | 7 |
8 | 8 |
9 function canon_type(t) | 9 function canon_type(t) |
10 -- struct types have more than one char | 10 -- aggregate types start with special (closing) char |
11 if #t > 1 then | 11 c = ({ ['}'] = 'struct ', ['>'] = 'union ' })[t:sub(1,1)] |
12 return 'struct '..t | 12 if c ~= nil then |
13 return c..'A'..t:sub(2) | |
13 end | 14 end |
14 return t | 15 return t |
15 end | 16 end |
16 | 17 |
17 function trim(l) return l:gsub("^%s+",""):gsub("%s+$","") end | 18 function trim(l) return l:gsub("^%s+",""):gsub("%s+$","") end |
28 for i = 1, #sig do | 29 for i = 1, #sig do |
29 local name = "a"..pos | 30 local name = "a"..pos |
30 local ch = sig:sub(i,i) | 31 local ch = sig:sub(i,i) |
31 | 32 |
32 -- aggregate nest level change? | 33 -- aggregate nest level change? |
33 if ch == '{' then | 34 if ch == '{' or ch == '<' then |
34 n_nest = n_nest + 1 | 35 n_nest = n_nest + 1 |
35 aggr[n_nest] = { } | 36 aggr[n_nest] = { } |
36 aggr_sig[n_nest] = '' | 37 aggr_sig[n_nest] = '' |
37 end | 38 end |
38 | 39 |
39 aggr_sig[n_nest] = aggr_sig[n_nest]..ch | 40 aggr_sig[n_nest] = aggr_sig[n_nest]..ch |
40 | 41 |
41 if ch == '}' then | 42 if ch == '}' or ch == '>' then |
42 -- register yet unseen aggregates, key is sig, val is body and name | 43 -- register yet unseen aggregates, key is sig, val is body and name |
43 if seen_aggrs[aggr_sig[n_nest]] == nil then | 44 if seen_aggrs[aggr_sig[n_nest]] == nil then |
44 aggrs[#aggrs+1] = aggr_sig[n_nest] | 45 aggrs[#aggrs+1] = aggr_sig[n_nest] |
45 ch = 'A'..#aggrs | 46 ch = ch..#aggrs |
46 seen_aggrs[aggr_sig[n_nest]] = { aggr[n_nest], ch } | 47 seen_aggrs[aggr_sig[n_nest]] = { aggr[n_nest], ch } |
47 end | 48 end |
48 ch = seen_aggrs[aggr_sig[n_nest]][2] | 49 ch = seen_aggrs[aggr_sig[n_nest]][2] |
49 | 50 |
50 n_nest = n_nest - 1 | 51 n_nest = n_nest - 1 |
51 aggr_sig[n_nest] = aggr_sig[n_nest]..aggr_sig[n_nest+1] | 52 aggr_sig[n_nest] = aggr_sig[n_nest]..aggr_sig[n_nest+1] |
52 end | 53 end |
53 | 54 |
54 if ch ~= '{' and ch ~= '}' then | 55 if ch ~= '{' and ch ~= '}' and ch ~= '<' and ch ~= '>' then |
55 aggr[n_nest][#aggr[n_nest]+1] = canon_type(ch) | 56 aggr[n_nest][#aggr[n_nest]+1] = canon_type(ch) |
56 aggr[n_nest][#aggr[n_nest]+1] = 'm'..(#aggr[n_nest] >> 1) | 57 aggr[n_nest][#aggr[n_nest]+1] = 'm'..(#aggr[n_nest] >> 1) |
57 end | 58 end |
58 | 59 |
59 | 60 |
60 if n_nest == 0 then | 61 if n_nest == 0 then |
61 h[#h+1] = canon_type(ch) | 62 h[#h+1] = canon_type(ch) |
62 -- struct types (more than one char) need copying via a func | 63 -- aggregate types (more than one char) need copying via a func |
63 if #ch > 1 then | 64 if #h[#h] > 1 then |
64 t[#t+1] = 'f_cp'..ch..'(V_a['..pos.."],&"..name..");" | 65 t[#t+1] = 'f_cp'..h[#h]:sub(8)..'(V_a['..pos.."],&"..name..");" |
65 else | 66 else |
66 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" | 67 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" |
67 end | 68 end |
68 | 69 |
69 -- is return type or func arg? | 70 -- is return type or func arg? |
122 agg_sigs = {} | 123 agg_sigs = {} |
123 agg_names = {} | 124 agg_names = {} |
124 for a = 1, #aggrs do | 125 for a = 1, #aggrs do |
125 k = aggrs[a] | 126 k = aggrs[a] |
126 v = seen_aggrs[k] | 127 v = seen_aggrs[k] |
127 st = 'struct '..v[2] | 128 st = canon_type(v[2]) |
128 | 129 |
129 agg_sizes[#agg_sizes + 1] = 'sizeof('..st..')' | 130 agg_sizes[#agg_sizes + 1] = 'sizeof('..st..')' |
130 agg_sigs [#agg_sigs + 1] = k | 131 agg_sigs [#agg_sigs + 1] = k |
131 agg_names[#agg_names + 1] = v[2] | 132 agg_names[#agg_names + 1] = st:sub(8) |
132 | 133 |
133 -- struct def | 134 -- aggregate def |
134 io.write('/* '..k..' */\n') | 135 io.write('/* '..k..' */\n') |
135 io.write(st..' { ') | 136 io.write(st..' { ') |
136 for i = 1, #v[1], 2 do | 137 for i = 1, #v[1], 2 do |
137 io.write(v[1][i]..' '..v[1][i+1]..'; ') | 138 io.write(v[1][i]..' '..v[1][i+1]..'; ') |
138 end | 139 end |
139 io.write("};\n") | 140 io.write("};\n") |
140 | 141 |
141 -- struct cp and cmp funcs | 142 -- aggregate cp and cmp funcs |
142 s = { | 143 s = { |
143 'void f_cp'..v[2]..'('..st..' *x, const '..st..' *y) { ', | 144 'void f_cp'..st:sub(8)..'('..st..' *x, const '..st..' *y) { ', |
144 'int f_cmp'..v[2]..'(const '..st..' *x, const '..st..' *y) { return ' | 145 'int f_cmp'..st:sub(8)..'(const '..st..' *x, const '..st..' *y) { return ' |
145 } | 146 } |
146 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' } | 147 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' } |
147 for t = 1, 2 do | 148 for t = 1, 2 do |
148 io.write(s[t]) | 149 io.write(s[t]) |
149 b = {} | 150 b = {} |
150 for i = 1, #v[1], 2 do | 151 for i = 1, #v[1], 2 do |
151 if string.match(v[1][i], '^struct') then | 152 if string.match(v[1][i], ' ') then -- aggregate canonical types contain at least one space |
152 b[#b+1] = o[t+2]..v[1][i]:sub(8)..'(&x->'..v[1][i+1]..', &y->'..v[1][i+1]..')'; | 153 b[#b+1] = o[t+2]..v[1][i]:sub(8)..'(&x->'..v[1][i+1]..', &y->'..v[1][i+1]..')'; |
153 else | 154 else |
154 b[#b+1] = 'x->'..v[1][i+1]..' '..o[t]..' y->'..v[1][i+1]; | 155 b[#b+1] = 'x->'..v[1][i+1]..' '..o[t]..' y->'..v[1][i+1]; |
155 end | 156 end |
156 end | 157 end |
157 if #b == 0 then -- to handle empty structs | 158 if #b == 0 then -- to handle empty aggregates |
158 b[1] = o[t+6] | 159 b[1] = o[t+6] |
159 end | 160 end |
160 io.write(table.concat(b,o[t+4]).."; };\n") | 161 io.write(table.concat(b,o[t+4]).."; };\n") |
161 end | 162 end |
162 | 163 |
163 -- convenient dcnewstruct helper funcs | 164 -- convenient dcnewstruct helper funcs |
164 io.write('DCstruct* f_touchdcst'..v[2]..'() {\n\tstatic DCstruct* st = NULL;\n\tif(!st) {\n\t\tst = dcNewStruct('..(#v[1]>>1)..', sizeof('..st..'), DC_TRUE);\n\t\t') | 165 io.write('DCstruct* f_touchdcst'..st:sub(8)..'() {\n\tstatic DCstruct* st = NULL;\n\tif(!st) {\n\t\tst = dcNewStruct('..(#v[1]>>1)..', sizeof('..st..'), DC_TRUE);\n\t\t') |
165 for i = 1, #v[1], 2 do | 166 for i = 1, #v[1], 2 do |
166 if string.match(v[1][i], '^struct') then | 167 if string.match(v[1][i], ' ') then -- aggregate canonical types contain at least one space |
167 io.write('dcStructField(st, DC_SIGCHAR_STRUCT, offsetof('..st..', '..v[1][i+1]..'), 1, f_touchdcst'..v[1][i]:sub(8)..'());\n\t\t') | 168 io.write('dcStructField(st, DC_SIGCHAR_STRUCT, offsetof('..st..', '..v[1][i+1]..'), 1, f_touchdcst'..v[1][i]:sub(8)..'());\n\t\t') |
168 else | 169 else |
169 io.write("dcStructField(st, '"..v[1][i].."', offsetof("..st..', '..v[1][i+1]..'), 1);\n\t\t') | 170 io.write("dcStructField(st, '"..v[1][i].."', offsetof("..st..', '..v[1][i+1]..'), 1);\n\t\t') |
170 end | 171 end |
171 end | 172 end |