aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2019-01-19 00:23:26 -0600
committerGanesh Viswanathan <dev@genotrance.com>2019-01-19 00:23:26 -0600
commit47bc610c9ac321c69b4919b9c339e9e390a806a7 (patch)
treeadede4092edcaffdfa67bb1cec4a8f3ecf1a5eed
parentdd234ab7eff217d9d14df7d0fe16ff44466f5be9 (diff)
downloadnimterop-47bc610c9ac321c69b4919b9c339e9e390a806a7.tar.gz
nimterop-47bc610c9ac321c69b4919b9c339e9e390a806a7.zip
Fix #41
-rw-r--r--nimterop/getters.nim9
-rw-r--r--nimterop/grammar.nim25
-rw-r--r--tests/include/test.h2
-rw-r--r--tests/tnimterop_c.nim3
4 files changed, 33 insertions, 6 deletions
diff --git a/nimterop/getters.nim b/nimterop/getters.nim
index 1b39247..06688a9 100644
--- a/nimterop/getters.nim
+++ b/nimterop/getters.nim
@@ -109,7 +109,14 @@ proc getUniqueIdentifier*(existing: HashSet[string], prefix = ""): string =
return name & $count
proc addNewIdentifer*(existing: var HashSet[string], name: string): bool =
- return not existing.containsOrIncl(name.replace("_", "").toLowerAscii)
+ let
+ nimName =
+ if existing == gStateRT.types:
+ name[0] & name[1 .. ^1].replace("_", "").toLowerAscii
+ else:
+ name.replace("_", "").toLowerAscii
+
+ return not existing.containsOrIncl(nimName)
proc getPtrType*(str: string): string =
result = case str:
diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim
index ee42825..5e37393 100644
--- a/nimterop/grammar.nim
+++ b/nimterop/grammar.nim
@@ -171,8 +171,14 @@ proc initGrammar() =
let
nchild = $node.tsNodeNamedChild(i).tsNodeType()
if nchild != "comment":
- if nchild == "union_specifier":
- union = " {.union.}"
+ case nchild:
+ of "struct_specifier":
+ if fstart == 1:
+ prefix = "struct "
+ of "union_specifier":
+ if fstart == 1:
+ prefix = "union "
+ union = " {.union.}"
break
if gStateRT.types.addNewIdentifer(nname):
@@ -238,6 +244,15 @@ proc initGrammar() =
gStateRT.typeStr &= &" {fname}*: {getPtrType(fptr&ftyp)}\n"
i += 1
+ if node.tsNodeType() == "type_definition" and
+ gStateRT.data[^1].name == "type_identifier":
+ let
+ dname = gStateRT.data[^1].val
+ ndname = gStateRT.data[^1].val.getIdentifier()
+
+ if gStateRT.types.addNewIdentifer(ndname):
+ gStateRT.typeStr &= &" {ndname}* {{.importc: \"{dname}\", header: {gStateRT.currentHeader}, bycopy.}} = {nname}\n"
+
let
fieldGrammar = &"""
(field_identifier!)
@@ -296,9 +311,11 @@ proc initGrammar() =
if gStateRT.data.len > 1 and
gStateRT.data[0].name == "type_identifier" and
gStateRT.data[1].name != "field_identifier":
- offset = 1
- pStructCommon(ast, node, gStateRT.data[^1].val, offset, 1)
+ offset = 1
+ pStructCommon(ast, node, gStateRT.data[0].val, offset, 1)
+ else:
+ pStructCommon(ast, node, gStateRT.data[^1].val, offset, 1)
))
proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
diff --git a/tests/include/test.h b/tests/include/test.h
index 64bdbb2..f450814 100644
--- a/tests/include/test.h
+++ b/tests/include/test.h
@@ -77,7 +77,7 @@ typedef struct {
ENUM4 *field5[TEST_INT];
} STRUCT4;
-typedef struct STRUCT5 {
+typedef struct struct5 {
int (*tci)();
struct STRUCT1 (*tcp)(int);
float (*tcp8)(int *i);
diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim
index 86526c1..e848950 100644
--- a/tests/tnimterop_c.nim
+++ b/tests/tnimterop_c.nim
@@ -33,6 +33,7 @@ var
s3: STRUCT3
s4: STRUCT4
s5: STRUCT5
+ s51: struct5
e: ENUM
e2: ENUM2 = enum5
@@ -62,7 +63,9 @@ else: # TODO: what's `defined(cpp)` for c ?
s5.tci = test_call_int
s5.tcp = test_call_param
s5.tcp8 = test_call_param8
+s51.tci = test_call_int
check s5.tci() == 5
+check s51.tci() == 5
e = enum1
e2 = enum4