@@ -19,9 +19,6 @@ func generateGo(src *mkcgo.Source, w io.Writer) {
19
19
// This block outputs C header includes and forward declarations for loader functions.
20
20
fmt .Fprintf (w , "/*\n " )
21
21
fmt .Fprintf (w , "#cgo CFLAGS: -Wno-attributes\n \n " )
22
- for _ , file := range src .Files {
23
- fmt .Fprintf (w , "#include %q\n " , file )
24
- }
25
22
if * includeHeader != "" {
26
23
fmt .Fprintf (w , "#include \" %s\" \n " , * includeHeader )
27
24
}
@@ -39,10 +36,10 @@ func generateGo(src *mkcgo.Source, w io.Writer) {
39
36
// Generate Go wrapper functions that load and unload the C symbols.
40
37
for _ , tag := range src .Tags () {
41
38
fmt .Fprintf (w , "func mkcgoLoad_%s(handle unsafe.Pointer) {\n " , tag )
42
- fmt .Fprintf (w , "\t C.__mkcgoLoad_ %s(handle)\n " , tag )
39
+ fmt .Fprintf (w , "\t C.__mkcgo_load_ %s(handle)\n " , tag )
43
40
fmt .Fprintf (w , "}\n \n " )
44
41
fmt .Fprintf (w , "func mkcgoUnload_%s() {\n " , tag )
45
- fmt .Fprintf (w , "\t C.__mkcgoUnload_ %s()\n " , tag )
42
+ fmt .Fprintf (w , "\t C.__mkcgo_unload_ %s()\n " , tag )
46
43
fmt .Fprintf (w , "}\n \n " )
47
44
}
48
45
@@ -57,14 +54,13 @@ func generateGo(src *mkcgo.Source, w io.Writer) {
57
54
58
55
// Generate function wrappers.
59
56
for _ , fn := range src .Funcs {
60
- if fn .Variadic () {
61
- // cgo doesn't support variadic functions
57
+ if ! fnCalledFromGo (fn ) {
62
58
continue
63
59
}
64
60
if fn .Optional {
65
61
// Generate a function that returns true if the function is available.
66
- fmt .Fprintf (w , "func %s_Available () bool {\n " , fn . GoName )
67
- fmt .Fprintf (w , "\t return C.%s_Available () != 0\n " , fn . ImportName )
62
+ fmt .Fprintf (w , "func %s () bool {\n " , fnGoNameAvailable ( fn ) )
63
+ fmt .Fprintf (w , "\t return C.%s () != 0\n " , fnCNameAvailable ( fn ) )
68
64
fmt .Fprintf (w , "}\n \n " )
69
65
}
70
66
generateGoFn (fn , w )
@@ -81,10 +77,7 @@ func generateGo124(src *mkcgo.Source, w io.Writer) {
81
77
// This block outputs C header includes and forward declarations for loader functions.
82
78
fmt .Fprintf (w , "/*\n " )
83
79
for _ , fn := range src .Funcs {
84
- name := fn .CName
85
- if fnNeedErrWrapper (fn ) {
86
- name = fnCErrWrapperName (fn )
87
- }
80
+ name := fnCName (fn )
88
81
if fn .NoEscape {
89
82
fmt .Fprintf (w , "#cgo noescape %s\n " , name )
90
83
}
@@ -155,13 +148,26 @@ func generateCHeader(src *mkcgo.Source, w io.Writer) {
155
148
fmt .Fprintf (w , "#ifndef MKCGO_H // only include this header once\n " )
156
149
fmt .Fprintf (w , "#define MKCGO_H\n \n " )
157
150
158
- for _ , file := range src .Files {
159
- fmt .Fprintf (w , "#include %q\n " , file )
160
- }
161
151
if * includeHeader != "" {
162
- fmt .Fprintf (w , "#include \" %s\" \n " , * includeHeader )
152
+ fmt .Fprintf (w , "#include %q\n \n " , * includeHeader )
153
+ }
154
+
155
+ // Source includes.
156
+ for _ , v := range src .Includes {
157
+ fmt .Fprintf (w , "#include %s\n " , v )
158
+ }
159
+ fmt .Fprintf (w , "\n " )
160
+
161
+ // Source types and enums.
162
+ for _ , def := range src .TypeDefs {
163
+ fmt .Fprintf (w , "typedef %s %s;\n " , def .Type , def .Name )
163
164
}
164
165
fmt .Fprintf (w , "\n " )
166
+ fmt .Fprintf (w , "enum {\n " )
167
+ for _ , enum := range src .Enums {
168
+ fmt .Fprintf (w , "\t %s = %s,\n " , enum .Name , enum .Value )
169
+ }
170
+ fmt .Fprintf (w , "};\n \n " )
165
171
166
172
// Custom types
167
173
fmt .Fprintf (w , "typedef void* %s;\n " , mkcgoErrState )
@@ -171,25 +177,30 @@ func generateCHeader(src *mkcgo.Source, w io.Writer) {
171
177
172
178
// Add forward declarations for loader functions.
173
179
for _ , tag := range src .Tags () {
174
- fmt .Fprintf (w , "void __mkcgoLoad_ %s(void* handle);\n " , tag )
175
- fmt .Fprintf (w , "void __mkcgoUnload_ %s();\n " , tag )
180
+ fmt .Fprintf (w , "void __mkcgo_load_ %s(void* handle);\n " , tag )
181
+ fmt .Fprintf (w , "void __mkcgo_unload_ %s();\n " , tag )
176
182
}
177
183
fmt .Fprintf (w , "\n " )
178
184
179
185
// Add forward declarations for optional functions.
180
186
for _ , fn := range src .Funcs {
181
187
if fn .Optional {
182
- fmt .Fprintf (w , "int %s_Available ();\n " , fn . ImportName )
188
+ fmt .Fprintf (w , "int %s ();\n " , fnCNameAvailable ( fn ) )
183
189
}
184
190
}
185
191
fmt .Fprintf (w , "\n " )
186
192
187
193
// Add forward declarations for function wrappers returning errors.
188
194
for _ , fn := range src .Funcs {
189
- if ! fnNeedErrWrapper (fn ) {
195
+ if ! fnCalledFromGo (fn ) {
196
+ // cgo doesn't support variadic functions, no need to include them.
190
197
continue
191
198
}
192
- fmt .Fprintf (w , "%s %s(%s);\n " , fn .Ret .Type , fnCErrWrapperName (fn ), fnCErrWrapperParams (fn , false ))
199
+ if fnNeedErrWrapper (fn ) {
200
+ fmt .Fprintf (w , "%s %s(%s);\n " , fn .Ret .Type , fnCName (fn ), fnCErrWrapperParams (fn , false ))
201
+ } else {
202
+ fmt .Fprintf (w , "%s %s(%s);\n " , fn .Ret .Type , fnCName (fn ), fnToCArgs (fn , true , false ))
203
+ }
193
204
}
194
205
fmt .Fprintf (w , "\n " )
195
206
fmt .Fprintf (w , "#endif // MKCGO_H\n " )
@@ -204,11 +215,8 @@ func generateC(src *mkcgo.Source, w io.Writer) {
204
215
fmt .Fprintf (w , "#include <stdlib.h>\n " )
205
216
fmt .Fprintf (w , "#include <stdint.h>\n " )
206
217
fmt .Fprintf (w , "#include <stdio.h>\n " )
207
- for _ , file := range src .Files {
208
- fmt .Fprintf (w , "#include %q\n " , file )
209
- }
210
218
if * includeHeader != "" {
211
- fmt .Fprintf (w , "#include \" %s \" \n " , * includeHeader )
219
+ fmt .Fprintf (w , "#include %q \n " , * includeHeader )
212
220
}
213
221
fmt .Fprintf (w , "#include \" %s\" \n " , autogeneratedFileName (".h" ))
214
222
fmt .Fprintf (w , "\n " )
@@ -222,12 +230,11 @@ func generateC(src *mkcgo.Source, w io.Writer) {
222
230
fmt .Fprintf (w , "#endif\n \n " )
223
231
224
232
// Function pointer declarations.
225
- fmt .Fprintf (w , "#define __mkcgo__funcptr(name) typeof(name) *_g_##name;\n \n " )
226
233
for _ , fn := range src .Funcs {
227
234
if fn .VariadicInst {
228
235
continue
229
236
}
230
- fmt .Fprintf (w , "__mkcgo__funcptr( %s);\n " , fn .ImportName )
237
+ fmt .Fprintf (w , "%s (*_g_ %s)(%s) ;\n " , fn .Ret . Type , fn . ImportName , fnToCArgs ( fn , true , false ) )
231
238
}
232
239
fmt .Fprintf (w , "\n " )
233
240
@@ -242,7 +249,7 @@ func generateC(src *mkcgo.Source, w io.Writer) {
242
249
243
250
// Loader and unloader functions for each tag.
244
251
for _ , tag := range src .Tags () {
245
- fmt .Fprintf (w , "void __mkcgoLoad_ %s(void* handle) {\n " , tag )
252
+ fmt .Fprintf (w , "void __mkcgo_load_ %s(void* handle) {\n " , tag )
246
253
for _ , fn := range src .Funcs {
247
254
if fn .VariadicInst {
248
255
continue
@@ -267,7 +274,7 @@ func generateC(src *mkcgo.Source, w io.Writer) {
267
274
}
268
275
fmt .Fprintf (w , "}\n \n " )
269
276
270
- fmt .Fprintf (w , "void __mkcgoUnload_ %s() {\n " , tag )
277
+ fmt .Fprintf (w , "void __mkcgo_unload_ %s() {\n " , tag )
271
278
for _ , fn := range src .Funcs {
272
279
if fn .VariadicInst {
273
280
continue
@@ -292,26 +299,25 @@ func generateC(src *mkcgo.Source, w io.Writer) {
292
299
typedefs [def .Name ] = def .Type
293
300
}
294
301
for _ , fn := range src .Funcs {
295
- if fn . Variadic ( ) {
296
- // cgo doesn't support variadic functions
302
+ if ! fnCalledFromGo ( fn ) {
303
+ // cgo doesn't support variadic functions, no need to include them.
297
304
continue
298
305
}
299
306
if fn .Optional {
300
307
// Generate a function that returns true if the function is available.
301
- fmt .Fprintf (w , "int %s_Available () {\n " , fn . CName )
308
+ fmt .Fprintf (w , "int %s () {\n " , fnCNameAvailable ( fn ) )
302
309
fmt .Fprintf (w , "\t return _g_%s != NULL;\n " , fn .ImportName )
303
310
fmt .Fprintf (w , "}\n \n " )
304
311
}
305
- generateCFn (fn , w )
306
- generateCFnErrorWrapper (typedefs , fn , w )
312
+ generateCFn (typedefs , fn , w )
307
313
}
308
314
}
309
315
310
316
// generateGoFn generates Go function f.
311
317
func generateGoFn (fn * mkcgo.Func , w io.Writer ) {
312
- fnCall := fmt .Sprintf ("C.%s(%s)" , fn . CName , fnToGoArgs (fn ))
318
+ fnCall := fmt .Sprintf ("C.%s(%s)" , fnCName ( fn ) , fnToGoArgs (fn ))
313
319
// Function definition
314
- fmt .Fprintf (w , "func %s(%s)" , fn . GoName , fnToGoParams (fn ))
320
+ fmt .Fprintf (w , "func %s(%s)" , fnGoName ( fn ) , fnToGoParams (fn ))
315
321
if retIsVoid (fn .Ret ) {
316
322
// Easy path, just call the C function. No need to write the return types,
317
323
// nor do error handling, nor cast the return value.
@@ -320,17 +326,16 @@ func generateGoFn(fn *mkcgo.Func, w io.Writer) {
320
326
fmt .Fprintf (w , "}\n \n " )
321
327
return
322
328
}
323
- typ , _ := cTypeToGo (fn .Ret .Type , false )
329
+ goType , needCast := cTypeToGo (fn .Ret .Type , false )
324
330
if fn .NoError {
325
- fmt .Fprintf (w , " %s " , typ )
331
+ fmt .Fprintf (w , " %s " , goType )
326
332
} else {
327
- fmt .Fprintf (w , " (%s, error) " , typ )
333
+ fmt .Fprintf (w , " (%s, error) " , goType )
328
334
}
329
335
fmt .Fprintf (w , "{\n " )
330
336
331
337
// Function call
332
338
var needUnsafeCast bool
333
- goType , needCast := cTypeToGo (fn .Ret .Type , false )
334
339
if needCast && goType [0 ] == '*' {
335
340
goType = fmt .Sprintf ("(%s)(unsafe.Pointer" , goType )
336
341
needUnsafeCast = true
@@ -351,7 +356,7 @@ func generateGoFn(fn *mkcgo.Func, w io.Writer) {
351
356
return
352
357
}
353
358
fmt .Fprintf (w , "\t var _err C.%s\n " , mkcgoErrState )
354
- fmt .Fprintf (w , "\t _ret := C.%s(" , fnCErrWrapperName (fn ))
359
+ fmt .Fprintf (w , "\t _ret := C.%s(" , fnCName (fn ))
355
360
args := fnToGoArgs (fn )
356
361
if len (args ) > 0 {
357
362
args += ", "
@@ -368,26 +373,22 @@ func generateGoFn(fn *mkcgo.Func, w io.Writer) {
368
373
} else {
369
374
fmt .Fprintf (w , "_ret" )
370
375
}
371
- fmt .Fprintf (w , ", newMkcgoErr(%q, _err)\n " , fn .CName )
372
- fmt .Fprintf (w , "}\n \n " )
373
- }
374
-
375
- func generateCFn (fn * mkcgo.Func , w io.Writer ) {
376
- fmt .Fprintf (w , "%s %s(%s) {\n \t " , fn .Ret .Type , fn .CName , fnToCArgs (fn , true , true ))
377
- if ! retIsVoid (fn .Ret ) {
378
- fmt .Fprintf (w , "return " )
379
- }
380
- fmt .Fprintf (w , "_g_%s(%s);\n " , fn .ImportName , fnToCArgs (fn , false , true ))
376
+ fmt .Fprintf (w , ", newMkcgoErr(%q, _err)\n " , fn .Name )
381
377
fmt .Fprintf (w , "}\n \n " )
382
378
}
383
379
384
- // generateCFnErrorWrapper generates C function wrapper for function f
385
- // that returns an error state.
386
- func generateCFnErrorWrapper (typedefs map [string ]string , fn * mkcgo.Func , w io.Writer ) {
380
+ func generateCFn (typedefs map [string ]string , fn * mkcgo.Func , w io.Writer ) {
387
381
if ! fnNeedErrWrapper (fn ) {
382
+ fmt .Fprintf (w , "%s %s(%s) {\n \t " , fn .Ret .Type , fnCName (fn ), fnToCArgs (fn , true , true ))
383
+ if ! retIsVoid (fn .Ret ) {
384
+ fmt .Fprintf (w , "return " )
385
+ }
386
+ fmt .Fprintf (w , "_g_%s(%s);\n " , fn .ImportName , fnToCArgs (fn , false , true ))
387
+ fmt .Fprintf (w , "}\n \n " )
388
388
return
389
389
}
390
- fmt .Fprintf (w , "%s %s(%s) {\n " , fn .Ret .Type , fnCErrWrapperName (fn ), fnCErrWrapperParams (fn , true ))
390
+
391
+ fmt .Fprintf (w , "%s %s(%s) {\n " , fn .Ret .Type , fnCName (fn ), fnCErrWrapperParams (fn , true ))
391
392
fmt .Fprintf (w , "\t mkcgo_err_clear();\n " ) // clear any previous error
392
393
fmt .Fprintf (w , "\t %s _ret = _g_%s(%s);\n " , fn .Ret .Type , fn .ImportName , fnToCArgs (fn , false , true ))
393
394
errCond := "<= 0"
@@ -506,7 +507,7 @@ func cTypeToGo(t string, cgo bool) (string, bool) {
506
507
// paramToC returns C source code of parameter p.
507
508
func paramToC (i int , p * mkcgo.Param , addType , addName bool ) string {
508
509
if p .Type == "..." {
509
- return ""
510
+ return "... "
510
511
}
511
512
var s string
512
513
if addType {
@@ -585,12 +586,33 @@ func fnCErrWrapperParams(fn *mkcgo.Func, addName bool) string {
585
586
return args
586
587
}
587
588
588
- // fnCErrWrapperName returns the name of the error wrapper function for function f.
589
- func fnCErrWrapperName (fn * mkcgo.Func ) string {
590
- return "_mkcgo_err_" + fn .CName
589
+ // fnGoName returns the Go function name for function f.
590
+ func fnGoName (fn * mkcgo.Func ) string {
591
+ // TODO: use a prefix that is not OpenSSL specific.
592
+ return "go_openssl_" + fn .Name
593
+ }
594
+
595
+ func fnGoNameAvailable (fn * mkcgo.Func ) string {
596
+ return fnGoName (fn ) + "_Available"
597
+ }
598
+
599
+ // fnCName returns the C function name for function f.
600
+ func fnCName (fn * mkcgo.Func ) string {
601
+ return "_mkcgo_" + fn .Name
602
+ }
603
+
604
+ // fnCNameAvailable returns the C function name for function f
605
+ // that checks if the function is available.
606
+ func fnCNameAvailable (fn * mkcgo.Func ) string {
607
+ return "_mkcgo_available_" + fn .Name
591
608
}
592
609
593
610
// fnNeedErrWrapper reports whether function fn needs an error wrapper.
594
611
func fnNeedErrWrapper (fn * mkcgo.Func ) bool {
595
612
return ! fn .NoError && ! retIsVoid (fn .Ret )
596
613
}
614
+
615
+ // fnCalledFromGo reports whether function fn is called from Go code.
616
+ func fnCalledFromGo (fn * mkcgo.Func ) bool {
617
+ return ! fn .Variadic () // cgo doesn't support variadic functions
618
+ }
0 commit comments