aboutsummaryrefslogtreecommitdiff
path: root/tests/tnimterop_c.nim
blob: c577c5d3e6b7067c120c1ae0e0b47e5cd8b34a27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
import std/unittest
import nimterop/cimport
import nimterop/paths

static:
  cDebug()
  cDisableCaching()
  cAddSearchDir testsIncludeDir()

cDefine("FORCE")
cIncludeDir testsIncludeDir()
cCompile cSearchPath("test.c")

cPlugin:
  import strutils

  proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} =
    if sym.name == "_Kernel":
      sym.name = "uKernel"
    else:
      sym.name = sym.name.strip(chars={'_'})

cOverride:
  type
    BITMAPINFOHEADER* {.bycopy.} = object
      biClrImportant*: int

    Random = object

    ABC = pointer

    GHI = object
      f2: ptr ptr cint

    JKL = object
      f2: ptr ptr cint

  const
    BIT* = 1

  proc weirdfunc(apple: ptr ptr ptr cchar): int {.importc.}
  proc weirdfunc2(mango: ptr ptr cchar): int {.importc.}

cImport cSearchPath "test.h"

check TEST_INT == 512
check TEST_FLOAT == 5.12
check TEST_HEX == 0x512
check TEST_CHAR == 'a'
check TEST_STR == "hello world"

when defined(osx):
  check OSDEF == 10
elif defined(windows):
  check OSDEF == 20
else:
  check OSDEF == 30

block:
  # workaround for https://github.com/nim-lang/Nim/issues/10129
  const ok = OSDEF

var
  pt: PRIMTYPE
  ct: CUSTTYPE
  cct: CCUSTTYPE

  s0: STRUCT0
  s1: STRUCT1
  s2: STRUCT2
  s3: STRUCT3
  s4: STRUCT4
  s5: STRUCT5
  s51: struct5

  e: ENUM
  e2: ENUM2 = enum5
  e3: Enum_testh1 = enum7
  e4: ENUM4 = enum11

  vptr: VOIDPTR
  iptr: INTPTR

  u: UNION1
  u2: UNION2

  i: cint

pt = 3
ct = 4
cct = 5

s1.field1 = 5
s2.field1 = 6
s3.field1 = 7
s4.field2[2] = 5

# note: simplify with `defined(c)` for nim >= 0.19.9
when defined(cpp) and defined(OSX):
  discard
else:
  s4.field3[3] = enum1

s4.field6 = 1
s4.field6 += 1
check s4.field6 == 0

s5.tci = test_call_int
s5.tcp = test_call_param
s5.tcp8 = test_call_param8
s51.tci = test_call_int
s51.tcv = test_call9
check s5.tci() == 5
check s51.tci() == 5
check s51.tcv() == nil

e = enum1
e2 = enum4

u2.field2 = 'c'

i = 5

check test_call_int() == 5
check test_call_param(5).field1 == 5
check test_call_param2(5, s2).field1 == 11
check test_call_param3(5, s1).field1 == 10
when defined(cpp) and defined(OSX):
  # error: assigning to 'enum ENUM' from incompatible type 'NI' (aka 'long long')
  discard
else:
  check test_call_param4(e) == e2
check test_call_param5(5.0).field2 == 5.0
check test_call_param6(u2) == 'c'
u.field1 = 4
check test_call_param7(u) == 4

when defined(cpp) and defined(OSX):
   # note: candidate function not viable: no known conversion from 'NI *' (aka 'long long *') to 'int *' for 1st argument
  # check test_call_param8(cast[ptr int](addr i)) == 25.0
  discard
else:
  check test_call_param8(addr i) == 25.0
  check i == 25

check test_call9() == nil

check enum6a == 4
check enum6b == 5

check e3 == enum7
check e4 == enum11

check enum13 == 4
check enum14 == 9
check enum15 == 2
check enum17 == '\0'.ENUM7
check enum18 == 'A'.ENUM7

# Issue #58
multiline1()
let p = multiline2()
multiline3()

# Issue #52
var
  s6: struct6
  s6p: STRUCT6
  e6: enum6t
  e6p: ENUM6
  u3: union3
  u3p: UNION3
  k: uKernel
  kp: Kernel

## failing tests
when false:
  static: # Error: undeclared identifier: 'foobar1'
    doAssert foobar1(3) == OSDEF * 3
when false: # Error: undeclared identifier: 'foobar2'
    doAssert foobar2(3) == 3 + 1

# Double pointer
var
  dv: DVOIDPTR
  di: DINTPTR
  ds: dstruct
  cstr = "Hello".cstring
  ds2: DSTRUCT2

dv = addr vptr
di = addr iptr

ds.field1 = di
ds2.field1 = addr cstr
ds2.tcv = test_call10
check ds2.tcv(di) == nil

# Issue #131
check TDEFL_OUT_BUF_SIZE == 85196
check TDEFL_BOGUS_1 == 2
check TDEFL_BOGUS_2 == 1024
check TDEFL_BOGUS_3 == (85196 / 2).int

var
  arr: array[5, cint]

check test_array_param(arr) == nil

# cOverride

var
  ca = weirdfunc
  cb: BITMAPINFOHEADER
  cc = weirdfunc2
  cd: ABC
  ce: DEF
  cf: GHI
  cg: JKL

cd = nil
ce = 5
cf.f2 = nil
cg.f2 = nil

doAssert BIT == 1
doAssert ca(nil) == 1
doAssert cc(nil) == 2