github.com/huandu/go@v0.0.0-20151114150818-04e615e41150/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  extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
    35  
    36  enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
    37  
    38  // issue 1222
    39  typedef union {
    40  	long align;
    41  } xxpthread_mutex_t;
    42  
    43  struct ibv_async_event {
    44  	union {
    45  		int x;
    46  	} element;
    47  };
    48  
    49  struct ibv_context {
    50  	xxpthread_mutex_t mutex;
    51  };
    52  
    53  int add(int x, int y) {
    54  	return x+y;
    55  };
    56  */
    57  import "C"
    58  import (
    59  	"runtime"
    60  	"syscall"
    61  	"testing"
    62  	"unsafe"
    63  )
    64  
    65  const EINVAL = C.EINVAL /* test #define */
    66  
    67  var KILO = C.KILO
    68  
    69  func uuidgen() {
    70  	var uuid C.cgo_uuid_t
    71  	C.uuid_generate(&uuid[0])
    72  }
    73  
    74  func Strtol(s string, base int) (int, error) {
    75  	p := C.CString(s)
    76  	n, err := C.strtol(p, nil, C.int(base))
    77  	C.free(unsafe.Pointer(p))
    78  	return int(n), err
    79  }
    80  
    81  func Atol(s string) int {
    82  	p := C.CString(s)
    83  	n := C.atol(p)
    84  	C.free(unsafe.Pointer(p))
    85  	return int(n)
    86  }
    87  
    88  func testConst(t *testing.T) {
    89  	C.myConstFunc(nil, 0, nil)
    90  }
    91  
    92  func testEnum(t *testing.T) {
    93  	if C.Enum1 != 1 || C.Enum2 != 2 {
    94  		t.Error("bad enum", C.Enum1, C.Enum2)
    95  	}
    96  }
    97  
    98  func testAtol(t *testing.T) {
    99  	l := Atol("123")
   100  	if l != 123 {
   101  		t.Error("Atol 123: ", l)
   102  	}
   103  }
   104  
   105  func testErrno(t *testing.T) {
   106  	p := C.CString("no-such-file")
   107  	m := C.CString("r")
   108  	f, err := C.fopen(p, m)
   109  	C.free(unsafe.Pointer(p))
   110  	C.free(unsafe.Pointer(m))
   111  	if err == nil {
   112  		C.fclose(f)
   113  		t.Fatalf("C.fopen: should fail")
   114  	}
   115  	if err != syscall.ENOENT {
   116  		t.Fatalf("C.fopen: unexpected error: %v", err)
   117  	}
   118  }
   119  
   120  func testMultipleAssign(t *testing.T) {
   121  	p := C.CString("234")
   122  	n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10)
   123  	if runtime.GOOS == "openbsd" {
   124  		// Bug in OpenBSD strtol(3) - base > 36 succeeds.
   125  		if (n != 0 && n != 239089) || m != 234 {
   126  			t.Fatal("Strtol x2: ", n, m)
   127  		}
   128  	} else if n != 0 || m != 234 {
   129  		t.Fatal("Strtol x2: ", n, m)
   130  	}
   131  	C.free(unsafe.Pointer(p))
   132  }
   133  
   134  var (
   135  	cuint  = (C.uint)(0)
   136  	culong C.ulong
   137  	cchar  C.char
   138  )
   139  
   140  type Context struct {
   141  	ctx *C.struct_ibv_context
   142  }
   143  
   144  func benchCgoCall(b *testing.B) {
   145  	const x = C.int(2)
   146  	const y = C.int(3)
   147  	for i := 0; i < b.N; i++ {
   148  		C.add(x, y)
   149  	}
   150  }
   151  
   152  // Issue 2470.
   153  func testUnsignedInt(t *testing.T) {
   154  	a := (int64)(C.UINT32VAL)
   155  	b := (int64)(0xc008427b)
   156  	if a != b {
   157  		t.Errorf("Incorrect unsigned int - got %x, want %x", a, b)
   158  	}
   159  }
   160  
   161  // Static (build-time) test that syntax traversal visits all operands of s[i:j:k].
   162  func sliceOperands(array [2000]int) {
   163  	_ = array[C.KILO:C.KILO:C.KILO] // no type error
   164  }