aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2020-03-30 15:46:34 -0500
committerGanesh Viswanathan <dev@genotrance.com>2020-03-30 15:46:34 -0500
commite06917f40f5bd3a4b4bec51d05d85dffa4eb5867 (patch)
tree58e887f548d0a6276dcc35a686d523420f544a1c /tests
parent8b9c39f42eec79607392c81538e08da1b814809a (diff)
downloadnimterop-e06917f40f5bd3a4b4bec51d05d85dffa4eb5867.tar.gz
nimterop-e06917f40f5bd3a4b4bec51d05d85dffa4eb5867.zip
c2nImport ret, del specials from header, cache if exec not die, ast2 type pragma improvements
Diffstat (limited to 'tests')
-rw-r--r--tests/include/tast2.h8
-rw-r--r--tests/tast2.nim247
2 files changed, 190 insertions, 65 deletions
diff --git a/tests/include/tast2.h b/tests/include/tast2.h
index 8e84b01..db539c7 100644
--- a/tests/include/tast2.h
+++ b/tests/include/tast2.h
@@ -19,6 +19,10 @@ struct A0 {
int f1;
};
+struct A4 {
+ float f1;
+};
+
typedef char *A9p[3]; //, A9[4];
typedef char *A10[3][6];
typedef char *(*A11)[3];
@@ -127,6 +131,10 @@ struct A0 {
int f1;
};
+struct A4 {
+ float f1;
+};
+
typedef char *A9p[3]; //, A9[4];
typedef char *A10[3][6];
typedef char *(*A11)[3];
diff --git a/tests/tast2.nim b/tests/tast2.nim
index 76e4561..4b19429 100644
--- a/tests/tast2.nim
+++ b/tests/tast2.nim
@@ -1,30 +1,41 @@
-import macros, sets, tables
+import macros, os, sets, strutils
import nimterop/[cimport]
static:
cDebug()
-cOverride:
- const
- A* = 2
-
- type
- A1* = A0
+const
+ path = currentSourcePath.parentDir() / "include" / "tast2.h"
when defined(HEADER):
cDefine("HEADER")
const
- flags = " -H"
- imp = @["importc", "header:headertast2"]
+ flags = " -H -d"
+ pHeader = @["header:" & path]
+ pHeaderImp = @["importc"] & pHeader
else:
const
flags = ""
- imp = @[]
+ pHeader: seq[string] = @[]
+ pHeaderImp: seq[string] = @[]
-cImport("include/tast2.h", flags="-d -f:ast2 -ENK_" & flags)
+const
+ pHeaderImpBy = @["bycopy"] & pHeaderImp
+ pHeaderBy = @["bycopy"] & pHeader
+ pHeaderInc = @["incompleteStruct"] & pHeader
+
+cOverride:
+ const
+ A* = 2
+
+ type
+ A1* = A0
+
+cImport(path, flags="-f:ast2 -ENK_" & flags)
proc getPragmas(n: NimNode): HashSet[string] =
+ # Find all pragmas in AST, return as "name" or "name:value" in set
for i in 0 ..< n.len:
if n[i].kind == nnkPragma:
for j in 0 ..< n[i].len:
@@ -35,24 +46,54 @@ proc getPragmas(n: NimNode): HashSet[string] =
else:
result.incl n[i].getPragmas()
-macro checkPragmas(t: typed, pragmas: static[seq[string]]): untyped =
- let
+proc getRecList(n: NimNode): NimNode =
+ # Find nnkRecList in AST
+ for i in 0 ..< n.len:
+ if n[i].kind == nnkRecList:
+ return n[i]
+ elif n[i].len != 0:
+ let
+ rl = getRecList(n[i])
+ if not rl.isNil:
+ return rl
+
+macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] = true): untyped =
+ # Verify that type has expected pragmas defined
+ # `istype` is true when typedef X
+ var
ast = t.getImpl()
prag = ast.getPragmas()
exprag = pragmas.toHashSet()
+ when defined(HEADER):
+ if not istype:
+ if "union" in exprag:
+ exprag.incl "importc:union " & $t
+ else:
+ exprag.incl "importc:struct " & $t
doAssert symmetricDifference(prag, exprag).len == 0,
"\nWrong number of pragmas in " & $t & "\n" & $prag & " vs " & $exprag
-proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) =
+macro testFields(t: typed, fields: static[string] = "") =
+ # Verify that type has expected fields
var
- obj: t
- count = 0
- for name, value in obj.fieldPairs():
- count += 1
- assert name in fields, $t & "." & name & " invalid"
- assert $fields[name] == $typeof(value),
- "typeof(" & $t & ":" & name & ") != " & fields[name] & ", is " & $typeof(value)
- assert count == fields.len, "Failed for " & $t
+ ast = t.getImpl()
+ rl = ast.getRecList()
+ fsplit = fields.split(":")
+ names = fsplit[0].split("|")
+ types =
+ if fsplit.len > 1:
+ fsplit[1].split("|")
+ else:
+ @[]
+ if not rl.isNil:
+ for i in 0 ..< rl.len:
+ let
+ name = ($rl[i][0]).strip(chars = {'*'})
+ typ = $(rl[i][1].repr())
+ n = names.find(name)
+ assert n != -1, $t & "." & name & " invalid"
+ assert types[n] == typ,
+ "typeof(" & $t & ":" & name & ") != " & types[n] & ", is " & typ
assert A == 2
assert B == 1.0
@@ -60,114 +101,190 @@ assert C == 0x10
assert D == "hello"
assert E == 'c'
-const
- pragmas = @["bycopy"] & imp
-
assert A0 is object
-testFields(A0, {"f1": "cint"}.toTable())
-checkPragmas(A0, pragmas)
+testFields(A0, "f1:cint")
+checkPragmas(A0, pHeaderBy, istype = false)
+var a0: A0
+a0.f1 = 1
assert A1 is A0
-testFields(A1, {"f1": "cint"}.toTable())
+testFields(A1, "f1:cint")
+var a1: A1
+a1.f1 = 2
assert A2 is object
testFields(A2)
-checkPragmas(A2, pragmas)
+checkPragmas(A2, pHeaderInc, istype = false)
+when not defined(HEADER):
+ # typedef struct X; is invalid
+ var a2: A2
assert A3 is object
testFields(A3)
-checkPragmas(A3, pragmas)
+checkPragmas(A3, pHeaderInc, istype = false)
+var a3: A3
assert A4 is object
-testFields(A4)
-checkPragmas(A4, pragmas)
+testFields(A4, "f1:cfloat")
+checkPragmas(A4, pHeaderImpBy)
+var a4: A4
+a4.f1 = 4.1
assert A4p is ptr A4
-checkPragmas(A4p, imp)
+testFields(A4p, "f1:cfloat")
+checkPragmas(A4p, pHeaderImp)
+var a4p: A4p
+a4p = addr a4
assert A5 is cint
-checkPragmas(A5, imp)
+checkPragmas(A5, pHeaderImp)
+const a5: A5 = 5
assert A6 is ptr cint
-checkPragmas(A6, imp)
+checkPragmas(A6, pHeaderImp)
+var
+ a6: A6
+ a6i = 6
+a6 = cast[A6](addr a6i)
assert A7 is ptr ptr A0
-checkPragmas(A7, imp)
+checkPragmas(A7, pHeaderImp)
+var
+ a7: A7
+ a7a = addr a0
+a7 = addr a7a
assert A8 is pointer
-checkPragmas(A8, imp)
+checkPragmas(A8, pHeaderImp)
+var a8: A8
+a8 = nil
assert A9p is array[3, cstring]
-checkPragmas(A9p, imp)
+checkPragmas(A9p, pHeaderImp)
+var a9p: A9p
+a9p[1] = nil
+a9p[2] = "hello".cstring
+#Not implemented yet
#assert A9 is array[4, cchar]
-#checkPragmas(A9, imp)
+#checkPragmas(A9, pHeaderImp)
+#var a9: A9
assert A10 is array[3, array[6, cstring]]
-checkPragmas(A10, imp)
+checkPragmas(A10, pHeaderImp)
+var a10: A10
+a10[2][5] = "12345".cstring
assert A11 is ptr array[3, cstring]
-checkPragmas(A11, imp)
+checkPragmas(A11, pHeaderImp)
+var a11: A11
+a11 = addr a9p
assert A111 is array[12, ptr A1]
-checkPragmas(A111, imp)
+checkPragmas(A111, pHeaderImp)
+var a111: A111
+a111[11] = addr a1
assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint
-checkPragmas(A12, imp)
+checkPragmas(A12, pHeaderImp)
+when not defined(HEADER):
+ # Unclear why this fails
+ # request for member ‘ClE_0’ in something not a structure or union
+ var a12: A12
assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint
-checkPragmas(A13, imp)
+checkPragmas(A13, pHeaderImp)
+when not defined(HEADER):
+ # Unclear why this fails
+ # request for member ‘ClE_0’ in something not a structure or union
+ var a13: A13
assert A14 is object
-testFields(A14, {"a1": "cchar"}.toTable())
-checkPragmas(A14, pragmas)
+testFields(A14, "a1:cchar")
+checkPragmas(A14, pHeaderBy, istype = false)
+var a14: A14
+a14.a1 = 'a'
assert A15 is object
-testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable())
-checkPragmas(A15, pragmas)
+testFields(A15, "a1|a2:cstring|array[1, ptr cint]")
+checkPragmas(A15, pHeaderBy, istype = false)
+var
+ a15: A15
+ a15i = 15.cint
+a15.a1 = "hello".cstring
+a15.a2[0] = addr a15i
assert A16 is object
-testFields(A16, {"f1": "cchar"}.toTable())
-checkPragmas(A16, pragmas)
+testFields(A16, "f1:cchar")
+checkPragmas(A16, pHeaderImpBy)
+when not defined(HEADER):
+ # Similar to A2
+ var a16: A16
+ a16.f1 = 's'
assert A17 is object
-testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable())
-checkPragmas(A17, pragmas)
+testFields(A17, "a1|a2:cstring|array[1, ptr cint]")
+checkPragmas(A17, pHeaderImpBy)
+when not defined(HEADER):
+ # Similar to A2
+ var a17: A17
+ a17.a1 = "hello".cstring
+ a17.a2[0] = addr a15i
assert A18 is A17
-checkPragmas(A18, imp)
+checkPragmas(A18, pHeaderImp)
+var a18: A18
assert A18p is ptr A17
-checkPragmas(A18p, imp)
+checkPragmas(A18p, pHeaderImp)
+var a18p: A18p
+a18p = addr a18
assert A19 is object
-testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable())
-checkPragmas(A19, pragmas)
+testFields(A19, "a1|a2:cstring|array[1, ptr cint]")
+checkPragmas(A19, pHeaderImpBy)
+var a19: A19
+a19.a1 = "hello".cstring
+a19.a2[0] = addr a15i
assert A19p is ptr A19
-checkPragmas(A19p, imp)
+checkPragmas(A19p, pHeaderImp)
+var a19p: A19p
+a19p = addr a19
assert A20 is object
-testFields(A20, {"a1": "cchar"}.toTable())
-checkPragmas(A20, pragmas)
+testFields(A20, "a1:cchar")
+checkPragmas(A20, pHeaderImpBy)
+var a20: A20
+a20.a1 = 'a'
assert A21 is A20
-checkPragmas(A21, imp)
+checkPragmas(A21, pHeaderImp)
+var a21: A21
+a21 = a20
assert A21p is ptr A20
-checkPragmas(A21p, imp)
+checkPragmas(A21p, pHeaderImp)
+var a21p: A21p
+a21p = addr a20
assert A22 is object
-testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable())
-checkPragmas(A22, pragmas)
+testFields(A22, "f1|f2:ptr ptr cint|array[123 + 132, ptr cint]")
+checkPragmas(A22, pHeaderImpBy)
+var a22: A22
+a22.f1 = addr a15.a2[0]
assert U1 is object
assert sizeof(U1) == sizeof(cfloat)
-checkPragmas(U1, pragmas & @["union"])
+checkPragmas(U1, pHeaderBy & @["union"], istype = false)
+var u1: U1
+u1.f1 = 5
assert U2 is object
assert sizeof(U2) == 256 * sizeof(cint)
-checkPragmas(U2, pragmas & @["union"])
+checkPragmas(U2, pHeaderImpBy & @["union"])
+var u2: U2
+u2.f1 = addr a15.a2[0]
assert PANEL_WINDOW == 1
assert PANEL_GROUP == 2