Files
llgo/internal/cabi/_testdata/make.go

320 lines
6.9 KiB
Go

//go:build ignore
// +build ignore
package main
import (
"bytes"
"os"
"path/filepath"
"strconv"
"strings"
)
var ghead_basic = `package main
import "unsafe"
const (
LLGoFiles = "../wrap/basic.c"
)
type pointer = *int8
//go:linkname printf C.printf
func printf(format *byte, __llgo_va_list ...any) int32
func assert(info string, b bool) {
if !b {
printf(unsafe.StringData("Assertion failed: %s\n\000"), unsafe.StringData(info))
}
}
func main() {
}
`
var gbasic = `
//go:linkname cbasic C.basic
func cbasic(a int) int
func basic(a int) int {
return a
}
func init() {
assert("cbasic\000", cbasic(100) == 100)
assert("basic\000", basic(100) == 100)
}
`
var gbasic_pointer = `
//go:linkname cbasic_pointer C.basic_pointer
func cbasic_pointer(a pointer) pointer
func basic_pointer(a pointer) pointer {
return a
}
func init() {
var p int8
assert("cbasic_pointer\000", cbasic_pointer(&p) == &p)
assert("basic_pointer\000", basic_pointer(&p) == &p)
}
`
var garray = `
type array struct {
x [N]int
}
//go:linkname cdemo C.demo
func cdemo(a array) array
func demo(a array) array {
return a
}
func init() {
a := array{x: [N]int{M}}
assert("cdemo\000", cdemo(a) == a)
assert("demo\000", demo(a) == a)
}
`
var gstruct = `
type point struct {
x int
}
//go:linkname cdemo C.demo
func cdemo(a point) point
func demo(a point) point {
return a
}
func init() {
a := point{M}
assert("cdemo\000", cdemo(a) == a)
assert("demo\000", demo(a) == a)
}
`
var cbasic = `
int basic(int a) {
return a;
}
`
var carray = `
struct array {
int x[N];
};
struct array demo(struct array a) {
return a;
}
`
var cstruct = `
struct point {
int x;
};
struct point demo(struct point a) {
return a;
}
`
func main() {
// char
// short
// int
// int*
// float
// double
// 1 2 3 4 5 6 7 8
types := []string{"char", "short", "int", "long long", "float", "double", "void*"}
ids := []string{"int8", "int16", "int32", "int64", "float32", "float64", "pointer"}
idTypes := make(map[string]string)
for i, id := range ids {
idTypes[id] = types[i]
}
// write cbasic
var cbuf bytes.Buffer
for nid, id := range ids {
data := strings.NewReplacer("int", types[nid], "basic", "basic_"+id).Replace(cbasic)
cbuf.WriteString(data)
}
os.WriteFile("./wrap/basic.c", cbuf.Bytes(), 0666)
// write go basic
var buf bytes.Buffer
buf.WriteString(ghead_basic)
for _, id := range ids {
data := strings.NewReplacer("int", id, "basic", "basic_"+id).Replace(gbasic)
if id == "pointer" {
data = gbasic_pointer
}
buf.WriteString(data)
}
os.WriteFile("./demo/basic.go", buf.Bytes(), 0666)
// write c array
for nid, id := range ids {
f := filepath.Join("./wrap/array_" + id + ".c")
var buf bytes.Buffer
for i := 0; i < 20; i++ {
N := strconv.Itoa(i + 1)
data := strings.NewReplacer("int", types[nid], "N", N,
"array", "array"+N, "demo", "demo"+N).Replace(carray)
buf.WriteString(data)
}
os.WriteFile(f, buf.Bytes(), 0666)
}
// write c struct
for nid, id := range ids {
f := filepath.Join("./wrap/struct_" + id + ".c")
var buf bytes.Buffer
for i := 0; i < 20; i++ {
N := strconv.Itoa(i + 1)
ar := make([]string, i+1)
for j := 0; j < i+1; j++ {
ar[j] = types[nid] + " x" + strconv.Itoa(j) + ";"
}
data := strings.NewReplacer("int x;", strings.Join(ar, "\n\t"), "N", N,
"point", "point"+N, "demo", "demo"+N).Replace(cstruct)
buf.WriteString(data)
}
os.WriteFile(f, buf.Bytes(), 0666)
}
// write go array
for _, id := range ids {
f := filepath.Join("./demo/array_" + id + ".go")
var buf bytes.Buffer
buf.WriteString(strings.Replace(ghead_basic, "basic", "array_"+id, -1))
for i := 0; i < 20; i++ {
N := strconv.Itoa(i + 1)
M := make([]string, i+1)
if id == "pointer" {
for j := 0; j < i+1; j++ {
M[j] = "func() pointer { var a int8 = " + strconv.Itoa(j+1) + "; return &a}()"
}
} else {
for j := 0; j < i+1; j++ {
M[j] = strconv.Itoa(j + 1)
}
}
data := strings.NewReplacer("int", id, "N", N, "M", strings.Join(M, ", "),
"array", "array"+N, "demo", "demo"+N).Replace(garray)
buf.WriteString(data)
}
os.WriteFile(f, buf.Bytes(), 0666)
}
// write go struct
for _, id := range ids {
f := filepath.Join("./demo/struct_" + id + ".go")
var buf bytes.Buffer
buf.WriteString(strings.Replace(ghead_basic, "basic", "struct_"+id, -1))
for i := 0; i < 20; i++ {
N := strconv.Itoa(i + 1)
M := make([]string, i+1)
if id == "pointer" {
for j := 0; j < i+1; j++ {
M[j] = "func() pointer { var a int8 = " + strconv.Itoa(j+1) + "; return &a}()"
}
} else {
for j := 0; j < i+1; j++ {
M[j] = strconv.Itoa(j + 1)
}
}
ar := make([]string, i+1)
for j := 0; j < i+1; j++ {
ar[j] = "x" + strconv.Itoa(j) + " " + id
}
data := strings.NewReplacer("x int", strings.Join(ar, "\n\t"), "N", N, "M", strings.Join(M, ", "),
"point", "point"+N, "demo", "demo"+N).Replace(gstruct)
buf.WriteString(data)
}
os.WriteFile(f, buf.Bytes(), 0666)
}
var mixeds []string
for _, id1 := range ids {
for _, id2 := range ids {
if id1 == id2 {
continue
}
mixeds = append(mixeds, id1+","+id2)
}
}
ids2 := []string{"int8", "int16", "int32", "float32"}
for _, id1 := range ids2 {
for _, id2 := range ids2 {
if id1 == id2 {
continue
}
for _, id3 := range ids2 {
if id1 == id2 && id2 == id3 {
continue
}
mixeds = append(mixeds, id1+","+id2+","+id3)
for _, id4 := range ids2 {
if id1 == id2 && id2 == id3 && id3 == id4 {
continue
}
mixeds = append(mixeds, id1+","+id2+","+id3+","+id4)
for _, id5 := range ids2 {
if id1 == id2 && id2 == id3 && id3 == id4 && id4 == id5 {
continue
}
mixeds = append(mixeds, id1+","+id2+","+id3+","+id4+","+id5)
}
}
}
}
}
// write c mixed
cbuf.Reset()
for i, mixed := range mixeds {
N := strconv.Itoa(i + 1)
ids := strings.Split(mixed, ",")
ar := make([]string, len(ids))
for j, id := range ids {
ar[j] = idTypes[id] + " x" + strconv.Itoa(j) + ";"
}
data := strings.NewReplacer("int x;", strings.Join(ar, "\n\t"), "N", N,
"point", "point"+N, "demo", "demo"+N).Replace(cstruct)
cbuf.WriteString(data)
}
os.WriteFile("./wrap/struct_mixed.c", cbuf.Bytes(), 0666)
// write go mixed
buf.Reset()
buf.WriteString(strings.Replace(ghead_basic, "basic", "struct_mixed", -1))
for i, mixed := range mixeds {
N := strconv.Itoa(i + 1)
ids := strings.Split(mixed, ",")
ar := make([]string, len(ids))
for j, id := range ids {
ar[j] = "x" + strconv.Itoa(j) + " " + id
}
M := make([]string, len(ids))
for j := 0; j < len(ids); j++ {
if ids[j] == "pointer" {
M[j] = "func() pointer { var a int8 = " + strconv.Itoa(j+1) + "; return &a}()"
} else {
M[j] = strconv.Itoa(j + 1)
}
}
data := strings.NewReplacer("x int", strings.Join(ar, "\n\t"), "N", N, "M", strings.Join(M, ", "),
"point", "point"+N, "demo", "demo"+N).Replace(gstruct)
buf.WriteString(data)
}
os.WriteFile("./demo/struct_mixed.go", buf.Bytes(), 0666)
}