diff options
author | Russ Cox <rsc@golang.org> | 2010-07-14 17:17:53 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2010-07-14 17:17:53 -0700 |
commit | b77fb4247398a0cf19a3fe4e62ad94b897df84ad (patch) | |
tree | 6e5eea357991a689f7409d708581dc1c6a61014a /misc | |
parent | 6681be115171bad2ff1e7372982b0dcc17343c12 (diff) | |
download | go-b77fb4247398a0cf19a3fe4e62ad94b897df84ad.tar.gz |
cgo: various bug fixes
* remember #defined names, so that C.stdout can refer
to the real name (on OS X) __stdoutp.
* better handling of #defined constant expressions
* allow n, err = C.strtol("asdf", 0, 123) to get errno as os.Error
* write all output files to current directory
* don't require gcc output if there was no input
Fixes issue 533.
Fixes issue 709.
Fixes issue 756.
R=r
CC=dho, golang-dev, iant
http://codereview.appspot.com/1734047
Diffstat (limited to 'misc')
-rw-r--r-- | misc/cgo/stdio/Makefile | 4 | ||||
-rw-r--r-- | misc/cgo/stdio/align.go | 78 | ||||
-rw-r--r-- | misc/cgo/stdio/chain.go | 4 | ||||
-rw-r--r-- | misc/cgo/stdio/fib.go | 2 | ||||
-rw-r--r-- | misc/cgo/stdio/file.go | 24 | ||||
-rw-r--r-- | misc/cgo/stdio/hello.go | 23 | ||||
-rw-r--r-- | misc/cgo/stdio/test.go | 91 |
7 files changed, 206 insertions, 20 deletions
diff --git a/misc/cgo/stdio/Makefile b/misc/cgo/stdio/Makefile index 2e3d46631..a0093ff52 100644 --- a/misc/cgo/stdio/Makefile +++ b/misc/cgo/stdio/Makefile @@ -6,7 +6,9 @@ include ../../../src/Make.$(GOARCH) TARG=stdio CGOFILES=\ - file.go + align.go\ + file.go\ + test.go\ CLEANFILES+=hello fib chain run.out diff --git a/misc/cgo/stdio/align.go b/misc/cgo/stdio/align.go new file mode 100644 index 000000000..6cdfd902f --- /dev/null +++ b/misc/cgo/stdio/align.go @@ -0,0 +1,78 @@ +package stdio + +/* +#include <stdio.h> + +typedef unsigned char Uint8; +typedef unsigned short Uint16; + +typedef enum { + MOD1 = 0x0000, + MODX = 0x8000 +} SDLMod; + +typedef enum { + A = 1, + B = 322, + SDLK_LAST +} SDLKey; + +typedef struct SDL_keysym { + Uint8 scancode; + SDLKey sym; + SDLMod mod; + Uint16 unicode; +} SDL_keysym; + +typedef struct SDL_KeyboardEvent { + Uint8 typ; + Uint8 which; + Uint8 state; + SDL_keysym keysym; +} SDL_KeyboardEvent; + +void makeEvent(SDL_KeyboardEvent *event) { + unsigned char *p; + int i; + + p = (unsigned char*)event; + for (i=0; i<sizeof *event; i++) { + p[i] = i; + } +} + +int same(SDL_KeyboardEvent* e, Uint8 typ, Uint8 which, Uint8 state, Uint8 scan, SDLKey sym, SDLMod mod, Uint16 uni) { + return e->typ == typ && e->which == which && e->state == state && e->keysym.scancode == scan && e->keysym.sym == sym && e->keysym.mod == mod && e->keysym.unicode == uni; +} + +void cTest(SDL_KeyboardEvent *event) { + printf("C: %#x %#x %#x %#x %#x %#x %#x\n", event->typ, event->which, event->state, + event->keysym.scancode, event->keysym.sym, event->keysym.mod, event->keysym.unicode); + fflush(stdout); +} + +*/ +import "C" + +import ( + "fmt" + "syscall" +) + +func TestAlign() { + if syscall.ARCH == "amd64" { + // alignment is known to be broken on amd64. + // http://code.google.com/p/go/issues/detail?id=609 + return + } + var evt C.SDL_KeyboardEvent + C.makeEvent(&evt) + if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 { + fmt.Println("*** bad alignment") + C.cTest(&evt) + fmt.Printf("Go: %#x %#x %#x %#x %#x %#x %#x\n", + evt.typ, evt.which, evt.state, evt.keysym.scancode, + evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) + fmt.Println(evt) + } +} diff --git a/misc/cgo/stdio/chain.go b/misc/cgo/stdio/chain.go index dd5e01542..c2b105072 100644 --- a/misc/cgo/stdio/chain.go +++ b/misc/cgo/stdio/chain.go @@ -22,7 +22,7 @@ func link(left chan<- int, right <-chan int) { runtime.LockOSThread() for { v := <-right - stdio.Puts(strconv.Itoa(v)) + stdio.Stdout.WriteString(strconv.Itoa(v) + "\n") left <- 1+v } } @@ -38,6 +38,6 @@ func main() { for i := 0; i < R; i++ { right <- 0 x := <-leftmost - stdio.Puts(strconv.Itoa(x)) + stdio.Stdout.WriteString(strconv.Itoa(x) + "\n") } } diff --git a/misc/cgo/stdio/fib.go b/misc/cgo/stdio/fib.go index 63ae04988..c02e31fd8 100644 --- a/misc/cgo/stdio/fib.go +++ b/misc/cgo/stdio/fib.go @@ -26,7 +26,7 @@ func fibber(c, out chan int64, i int64) { } for { j := <-c - stdio.Puts(strconv.Itoa64(j)) + stdio.Stdout.WriteString(strconv.Itoa64(j) + "\n") out <- j <-out i += j diff --git a/misc/cgo/stdio/file.go b/misc/cgo/stdio/file.go index 7d1f22280..1f461f293 100644 --- a/misc/cgo/stdio/file.go +++ b/misc/cgo/stdio/file.go @@ -10,33 +10,31 @@ see ../gmp/gmp.go. package stdio -// TODO(rsc): Remove fflushstdout when C.fflush(C.stdout) works in cgo. - /* #include <stdio.h> #include <stdlib.h> +#include <sys/stat.h> +#include <errno.h> -void fflushstdout(void) { fflush(stdout); } +char* greeting = "hello, world"; */ import "C" import "unsafe" -/* type File C.FILE var Stdout = (*File)(C.stdout) var Stderr = (*File)(C.stderr) func (f *File) WriteString(s string) { - p := C.CString(s); - C.fputs(p, (*C.FILE)(f)); - C.free(p); -} -*/ - -func Puts(s string) { p := C.CString(s) - C.puts(p) + C.fputs(p, (*C.FILE)(f)) C.free(unsafe.Pointer(p)) - C.fflushstdout() + f.Flush() +} + +func (f *File) Flush() { + C.fflush((*C.FILE)(f)) } + +var Greeting = C.GoString(C.greeting) diff --git a/misc/cgo/stdio/hello.go b/misc/cgo/stdio/hello.go index 47f9de02f..9cb6e6884 100644 --- a/misc/cgo/stdio/hello.go +++ b/misc/cgo/stdio/hello.go @@ -4,9 +4,26 @@ package main -import "stdio" +import ( + "os" + "stdio" +) func main() { - // stdio.Stdout.WriteString("hello, world\n"); - stdio.Puts("hello, world") + stdio.Stdout.WriteString(stdio.Greeting + "\n") + + l := stdio.Atol("123") + if l != 123 { + println("Atol 123: ", l) + panic("bad atol") + } + + n, err := stdio.Strtol("asdf", 123) + if n != 0 || err != os.EINVAL { + println("Strtol: ", n, err) + panic("bad atoi2") + } + + stdio.TestAlign() + stdio.TestEnum() } diff --git a/misc/cgo/stdio/test.go b/misc/cgo/stdio/test.go new file mode 100644 index 000000000..490eb93c6 --- /dev/null +++ b/misc/cgo/stdio/test.go @@ -0,0 +1,91 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains test cases for cgo. + +package stdio + +/* +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <errno.h> + +#define SHIFT(x, y) ((x)<<(y)) +#define KILO SHIFT(1, 10) + +enum { + Enum1 = 1, + Enum2 = 2, +}; +*/ +import "C" +import ( + "os" + "unsafe" +) + +const EINVAL = C.EINVAL /* test #define */ + +var KILO = C.KILO + +func Size(name string) (int64, os.Error) { + var st C.struct_stat + p := C.CString(name) + _, err := C.stat(p, &st) + C.free(unsafe.Pointer(p)) + if err != nil { + return 0, err + } + return int64(C.ulong(st.st_size)), nil +} + +func Strtol(s string, base int) (int, os.Error) { + p := C.CString(s) + n, err := C.strtol(p, nil, C.int(base)) + C.free(unsafe.Pointer(p)) + return int(n), err +} + +func Atol(s string) int { + p := C.CString(s) + n := C.atol(p) + C.free(unsafe.Pointer(p)) + return int(n) +} + +func TestEnum() { + if C.Enum1 != 1 || C.Enum2 != 2 { + println("bad enum", C.Enum1, C.Enum2) + } +} + +func TestAtol() { + l := Atol("123") + if l != 123 { + println("Atol 123: ", l) + panic("bad atol") + } +} + +func TestErrno() { + n, err := Strtol("asdf", 123) + if n != 0 || err != os.EINVAL { + println("Strtol: ", n, err) + panic("bad atoi2") + } +} + +var ( + uint = (C.uint)(0) + ulong C.ulong + char C.char +) + +func Test() { + TestAlign() + TestAtol() + TestEnum() + TestErrno() +} |