...
Run Format

Source file test/slice3.go

Documentation: test

  // runoutput
  
  // Copyright 2013 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.
  
  // Test run-time behavior of 3-index slice expressions.
  
  package main
  
  import (
  	"bufio"
  	"fmt"
  	"os"
  	"strconv"
  )
  
  var bout *bufio.Writer
  
  func main() {
  	bout = bufio.NewWriter(os.Stdout)
  
  	fmt.Fprintf(bout, "%s", programTop)
  	fmt.Fprintf(bout, "func main() {\n")
  
  	index := []string{
  		"0",
  		"1",
  		"2",
  		"3",
  		"10",
  		"20",
  		"vminus1",
  		"v0",
  		"v1",
  		"v2",
  		"v3",
  		"v10",
  		"v20",
  	}
  
  	parse := func(s string) (n int, isconst bool) {
  		if s == "vminus1" {
  			return -1, false
  		}
  		isconst = true
  		if s[0] == 'v' {
  			isconst = false
  			s = s[1:]
  		}
  		n, _ = strconv.Atoi(s)
  		return n, isconst
  	}
  
  	const Cap = 10 // cap of slice, array
  
  	for _, base := range []string{"array", "slice"} {
  		for _, i := range index {
  			iv, iconst := parse(i)
  			for _, j := range index {
  				jv, jconst := parse(j)
  				for _, k := range index {
  					kv, kconst := parse(k)
  					// Avoid errors that would make the program not compile.
  					// Those are tested by slice3err.go.
  					switch {
  					case iconst && jconst && iv > jv,
  						jconst && kconst && jv > kv,
  						iconst && kconst && iv > kv,
  						iconst && base == "array" && iv > Cap,
  						jconst && base == "array" && jv > Cap,
  						kconst && base == "array" && kv > Cap:
  						continue
  					}
  
  					expr := base + "[" + i + ":" + j + ":" + k + "]"
  					var xbase, xlen, xcap int
  					if iv > jv || jv > kv || kv > Cap || iv < 0 || jv < 0 || kv < 0 {
  						xbase, xlen, xcap = -1, -1, -1
  					} else {
  						xbase = iv
  						xlen = jv - iv
  						xcap = kv - iv
  					}
  					fmt.Fprintf(bout, "\tcheckSlice(%q, func() []byte { return %s }, %d, %d, %d)\n", expr, expr, xbase, xlen, xcap)
  				}
  			}
  		}
  	}
  
  	fmt.Fprintf(bout, "\tif !ok { os.Exit(1) }\n")
  	fmt.Fprintf(bout, "}\n")
  	bout.Flush()
  }
  
  var programTop = `
  package main
  
  import (
  	"fmt"
  	"os"
  	"unsafe"
  )
  
  var ok = true
  
  var (
  	array = new([10]byte)
  	slice = array[:]
  
  	vminus1 = -1
  	v0 = 0
  	v1 = 1
  	v2 = 2
  	v3 = 3
  	v4 = 4
  	v5 = 5
  	v10 = 10
  	v20 = 20
  )
  
  func notOK() {
  	if ok {
  		println("BUG:")
  		ok = false
  	}
  }
  
  func checkSlice(desc string, f func() []byte, xbase, xlen, xcap int) {
  	defer func() {
  		if err := recover(); err != nil {
  			if xbase >= 0 {
  				notOK()
  				println(desc, " unexpected panic: ", fmt.Sprint(err))
  			}
  		}
  		// "no panic" is checked below
  	}()
  	
  	x := f()
  
  	arrayBase := uintptr(unsafe.Pointer(array))
  	raw := *(*[3]uintptr)(unsafe.Pointer(&x))
  	base, len, cap := raw[0] - arrayBase, raw[1], raw[2]
  	if xbase < 0 {
  		notOK()
  		println(desc, "=", base, len, cap, "want panic")
  		return
  	}
  	if cap != 0 && base != uintptr(xbase) || base >= 10 || len != uintptr(xlen) || cap != uintptr(xcap) {
  		notOK()
  		if cap == 0 {
  			println(desc, "=", base, len, cap, "want", "0-9", xlen, xcap)
  		} else {
  			println(desc, "=", base, len, cap, "want", xbase, xlen, xcap)
  		}
  	}
  }
  
  `
  

View as plain text