bind: make sure GODEBUG=cgocheck=0 for Go>=1.6

This commit is contained in:
Dong-hee Na 2017-05-06 16:00:07 +00:00
parent ae2cdaa5cd
commit 633184e998
3 changed files with 96 additions and 1 deletions

View File

@ -8,10 +8,40 @@ import (
"fmt"
"go/token"
"go/types"
"runtime"
"strings"
)
const (
checkGoVersionImport = `"strconv"
"strings"
"os"
`
checkGoVersion= "_cgopy_CheckGoVersion()"
checkGoVersionDef = `
func _cgopy_CheckGoVersion() {
godebug := os.Getenv("GODEBUG")
cgocheck := -1
var err error
if godebug != "" {
const prefix = "cgocheck="
for _, option := range strings.Split(godebug, ",") {
if !strings.HasPrefix(option, prefix) {
continue
}
cgocheck, err = strconv.Atoi(option[len(prefix):])
if err != nil {
cgocheck = -1
fmt.Fprintf(os.Stderr, "gopy: invalid cgocheck value %q (expected an integer)\n", option)
}
}
}
if cgocheck != 0 {
fmt.Fprintf(os.Stderr, "gopy: GODEBUG=cgocheck=0 should be set for Go>=1.6\n")
}
}
`
goPreamble = `// Package main is an autogenerated binder stub for package %[1]s.
// gopy gen -lang=go %[1]s
//
@ -30,6 +60,8 @@ import (
"unsafe"
%[3]s
%[4]s
)
var _ = unsafe.Pointer(nil)
@ -111,7 +143,10 @@ func cgopy_decref(ptr unsafe.Pointer) {
refs.Unlock()
}
%[5]s
func init() {
%[6]s
refs.Lock()
refs.next = -24 // Go objects get negative reference numbers. Arbitrary starting point.
refs.refs = make(map[unsafe.Pointer]int32)
@ -969,7 +1004,13 @@ func (g *goGen) genPreamble() {
panic(err)
}
g.Printf(goPreamble, n, pkgcfg, pkgimport)
version := runtime.Version()
major, minor, _ := getGoVersion(version)
if major >= 1 && minor >= 6 {
g.Printf(goPreamble, n, pkgcfg, pkgimport, checkGoVersionImport, checkGoVersionDef, checkGoVersion)
} else {
g.Printf(goPreamble, n, pkgcfg, pkgimport, "", "", "")
}
}
func (g *goGen) tupleString(tuple []*Var) string {

View File

@ -13,6 +13,8 @@ import (
"os/exec"
"regexp"
"sort"
"strconv"
"strings"
)
func isErrorType(typ types.Type) bool {
@ -148,3 +150,15 @@ func getPkgConfig(vers int) (string, error) {
return pkgcfg, nil
}
func getGoVersion(version string) (int64, int64, error) {
version_regex := regexp.MustCompile(`^go((\d+)(\.(\d+))*)`)
match := version_regex.FindStringSubmatch(version)
if match == nil {
return -1, -1, fmt.Errorf("gopy: invalid Go version information: %q", version)
}
version_info := strings.Split(match[1], ".")
major, _ := strconv.ParseInt(version_info[0], 10, 0)
minor, _ := strconv.ParseInt(version_info[1], 10, 0)
return major, minor, nil
}

40
bind/utils_test.go Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2017 The go-python Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bind
import (
"errors"
"testing"
)
func TestGetGoVersion(t *testing.T) {
for _, tt := range []struct {
info string
major int64
minor int64
err error
}{
{"go1.5", 1, 5, nil},
{"go1.6", 1, 6, nil},
{"go1.7", 1, 7, nil},
{"go1.8", 1, 8, nil},
{"gcc4", -1, -1, errors.New("gopy: invalid Go version information: \"gcc4\"")},
{"1.8go", -1, -1, errors.New("gopy: invalid Go version information: \"1.8go\"")},
{"llvm", -1, -1, errors.New("gopy: invalid Go version information: \"llvm\"")},
} {
major, minor, err := getGoVersion(tt.info)
if major != tt.major {
t.Errorf("getGoVersion(%s): expected major %d, actual %d", tt.info, tt.major, major)
}
if minor != tt.minor {
t.Errorf("getGoVersion(%s): expected major %d, actual %d", tt.info, tt.minor, minor)
}
if err != nil && err.Error() != tt.err.Error() {
t.Errorf("getGoVersion(%s): expected err %s, actual %s", tt.info, tt.err, err)
}
}
}