diff test/suite_aggrs/mk-cases.lua @ 462:653b65580cb4

suite_aggr: - added arrays (inside of structs/unions, only, as only way to pass/return them by value) - cleanups and pregen of source
author Tassilo Philipp
date Tue, 01 Feb 2022 21:44:18 +0100
parents 236015fdf7a8
children 0f3b6898078d
line wrap: on
line diff
--- a/test/suite_aggrs/mk-cases.lua	Mon Jan 31 14:41:11 2022 +0100
+++ b/test/suite_aggrs/mk-cases.lua	Tue Feb 01 21:44:18 2022 +0100
@@ -30,6 +30,7 @@
     local name = "a"..pos
     local ch   = sig:sub(i,i)
 
+
     -- aggregate nest level change?
     if ch == '{' or ch == '<' then
       n_nest = n_nest + 1
@@ -39,45 +40,51 @@
 
     aggr_sig[n_nest] = aggr_sig[n_nest]..ch
 
-    if ch == '}' or ch == '>' then
-      -- register yet unseen aggregates, key is sig, val is body and name
-      if seen_aggrs[aggr_sig[n_nest]] == nil then
-        aggrs[#aggrs+1] = aggr_sig[n_nest]
-        ch = ch..#aggrs
-        seen_aggrs[aggr_sig[n_nest]] = { aggr[n_nest], ch }
-      end
-      ch = seen_aggrs[aggr_sig[n_nest]][2]
-
-      n_nest = n_nest - 1
-      aggr_sig[n_nest] = aggr_sig[n_nest]..aggr_sig[n_nest+1]
-    end
+    -- array? Just append to name of member var from prev loop
+    if ch:match('[%[%]0123456789]') ~= nil then
+      aggr[n_nest][#aggr[n_nest]] = aggr[n_nest][#aggr[n_nest]]..ch
+    else
 
-    if ch ~= '{' and ch ~= '}' and ch ~= '<' and ch ~= '>' then
-      aggr[n_nest][#aggr[n_nest]+1] = canon_type(ch)
-      aggr[n_nest][#aggr[n_nest]+1] = 'm'..(#aggr[n_nest] >> 1)
-    end
-
+      if ch == '}' or ch == '>' then
+        -- register yet unseen aggregates, key is sig, val is body and name
+        if seen_aggrs[aggr_sig[n_nest]] == nil then
+          aggrs[#aggrs+1] = aggr_sig[n_nest]
+          ch = ch..#aggrs
+          seen_aggrs[aggr_sig[n_nest]] = { aggr[n_nest], ch }
+        end
+        ch = seen_aggrs[aggr_sig[n_nest]][2]
 
-    if n_nest == 0 then
-      h[#h+1] = canon_type(ch)
-      -- aggregate types (more than one char) need copying via a func
-      if #h[#h] > 1 then
-        t[#t+1] = 'f_cp'..h[#h]:sub(8)..'(V_a['..pos.."],&"..name..");"
-      else
-        t[#t+1] = "V_"..ch.."["..pos.."]="..name..";"
+        n_nest = n_nest - 1
+        aggr_sig[n_nest] = aggr_sig[n_nest]..aggr_sig[n_nest+1]
+      end
+
+      if ch ~= '{' and ch ~= '}' and ch ~= '<' and ch ~= '>' then
+        aggr[n_nest][#aggr[n_nest]+1] = canon_type(ch)
+        aggr[n_nest][#aggr[n_nest]+1] = 'm'..(#aggr[n_nest] >> 1)
       end
 
-      -- is return type or func arg?
-      if pos == 0 then
-        h[#h+1] = " f"..id.."("
-        h[#h+1] = ''
-        t[#t] = ''  -- clear; aggr return type handled explicitly
-      else
-        h[#h+1] = ' '..name
-        h[#h+1] = ","
+      -- no nesting (= actual func args), generate case code
+      if n_nest == 0 then
+        h[#h+1] = canon_type(ch)
+        -- aggregate types (more than one char) need copying via a func
+        if #h[#h] > 1 then
+          t[#t+1] = 'f_cp'..h[#h]:sub(8)..'(V_a['..pos.."],&"..name..");"
+        else
+          t[#t+1] = "V_"..ch.."["..pos.."]="..name..";"
+        end
+
+        -- is return type or func arg?
+        if pos == 0 then
+          h[#h+1] = " f"..id.."("
+          h[#h+1] = ''
+          t[#t] = ''  -- clear; aggr return type handled explicitly
+        else
+          h[#h+1] = ' '..name
+          h[#h+1] = ","
+        end
+
+        pos = pos + 1
       end
-
-      pos = pos + 1
     end
   end
   maxargs = max(maxargs, pos-1)
@@ -108,6 +115,17 @@
   return table.concat(s,"")
 end
 
+function split_array_decl(s)
+  local name = s
+  local n = nil  -- not an array
+  local array_i = s:find('%[')
+  if array_i ~= nil then
+    name = name:sub(1, array_i-1)
+    n = tonumber(s:sub(array_i):match('[0123456789]+'))
+  end
+  return { name, n }
+end
+
 function mkall()
   local lineno = 0
   local sigtab = { }
@@ -123,37 +141,49 @@
   agg_sigs  = {}
   agg_names = {}
   for a = 1, #aggrs do
-    k = aggrs[a]
-	v = seen_aggrs[k]
-    st = canon_type(v[2])
+    local k = aggrs[a]
+    local v = seen_aggrs[k]
+    local at = canon_type(v[2])  -- aggregate type
+    local am = v[1]              -- aggregate members
 
-    agg_sizes[#agg_sizes + 1] = 'sizeof('..st..')'
+    agg_sizes[#agg_sizes + 1] = 'sizeof('..at..')'
     agg_sigs [#agg_sigs  + 1] = k
-    agg_names[#agg_names + 1] = st:sub(8)
+    agg_names[#agg_names + 1] = at:sub(8)
 
     -- aggregate def
     io.write('/* '..k..' */\n')
-    io.write(st..' { ')
-    for i = 1, #v[1], 2 do
-      io.write(v[1][i]..' '..v[1][i+1]..'; ')
+    io.write(at..' { ')
+    for i = 1, #am, 2 do
+      io.write(am[i]..' '..am[i+1]..'; ')
     end
     io.write("};\n")
 
     -- aggregate cp and cmp funcs
     s = {
-      'void f_cp'..st:sub(8)..'('..st..' *x, const '..st..' *y) { ',
-      'int f_cmp'..st:sub(8)..'(const '..st..' *x, const '..st..' *y) { return '
+      'void f_cp'..at:sub(8)..'('..at..' *x, const '..at..' *y) { ',
+      'int f_cmp'..at:sub(8)..'(const '..at..' *x, const '..at..' *y) { return '
     }
     o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' }
     for t = 1, 2 do
       io.write(s[t])
-      b = {}
-      for i = 1, #v[1], 2 do
-        if string.match(v[1][i], ' ') then -- aggregate canonical types contain at least one space
-		  b[#b+1] = o[t+2]..v[1][i]:sub(8)..'(&x->'..v[1][i+1]..', &y->'..v[1][i+1]..')';
-		else
-          b[#b+1] = 'x->'..v[1][i+1]..' '..o[t]..' y->'..v[1][i+1];
-		end
+      local b = {}
+      for i = 1, #am, 2 do
+        local m = split_array_decl(am[i+1])
+        local fmt = ''
+        if m[2] ~= nil then -- need array suffixes?
+          fmt = '[%d]'
+        else
+          m[2] = 1
+        end
+
+        for j = 1, m[2] do
+          name = m[1]..string.format(fmt, j-1)
+          if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space
+            b[#b+1] = o[t+2]..am[i]:sub(8)..'(&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]
@@ -162,15 +192,19 @@
     end
 
     -- convenient dcnewstruct helper funcs
-    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')
-    for i = 1, #v[1], 2 do
-      if string.match(v[1][i], ' ') then -- aggregate canonical types contain at least one space
-	    io.write('dcStructField(st, DC_SIGCHAR_STRUCT, offsetof('..st..', '..v[1][i+1]..'), 1, f_touchdcst'..v[1][i]:sub(8)..'());\n\t\t')
-	  else
-        io.write("dcStructField(st, '"..v[1][i].."', offsetof("..st..', '..v[1][i+1]..'), 1);\n\t\t')
-	  end
+    io.write('DCstruct* f_touchdcst'..at:sub(8)..'() {\n\tstatic DCstruct* at = NULL;\n\tif(!at) {\n\t\tat = dcNewStruct('..(#am>>1)..', sizeof('..at..'), DC_TRUE);\n\t\t')
+    for i = 1, #am, 2 do
+      local m = split_array_decl(am[i+1])
+      if m[2] == nil then -- need array suffixes?
+        m[2] = 1
+      end
+      if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space
+        io.write('dcStructField(at, DC_SIGCHAR_STRUCT, offsetof('..at..', '..m[1]..'), '..m[2]..', f_touchdcst'..am[i]:sub(8)..'());\n\t\t')
+      else
+        io.write("dcStructField(at, '"..am[i].."', offsetof("..at..', '..m[1]..'), '..m[2]..');\n\t\t')
+      end
     end
-    io.write("dcCloseStruct(st);\n\t}\n\treturn st;\n};\n")
+    io.write("dcCloseStruct(at);\n\t}\n\treturn at;\n};\n")
   end
 
   -- make table.concat work