diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-30 15:46:34 -0500 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-30 15:46:34 -0500 |
| commit | e06917f40f5bd3a4b4bec51d05d85dffa4eb5867 (patch) | |
| tree | 58e887f548d0a6276dcc35a686d523420f544a1c /tests | |
| parent | 8b9c39f42eec79607392c81538e08da1b814809a (diff) | |
| download | nimterop-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.h | 8 | ||||
| -rw-r--r-- | tests/tast2.nim | 247 |
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 |
