comparison test/call_suite_aggrs/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
comparison
equal deleted inserted replaced
520:bb4933eab7d6 521:a2de1d0a73f3
4 -- use shared helpers to generate cases 4 -- use shared helpers to generate cases
5 package.path = '../common/?.lua;' .. package.path 5 package.path = '../common/?.lua;' .. package.path
6 require"mk-cases" 6 require"mk-cases"
7 7
8 8
9 local max_numargs = 0
10 9
11 10 -- returns: generated case str, num args; accumulates unique idx => aggr-sig in
12 11 -- aggrs (sequentially) and aggr-sig => {body,name} in seen_aggrs (depth first
13 function put_sig_rtype_first(sig) 12 -- for nested aggrs, so sub-aggrs conveniently precede parents)
14 return sig:sub(sig:find(')')+1,-1)..sig:sub(1,sig:find(')')-1)
15 end
16
17
18 -- returns one case as str; accumulates unique idx => aggr-sig in aggrs
19 -- (sequentially) and aggr-sig => {body,name} in seen_aggrs (depth first for
20 -- nested aggrs, so sub-aggrs conveniently precede parents)
21 function mkcase(id, sig, aggrs, seen_aggrs) 13 function mkcase(id, sig, aggrs, seen_aggrs)
22 local sig = trim(sig) 14 local sig = trim(sig)
23 local fsig = put_sig_rtype_first(sig) 15 local fsig = put_sig_rtype_first(sig)
24 local h = { "/* ",id,":",sig," */ " } 16 local h = { "/* ",id,":",sig," */ " }
25 local t = { "" } 17 local t = { "" }
97 89
98 pos = pos + 1 90 pos = pos + 1
99 end 91 end
100 end 92 end
101 end 93 end
102 max_numargs = math.max(max_numargs, pos)
103 h[#h] = "){" 94 h[#h] = "){"
104 if #h[6] == 1 then 95 if #h[6] == 1 then
105 t[#t+1] = "ret_"..h[6].."("..pos..")}\n" 96 t[#t+1] = "ret_"..h[6].."("..pos..")}\n"
106 else 97 else
107 t[#t+1] = "ret_a("..pos..","..h[6]..")}\n" 98 t[#t+1] = "ret_a("..pos..","..h[6]..")}\n"
108 end 99 end
109 return table.concat(h,"")..table.concat(t,"") 100 return table.concat(h,"")..table.concat(t,""), pos
110 end
111
112
113 function mkaggrdefs(aggrs, seen_aggrs)
114 local agg_defs = { }
115 local agg_sizes = { }
116 local agg_sigs = { }
117 local agg_names = { }
118
119 for a = 1, #aggrs do
120 local k = aggrs[a]
121 local v = seen_aggrs[k]
122 local am = v[1] -- aggregate members
123 local at = v[2] -- aggregate type
124 local an = at:match('A.*') -- aggregate name (w/o struct or union)
125
126 -- aggregate def
127 aggr_def = '/* '..k..' */\n'
128 if aggrpacking ~= 0 then
129 local pack = aggrpacking
130 if pack < 0 then
131 pack = math.floor(math.pow(2,math.floor(math.log(math.random(math.abs(pack)),2))))
132 end
133 aggr_def = aggr_def..'#pragma pack(push,'..pack..')\n'
134 end
135
136 aggr_def = aggr_def..at..' { '
137 for i = 1, #am, 2 do
138 aggr_def = aggr_def..am[i]..' '..am[i+1]..'; '
139 end
140 aggr_def = aggr_def..'};\n'
141
142 if aggrpacking ~= 0 then
143 aggr_def = aggr_def..'#pragma pack(pop)\n'
144 end
145
146 -- aggregate cp and cmp funcs
147 s = {
148 'void f_cp'..an..'('..at..' *x, const '..at..' *y) { ',
149 'int f_cmp'..an..'(const '..at..' *x, const '..at..' *y) { return '
150 }
151 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' }
152 for t = 1, 2 do
153 if t ~= 1 or aggrcpsimple == false then
154 aggr_def = aggr_def..s[t]
155 local b = {}
156 for i = 1, #am, 2 do
157 local mn, mc = split_array_decl(am[i+1]) -- aggr member name and (array) count
158 local fmt = ''
159 if mc ~= nil then -- need array suffixes?
160 fmt = '[%d]'
161 else
162 mc = 1
163 end
164
165 for j = 1, mc do
166 name = mn..fmt:format(j-1)
167 amn = am[i]:match('A.*')
168 if amn then -- is aggr?
169 b[#b+1] = o[t+2]..amn..'(&x->'..name..', &y->'..name..')'
170 else
171 b[#b+1] = 'x->'..name..' '..o[t]..' y->'..name
172 end
173 end
174 end
175 if #b == 0 then -- to handle empty aggregates
176 b[1] = o[t+6]
177 end
178 aggr_def = aggr_def..table.concat(b,o[t+4])..'; };\n'
179 end
180 end
181
182 -- write convenient dcNewAggr() helper/wrapper funcs
183 aggr_def = aggr_def..'DCaggr* f_touchdcst'..an..'() {\n\tstatic DCaggr* a = NULL;\n\tif(!a) {\n\t\ta = dcNewAggr('..(#am>>1)..', sizeof('..at..'));\n\t\t'
184 for i = 1, #am, 2 do
185 local mn, mc = split_array_decl(am[i+1])
186 if mc == nil then
187 mc = 1
188 end
189 amn = am[i]:match('A.*')
190 if amn then -- is aggr?
191 --aggr_def = aggr_def..'dcAggrField(at, DC_SIGCHAR_AGGREGATE, offsetof('..at..', '..mn..'), '..mc..', f_touchdcst'..amn..'());\n\t\t'
192 aggr_def = aggr_def.."AFa("..at..','..mn..','..mc..','..amn..')\n\t\t'
193 else
194 --aggr_def = aggr_def.."dcAggrField(at, '"..am[i].."', offsetof("..at..', '..mn..'), '..mc..');\n\t\t'
195 aggr_def = aggr_def.."AF('"..am[i].."',"..at..','..mn..','..mc..')\n\t\t'
196 end
197 end
198
199 agg_defs [#agg_defs + 1] = aggr_def..'dcCloseAggr(a);\n\t}\n\treturn a;\n};'
200 agg_sizes[#agg_sizes + 1] = 'sizeof('..at..')'
201 agg_sigs [#agg_sigs + 1] = k
202 agg_names[#agg_names + 1] = an
203 end
204
205 return agg_defs, agg_sizes, agg_sigs, agg_names
206 end 101 end
207 102
208 103
209 function mkall() 104 function mkall()
210 local lineno = 0 105 local lineno = 0
211 local sigtab = { } 106 local sigtab = { }
212 local cases = '' 107 local cases = ''
213 local aggrs = { } 108 local aggrs = { }
214 local seen_aggrs = { } 109 local seen_aggrs = { }
215 110 local max_numargs = 0
216 111
217 for line in io.lines() do 112 for line in io.lines() do
218 local sig = trim(line) 113 local sig = trim(line)
219 cases = cases..mkcase(lineno, sig, aggrs, seen_aggrs) 114 local c, n = mkcase(lineno, sig, aggrs, seen_aggrs)
115 cases = cases..c
116 max_numargs = math.max(max_numargs, n)
220 sigtab[#sigtab+1] = sig 117 sigtab[#sigtab+1] = sig
221 lineno = lineno + 1 118 lineno = lineno + 1
222 end 119 end
223 120
224 local agg_defs, agg_sizes, agg_sigs, agg_names = mkaggrdefs(aggrs, seen_aggrs) 121 local agg_defs, agg_sizes, agg_sigs, agg_names = mkaggrdefs(aggrs, seen_aggrs, aggrpacking, aggrpackingseed)
225 122
226 -- make table.concat work 123 -- make table.concat work
227 if #agg_names > 0 then 124 if #agg_names > 0 then
228 table.insert(agg_names, 1, '') 125 table.insert(agg_names, 1, '')
229 end 126 end
232 io.write(cases) 129 io.write(cases)
233 io.write(mkfuntab(lineno, 'f', 'funptr', 'G_funtab', true)) 130 io.write(mkfuntab(lineno, 'f', 'funptr', 'G_funtab', true))
234 io.write(mksigtab(sigtab, '', 'G_sigtab')) 131 io.write(mksigtab(sigtab, '', 'G_sigtab'))
235 io.write('const char* G_agg_sigs[] = {\n\t"'..table.concat(agg_sigs, '",\n\t"')..'"\n};\n') 132 io.write('const char* G_agg_sigs[] = {\n\t"'..table.concat(agg_sigs, '",\n\t"')..'"\n};\n')
236 io.write('int G_agg_sizes[] = {\n\t'..table.concat(agg_sizes, ',\n\t')..'\n};\n') 133 io.write('int G_agg_sizes[] = {\n\t'..table.concat(agg_sizes, ',\n\t')..'\n};\n')
237 io.write('funptr G_agg_touchdcstfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_touchdcst'),2)..'\n};\n') 134 io.write('funptr G_agg_touchAfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_touch'),2)..'\n};\n')
238 io.write('funptr G_agg_cmpfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_cmp'),2)..'\n};\n') 135 io.write('funptr G_agg_cmpfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_cmp'),2)..'\n};\n')
239 io.write("int G_maxargs = "..max_numargs..";\n") 136 io.write("int G_maxargs = "..max_numargs..";\n")
240 end 137 end
241 138
242 math.randomseed(seed)
243 mkall() 139 mkall()
244 140