github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/misc/cgo/test/basic.go (about)

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Basic test cases for cgo.
     6  
     7  package cgotest
     8  
     9  /*
    10  #include <stdio.h>
    11  #include <stdlib.h>
    12  #include <sys/stat.h>
    13  #include <errno.h>
    14  
    15  #define SHIFT(x, y)  ((x)<<(y))
    16  #define KILO SHIFT(1, 10)
    17  #define UINT32VAL 0xc008427bU
    18  
    19  enum E {
    20  	Enum1 = 1,
    21  	Enum2 = 2,
    22  };
    23  
    24  typedef unsigned char cgo_uuid_t[20];
    25  
    26  void uuid_generate(cgo_uuid_t x) {
    27  	x[0] = 0;
    28  }
    29  
    30  struct S {
    31  	int x;
    32  };
    33  
    34  const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    35  
    36  extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
    37  
    38  enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
    39  
    40  // issue 1222
    41  typedef union {
    42  	long align;
    43  } xxpthread_mutex_t;
    44  
    45  struct ibv_async_event {
    46  	union {
    47  		int x;
    48  	} element;
    49  };
    50  
    51  struct ibv_context {
    52  	xxpthread_mutex_t mutex;
    53  };
    54  
    55  int add(int x, int y) {
    56  	return x+y;
    57  };
    58  */
    59  import "C"
    60  import (
    61  	"runtime"
    62  	"syscall"
    63  	"testing"
    64  	"unsafe"
    65  )
    66  
    67  const EINVAL = C.EINVAL /* test #define */
    68  
    69  var KILO = C.KILO
    70  
    71  func uuidgen() {
    72  	var uuid C.cgo_uuid_t
    73  	C.uuid_generate(&uuid[0])
    74  }
    75  
    76  func Strtol(s string, base int) (int, error) {
    77  	p := C.CString(s)
    78  	n, err := C.strtol(p, nil, C.int(base))
    79  	C.free(unsafe.Pointer(p))
    80  	return int(n), err
    81  }
    82  
    83  func Atol(s string) int {
    84  	p := C.CString(s)
    85  	n := C.atol(p)
    86  	C.free(unsafe.Pointer(p))
    87  	return int(n)
    88  }
    89  
    90  func testConst(t *testing.T) {
    91  	C.myConstFunc(nil, 0, nil)
    92  }
    93  
    94  func testEnum(t *testing.T) {
    95  	if C.Enum1 != 1 || C.Enum2 != 2 {
    96  		t.Error("bad enum", C.Enum1, C.Enum2)
    97  	}
    98  }
    99  
   100  func testAtol(t *testing.T) {
   101  	l := Atol("123")
   102  	if l != 123 {
   103  		t.Error("Atol 123: ", l)
   104  	}
   105  }
   106  
   107  func testErrno(t *testing.T) {
   108  	p := C.CString("no-such-file")
   109  	m := C.CString("r")
   110  	f, err := C.fopen(p, m)
   111  	C.free(unsafe.Pointer(p))
   112  	C.free(unsafe.Pointer(m))
   113  	if err == nil {
   114  		C.fclose(f)
   115  		t.Fatalf("C.fopen: should fail")
   116  	}
   117  	if err != syscall.ENOENT {
   118  		t.Fatalf("C.fopen: unexpected error: %v", err)
   119  	}
   120  }
   121  
   122  func testMultipleAssign(t *testing.T) {
   123  	p := C.CString("234")
   124  	n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10)
   125  	if runtime.GOOS == "openbsd" {
   126  		// Bug in OpenBSD strtol(3) - base > 36 succeeds.
   127  		if (n != 0 && n != 239089) || m != 234 {
   128  			t.Fatal("Strtol x2: ", n, m)
   129  		}
   130  	} else if n != 0 || m != 234 {
   131  		t.Fatal("Strtol x2: ", n, m)
   132  	}
   133  	C.free(unsafe.Pointer(p))
   134  }
   135  
   136  var (
   137  	cuint  = (C.uint)(0)
   138  	culong C.ulong
   139  	cchar  C.char
   140  )
   141  
   142  type Context struct {
   143  	ctx *C.struct_ibv_context
   144  }
   145  
   146  func benchCgoCall(b *testing.B) {
   147  	const x = C.int(2)
   148  	const y = C.int(3)
   149  	for i := 0; i < b.N; i++ {
   150  		C.add(x, y)
   151  	}
   152  }
   153  
   154  var sinkString string
   155  
   156  func benchGoString(b *testing.B) {
   157  	for i := 0; i < b.N; i++ {
   158  		sinkString = C.GoString(C.cstr)
   159  	}
   160  	const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
   161  	if sinkString != want {
   162  		b.Fatalf("%q != %q", sinkString, want)
   163  	}
   164  }
   165  
   166  // Issue 2470.
   167  func testUnsignedInt(t *testing.T) {
   168  	a := (int64)(C.UINT32VAL)
   169  	b := (int64)(0xc008427b)
   170  	if a != b {
   171  		t.Errorf("Incorrect unsigned int - got %x, want %x", a, b)
   172  	}
   173  }
   174  
   175  // Static (build-time) test that syntax traversal visits all operands of s[i:j:k].
   176  func sliceOperands(array [2000]int) {
   177  	_ = array[C.KILO:C.KILO:C.KILO] // no type error
   178  }
   179  
   180  // set in cgo_thread_lock.go init
   181  var testThreadLockFunc = func(*testing.T) {}