How to use Len method of main Package

Best Mock code snippet using main.Len

Run Mock automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

string.go

Source: string.go Github

copy
1package main
2
3func bf(mainString, patternString string) bool {
4	mainStrLen := len(mainString)
5	patternStrLen := len(patternString)
6
7	if mainStrLen < patternStrLen {
8		return false
9	}
10
11	for i := 0; i < mainStrLen-patternStrLen+1; i++ {
12		subStr := mainString[i : patternStrLen+i]
13		if subStr == patternString {
14			return true
15		}
16	}
17
18	return false
19}
20
21var squreMap = make(map[int]uint32)
22
23func initSqureNum() {
24	squreMap[0] = 1
25
26	for i := 1; i <= 26; i++ {
27		if i == 1 {
28			squreMap[i] = 26
29		} else {
30			squreMap[i] = squreMap[i-1] * 26
31		}
32	}
33}
34
35func hash(str string) uint32 {
36	var result uint32
37	strLen := len(str)
38
39	for index, rune := range str {
40		result += (uint32(rune%97) + 1) * squreMap[strLen-index-1]
41	}
42	return result
43}
44
45func rk(mainString, patternString string) bool {
46	mainStrLen := len(mainString)
47	patternStrLen := len(patternString)
48
49	if mainStrLen < patternStrLen {
50		return false
51	}
52
53	var subStrHash uint32
54	patternStrHash := hash(patternString)
55
56	for i := 0; i < mainStrLen-patternStrLen+1; i++ {
57		subStr := mainString[i : patternStrLen+i]
58		subStrHash = hash(subStr)
59
60		if subStrHash == patternStrHash {
61			return true
62		}
63	}
64
65	return false
66}
67
68// func main() {
69// 	mainString := "acdefg"
70// 	patternString := "cdeg"
71// 	fmt.Println("bf result: ", bf(mainString, patternString))
72
73// 	initSqureNum()
74// 	fmt.Println("rk result: ", rk(mainString, patternString))
75
76// }
77
Full Screen

slice.go

Source: slice.go Github

copy
1package main
2
3import "fmt"
4
5func main() {
6	/* -------- slice -------- */
7	// slice: array-like type, but slice has no specified length
8
9	s := []int{0, 1, 2, 3, 4, 5}
10	s = s[2:5]
11	fmt.Println(s) // [2 3 4]
12
13	s = s[1:]
14	fmt.Println(s) // [3 4]
15
16	s = append(s, 2)
17	fmt.Println(s) // [3 4 2]
18
19	s = append(s, 8, 9, 10)
20	fmt.Println(s) // [3 4 2 8 9 10]
21
22	// declare a slice, len = 0, cap = 3
23	//
24	// cap tells you the capacity of the underlying array
25	// len tells you how many items are in the array.
26	//
27	// ex.
28	// s := []int{0, 1, 2, 3, 4, 5}
29	//
30	// [ptr][len][cap]
31	//   |  [ 6 ][ 6 ]
32	//   |
33	//   | [0][1][2][3][4][5]
34	//   +--^
35	//  len -  -  -  -  -  - (6)
36	//  cap -  -  -  -  -  - (6)
37	//
38	// s = s[1:3]
39	//
40	// [ptr][len][cap]
41	//   |  [ 2 ][ 5 ]
42	//   |
43	//   | [0][1][2][3][4][5]
44	//   +-----^
45	//  len    -  -          (2)
46	//  cap    -  -  -  -  - (5)
47	fmt.Println(len(s), cap(s)) // 6 6
48	s = s[1:3]                  // includes the first element, but excludes the last one, [1,3)
49	fmt.Println(len(s), cap(s)) // 2 5
50
51	slice := make([]int, 0, 3)
52	for i := 1; i <= 15; i++ {
53		slice = append(slice, i)
54		fmt.Println(len(slice), cap(slice))
55		/*
56			1 3
57			2 3
58			3 3
59			4 6
60			5 6
61			6 6
62			7 12
63			8 12
64			9 12
65			10 12
66			11 12
67			12 12
68			13 24
69			14 24
70			15 24
71		*/
72	}
73	fmt.Println(slice)
74
75	// slice... -> replace to [1 2 3 ... 13 14 15]
76	fmt.Println(len(s), cap(s))         // 6 6
77	fmt.Println(len(slice), cap(slice)) // 15 24
78	s = append(s, slice...)
79	fmt.Println(len(s), cap(s)) // 21 22
80	fmt.Println(s)              // [3 4 2 8 9 10 1 2 3 ... 13 14 15]
81
82	source := []int{0, 1, 2}
83	target := make([]int, len(source), cap(source)*2)
84
85	// function copy returns the number of elements copied,
86	// which will be the minimum of len(dst) and len(src)
87	copy(target, source)
88	fmt.Println(len(target), cap(target)) // 3 6
89	fmt.Println(target)                   // [0 1 2]
90	copy(target, s)
91	fmt.Println(len(target), cap(target)) // 3 6
92	fmt.Println(target)                   // [3 4 2]
93}
94
95/*
96package main
97
98import "fmt"
99
100func main() {
101		s := []int{2, 3, 5, 7, 11, 13}
102			printSlice(s)
103
104				// Slice the slice to give it zero length.
105					s = s[:0]
106						printSlice(s)
107
108							// Extend its length.
109								s = s[:4]
110									printSlice(s)
111
112										// Drop its first two values.
113											s = s[2:]
114												printSlice(s)
115											}
116
117											func printSlice(s []int) {
118													fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
119												}
120
121*/
122
123/* nil slice
124// By default ptr pointer to nil, len and cap is zero
125package main
126
127import "fmt"
128
129func main() {
130		var s []int
131			fmt.Println(s, len(s), cap(s))
132				if s == nil {
133							fmt.Println("nil!")
134								}
135							}
136
137*/
138
139/* slice with make
140
141package main
142
143import "fmt"
144
145func main() {
146		a := make([]int, 5)
147			printSlice("a", a)
148
149				b := make([]int, 0, 5)
150					printSlice("b", b)
151
152						c := b[:2]
153							printSlice("c", c)
154
155								d := c[2:5]
156									printSlice("d", d)
157								}
158
159								func printSlice(s string, x []int) {
160										fmt.Printf("%s len=%d cap=%d %v\n",
161												s, len(x), cap(x), x)
162											}
163
164*/
165
166/* slices of slices
167// tic-tac-toe
168package main
169
170import (
171		"fmt"
172			"strings"
173		)
174
175		func main() {
176				// Create a tic-tac-toe board.
177					board := [][]string{
178								[]string{"_", "_", "_"},
179										[]string{"_", "_", "_"},
180												[]string{"_", "_", "_"},
181													}
182
183														// The players take turns.
184															board[0][0] = "X"
185																board[2][2] = "O"
186																	board[1][2] = "X"
187																		board[1][0] = "O"
188																			board[0][2] = "X"
189
190																				for i := 0; i < len(board); i++ {
191																							fmt.Printf("%s\n", strings.Join(board[i], " "))
192																								}
193																							}
194*/
195
196/* append
197package main
198
199import "fmt"
200
201func main() {
202		var s []int
203			printSlice(s)
204
205				// append works on nil slices.
206					s = append(s, 0)
207						printSlice(s)
208
209							// The slice grows as needed.
210								s = append(s, 1)
211									printSlice(s)
212
213										// We can add more than one element at a time.
214										s = append(s, 2, 3, 4) // cap: 2, If the backing array of s is too small to fit all the given values a bigger array will be allocated. (capXn) => 6
215										// The returned slice will point to the newly allocated array.
216												printSlice(s)
217											}
218
219											func printSlice(s []int) {
220													fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
221												}
222
223*/
224
225/* Map intro
226ickage main
227
228import "fmt"
229
230type Vertex struct {
231		Lat, Long float64
232	}
233
234	var m map[string]Vertex
235
236	func main() {
237			m = make(map[string]Vertex)
238				m["Bell Labs"] = Vertex{
239							40.68433, -74.39967,
240								}
241									fmt.Println(m["Bell Labs"])
242								}
243
244*/
245
Full Screen

test.go

Source: test.go Github

copy
1package main
2
3import "fmt"
4
5func main() {
6	/* -------- array -------- */
7	// array: 'specifies a length' and an element type
8	// The type [n]T is an array of n values of type T
9	// ex. type [2]int is defferent than type [4]int
10
11	var a1 [3]int // declaration
12	// By default an array is zero-valued
13	fmt.Println(a1)
14	a1[0] = 1
15	a1[1] = 2
16	a1[2] = 4
17	fmt.Println(a1)
18	var a2 = [3]int{1, 2, 4} // declare and initialize
19	fmt.Println(a2)
20	var a3 = [...]int{1, 2, 4}
21	fmt.Println(a3)
22	var a4 [2][3]int
23	a4[0][0] = 5
24	a4[0][1] = 4
25	a4[0][2] = 3
26	a4[1][0] = 2
27	a4[1][1] = 1
28	a4[1][2] = 0
29	fmt.Println(a4)
30	var a5 = [2][3]int{
31		{5, 4, 3},
32		{2, 1, 0}, // MUST have comma
33		// if it wouldn’t be there, Go would have added a semicolon(;)
34		// by the rule which would have CRASHED the program
35	}
36	fmt.Println(a5)
37
38	/* -------- slice -------- */
39	// slice: array-like type, but slice has no specified length
40
41	s := []int{0, 1, 2, 3, 4, 5}
42	s = s[2:5]
43	fmt.Println(s) // [2 3 4]
44
45	s = s[1:]
46	fmt.Println(s) // [3 4]
47
48	s = append(s, 2)
49	fmt.Println(s) // [3 4 2]
50
51	s = append(s, 8, 9, 10)
52	fmt.Println(s) // [3 4 2 8 9 10]
53
54	// declare a slice, len = 0, cap = 3
55	//
56	// cap tells you the capacity of the underlying array
57	// len tells you how many items are in the array.
58	//
59	// ex.
60	// s := []int{0, 1, 2, 3, 4, 5}
61	//
62	// [ptr][len][cap]
63	//   |  [ 6 ][ 6 ]
64	//   |
65	//   | [0][1][2][3][4][5]
66	//   +--^
67	//  len -  -  -  -  -  - (6)
68	//  cap -  -  -  -  -  - (6)
69	//
70	// s = s[1:3]
71	//
72	// [ptr][len][cap]
73	//   |  [ 2 ][ 5 ]
74	//   |
75	//   | [0][1][2][3][4][5]
76	//   +-----^
77	//  len    -  -          (2)
78	//  cap    -  -  -  -  - (5)
79	fmt.Println(len(s), cap(s)) // 6 6
80	s = s[1:3]                  // includes the first element, but excludes the last one, [1,3)
81	fmt.Println(len(s), cap(s)) // 2 5
82
83	slice := make([]int, 0, 3)
84	for i := 1; i <= 15; i++ {
85		slice = append(slice, i)
86		fmt.Println(len(slice), cap(slice))
87		/*
88			1 3
89			2 3
90			3 3
91			4 6
92			5 6
93			6 6
94			7 12
95			8 12
96			9 12
97			10 12
98			11 12
99			12 12
100			13 24
101			14 24
102			15 24
103		*/
104	}
105	fmt.Println(slice)
106
107	// slice... -> replace to [1 2 3 ... 13 14 15]
108	fmt.Println(len(s), cap(s))         // 6 6
109	fmt.Println(len(slice), cap(slice)) // 15 24
110	s = append(s, slice...)
111	fmt.Println(len(s), cap(s)) // 21 22
112	fmt.Println(s)              // [3 4 2 8 9 10 1 2 3 ... 13 14 15]
113
114	source := []int{0, 1, 2}
115	target := make([]int, len(source), cap(source)*2)
116
117	// function copy returns the number of elements copied,
118	// which will be the minimum of len(dst) and len(src)
119	copy(target, source)
120	fmt.Println(len(target), cap(target)) // 3 6
121	fmt.Println(target)                   // [0 1 2]
122	copy(target, s)
123	fmt.Println(len(target), cap(target)) // 3 6
124	fmt.Println(target)                   // [3 4 2]
125
126	/* -------- map -------- */
127	// maps keys to values
128	// zero value of map is nil
129	// nil map has no keys, nor can keys be added
130	// make function returns a map of the given type, initialized and ready for use
131
132}
133
134/*
135package main
136
137import "fmt"
138
139func main() {
140		s := []int{2, 3, 5, 7, 11, 13}
141			printSlice(s)
142
143				// Slice the slice to give it zero length.
144					s = s[:0]
145						printSlice(s)
146
147							// Extend its length.
148								s = s[:4]
149									printSlice(s)
150
151										// Drop its first two values.
152											s = s[2:]
153												printSlice(s)
154											}
155
156											func printSlice(s []int) {
157													fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
158												}
159
160*/
161
162/* nil slice
163// By default ptr pointer to nil, len and cap is zero
164package main
165
166import "fmt"
167
168func main() {
169		var s []int
170			fmt.Println(s, len(s), cap(s))
171				if s == nil {
172							fmt.Println("nil!")
173								}
174							}
175
176*/
177
178/* slice with make
179
180package main
181
182import "fmt"
183
184func main() {
185		a := make([]int, 5)
186			printSlice("a", a)
187
188				b := make([]int, 0, 5)
189					printSlice("b", b)
190
191						c := b[:2]
192							printSlice("c", c)
193
194								d := c[2:5]
195									printSlice("d", d)
196								}
197
198								func printSlice(s string, x []int) {
199										fmt.Printf("%s len=%d cap=%d %v\n",
200												s, len(x), cap(x), x)
201											}
202
203*/
204
205/* slices of slices
206// tic-tac-toe
207package main
208
209import (
210		"fmt"
211			"strings"
212		)
213
214		func main() {
215				// Create a tic-tac-toe board.
216					board := [][]string{
217								[]string{"_", "_", "_"},
218										[]string{"_", "_", "_"},
219												[]string{"_", "_", "_"},
220													}
221
222														// The players take turns.
223															board[0][0] = "X"
224																board[2][2] = "O"
225																	board[1][2] = "X"
226																		board[1][0] = "O"
227																			board[0][2] = "X"
228
229																				for i := 0; i < len(board); i++ {
230																							fmt.Printf("%s\n", strings.Join(board[i], " "))
231																								}
232																							}
233*/
234
235/* append
236package main
237
238import "fmt"
239
240func main() {
241		var s []int
242			printSlice(s)
243
244				// append works on nil slices.
245					s = append(s, 0)
246						printSlice(s)
247
248							// The slice grows as needed.
249								s = append(s, 1)
250									printSlice(s)
251
252										// We can add more than one element at a time.
253										s = append(s, 2, 3, 4) // cap: 2, If the backing array of s is too small to fit all the given values a bigger array will be allocated. (capXn) => 6
254										// The returned slice will point to the newly allocated array.
255												printSlice(s)
256											}
257
258											func printSlice(s []int) {
259													fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
260												}
261
262*/
263
264/* Map intro
265ickage main
266
267import "fmt"
268
269type Vertex struct {
270		Lat, Long float64
271	}
272
273	var m map[string]Vertex
274
275	func main() {
276			m = make(map[string]Vertex)
277				m["Bell Labs"] = Vertex{
278							40.68433, -74.39967,
279								}
280									fmt.Println(m["Bell Labs"])
281								}
282
283*/
284
285/* Map
286package main
287
288import "fmt"
289
290type Vertex struct {
291		Lat, Long float64
292	}
293
294	var m = map[string]Vertex{
295			"Bell Labs": Vertex{
296						40.68433, -74.39967,
297							},
298								"Google": Vertex{
299											37.42202, -122.08408,
300												},
301											}
302
303											func main() {
304													fmt.Println(m)
305												}
306
307*/
308
309/* Map 2
310package main
311
312import "fmt"
313
314type Vertex struct {
315		Lat, Long float64
316	}
317
318	var m = map[string]Vertex{
319			"Bell Labs": {40.68433, -74.39967},
320				"Google":    {37.42202, -122.08408},
321			}
322
323			func main() {
324					fmt.Println(m)
325				}
326
327*/
328
329/* Mutating Map
330package main
331
332import "fmt"
333
334func main() {
335		m := make(map[string]int)
336
337			m["Answer"] = 42
338				fmt.Println("The value:", m["Answer"])
339
340					m["Answer"] = 48
341						fmt.Println("The value:", m["Answer"])
342
343							delete(m, "Answer")
344								fmt.Println("The value:", m["Answer"])
345
346									v, ok := m["Answer"]
347										fmt.Println("The value:", v, "Present?", ok)
348									}
349
350*/
351
352/* Mutating Map 2
353package main
354
355func main() {
356	    tickers := map[string]string{
357			        "GOOG": "Google Inc",
358					        "MSFT": "Microsoft",
359							        "FB":   "FaceBook",
360									        "AMZN": "Amazon",
361											    }
362
363												    // map 키 체크
364													    val, exists := tickers["MSFT"]
365														    if !exists {
366																        println("No MSFT ticker")
367																		    }
368																		}
369*/
370
371/* Mutating Map 3
372package main
373
374import "fmt"
375
376func main() {
377	    myMap := map[string]string{
378			        "A": "Apple",
379					        "B": "Banana",
380							        "C": "Charlie",
381									    }
382
383										    // for range 문을 사용하여 모든 맵 요소 출력
384											    // Map은 unordered 이므로 순서는 무작위
385												    for key, val := range myMap {
386														        fmt.Println(key, val)
387																    }
388																}
389*/
390
Full Screen

variables_test.go

Source: variables_test.go Github

copy
1package service_test
2
3import (
4	"errors"
5	"fmt"
6	"runtime"
7	"sort"
8	"strings"
9	"testing"
10
11	"github.com/derekparker/delve/pkg/goversion"
12	"github.com/derekparker/delve/pkg/proc"
13	"github.com/derekparker/delve/pkg/proc/gdbserial"
14	"github.com/derekparker/delve/pkg/proc/native"
15	"github.com/derekparker/delve/service/api"
16
17	protest "github.com/derekparker/delve/pkg/proc/test"
18)
19
20var pnormalLoadConfig = proc.LoadConfig{true, 1, 64, 64, -1, 0}
21var pshortLoadConfig = proc.LoadConfig{false, 0, 64, 0, 3, 0}
22
23type varTest struct {
24	name         string
25	preserveName bool
26	value        string
27	alternate    string
28	varType      string
29	err          error
30}
31
32func matchStringOrPrefix(output, target string) bool {
33	if strings.HasSuffix(target, "…") {
34		prefix := target[:len(target)-len("…")]
35		b := strings.HasPrefix(output, prefix)
36		return b
37	} else {
38		return output == target
39	}
40}
41
42func assertVariable(t *testing.T, variable *proc.Variable, expected varTest) {
43	if expected.preserveName {
44		if variable.Name != expected.name {
45			t.Fatalf("Expected %s got %s\n", expected.name, variable.Name)
46		}
47	}
48
49	cv := api.ConvertVar(variable)
50
51	if cv.Type != expected.varType {
52		t.Fatalf("Expected %s got %s (for variable %s)\n", expected.varType, cv.Type, expected.name)
53	}
54
55	if ss := cv.SinglelineString(); !matchStringOrPrefix(ss, expected.value) {
56		t.Fatalf("Expected %#v got %#v (for variable %s)\n", expected.value, ss, expected.name)
57	}
58}
59
60func findFirstNonRuntimeFrame(p proc.Process) (proc.Stackframe, error) {
61	frames, err := proc.ThreadStacktrace(p.CurrentThread(), 10)
62	if err != nil {
63		return proc.Stackframe{}, err
64	}
65
66	for _, frame := range frames {
67		if frame.Current.Fn != nil && !strings.HasPrefix(frame.Current.Fn.Name, "runtime.") {
68			return frame, nil
69		}
70	}
71	return proc.Stackframe{}, fmt.Errorf("non-runtime frame not found")
72}
73
74func evalVariable(p proc.Process, symbol string, cfg proc.LoadConfig) (*proc.Variable, error) {
75	var scope *proc.EvalScope
76	var err error
77
78	if testBackend == "rr" {
79		var frame proc.Stackframe
80		frame, err = findFirstNonRuntimeFrame(p)
81		if err == nil {
82			scope = proc.FrameToScope(p.BinInfo(), p.CurrentThread(), nil, frame)
83		}
84	} else {
85		scope, err = proc.GoroutineScope(p.CurrentThread())
86	}
87
88	if err != nil {
89		return nil, err
90	}
91
92	return scope.EvalVariable(symbol, cfg)
93}
94
95func (tc *varTest) alternateVarTest() varTest {
96	r := *tc
97	r.value = r.alternate
98	return r
99}
100
101func setVariable(p proc.Process, symbol, value string) error {
102	scope, err := proc.GoroutineScope(p.CurrentThread())
103	if err != nil {
104		return err
105	}
106	return scope.SetVariable(symbol, value)
107}
108
109func withTestProcess(name string, t *testing.T, fn func(p proc.Process, fixture protest.Fixture)) {
110	var buildFlags protest.BuildFlags
111	if buildMode == "pie" {
112		buildFlags = protest.BuildModePIE
113	}
114	fixture := protest.BuildFixture(name, buildFlags)
115	var p proc.Process
116	var err error
117	var tracedir string
118	switch testBackend {
119	case "native":
120		p, err = native.Launch([]string{fixture.Path}, ".", false, []string{})
121	case "lldb":
122		p, err = gdbserial.LLDBLaunch([]string{fixture.Path}, ".", false, []string{})
123	case "rr":
124		protest.MustHaveRecordingAllowed(t)
125		t.Log("recording")
126		p, tracedir, err = gdbserial.RecordAndReplay([]string{fixture.Path}, ".", true, []string{})
127		t.Logf("replaying %q", tracedir)
128	default:
129		t.Fatalf("unknown backend %q", testBackend)
130	}
131	if err != nil {
132		t.Fatal("Launch():", err)
133	}
134
135	defer func() {
136		p.Detach(true)
137		if tracedir != "" {
138			protest.SafeRemoveAll(tracedir)
139		}
140	}()
141
142	fn(p, fixture)
143}
144
145func TestVariableEvaluation(t *testing.T) {
146	testcases := []varTest{
147		{"a1", true, "\"foofoofoofoofoofoo\"", "", "string", nil},
148		{"a11", true, "[3]main.FooBar [{Baz: 1, Bur: \"a\"},{Baz: 2, Bur: \"b\"},{Baz: 3, Bur: \"c\"}]", "", "[3]main.FooBar", nil},
149		{"a12", true, "[]main.FooBar len: 2, cap: 2, [{Baz: 4, Bur: \"d\"},{Baz: 5, Bur: \"e\"}]", "", "[]main.FooBar", nil},
150		{"a13", true, "[]*main.FooBar len: 3, cap: 3, [*{Baz: 6, Bur: \"f\"},*{Baz: 7, Bur: \"g\"},*{Baz: 8, Bur: \"h\"}]", "", "[]*main.FooBar", nil},
151		{"a2", true, "6", "10", "int", nil},
152		{"a3", true, "7.23", "3.1", "float64", nil},
153		{"a4", true, "[2]int [1,2]", "", "[2]int", nil},
154		{"a5", true, "[]int len: 5, cap: 5, [1,2,3,4,5]", "", "[]int", nil},
155		{"a6", true, "main.FooBar {Baz: 8, Bur: \"word\"}", "", "main.FooBar", nil},
156		{"a7", true, "*main.FooBar {Baz: 5, Bur: \"strum\"}", "", "*main.FooBar", nil},
157		{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil},
158		{"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil},
159		{"baz", true, "\"bazburzum\"", "", "string", nil},
160		{"neg", true, "-1", "-20", "int", nil},
161		{"f32", true, "1.2", "1.1", "float32", nil},
162		{"c64", true, "(1 + 2i)", "(4 + 5i)", "complex64", nil},
163		{"c128", true, "(2 + 3i)", "(6.3 + 7i)", "complex128", nil},
164		{"a6.Baz", true, "8", "20", "int", nil},
165		{"a7.Baz", true, "5", "25", "int", nil},
166		{"a8.Baz", true, "\"feh\"", "", "string", nil},
167		{"a9.Baz", true, "nil", "", "int", fmt.Errorf("a9 is nil")},
168		{"a9.NonExistent", true, "nil", "", "int", fmt.Errorf("a9 has no member NonExistent")},
169		{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil}, // reread variable after member
170		{"i32", true, "[2]int32 [1,2]", "", "[2]int32", nil},
171		{"b1", true, "true", "false", "bool", nil},
172		{"b2", true, "false", "true", "bool", nil},
173		{"i8", true, "1", "2", "int8", nil},
174		{"u16", true, "65535", "0", "uint16", nil},
175		{"u32", true, "4294967295", "1", "uint32", nil},
176		{"u64", true, "18446744073709551615", "2", "uint64", nil},
177		{"u8", true, "255", "3", "uint8", nil},
178		{"up", true, "5", "4", "uintptr", nil},
179		{"f", true, "main.barfoo", "", "func()", nil},
180		{"ba", true, "[]int len: 200, cap: 200, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+136 more]", "", "[]int", nil},
181		{"ms", true, "main.Nest {Level: 0, Nest: *main.Nest {Level: 1, Nest: *(*main.Nest)(…", "", "main.Nest", nil},
182		{"ms.Nest.Nest", true, "*main.Nest {Level: 2, Nest: *main.Nest {Level: 3, Nest: *(*main.Nest)(…", "", "*main.Nest", nil},
183		{"ms.Nest.Nest.Nest.Nest.Nest", true, "*main.Nest nil", "", "*main.Nest", nil},
184		{"ms.Nest.Nest.Nest.Nest.Nest.Nest", true, "", "", "*main.Nest", fmt.Errorf("ms.Nest.Nest.Nest.Nest.Nest is nil")},
185		{"main.p1", true, "10", "12", "int", nil},
186		{"p1", true, "10", "13", "int", nil},
187		{"NonExistent", true, "", "", "", fmt.Errorf("could not find symbol value for NonExistent")},
188	}
189
190	protest.AllowRecording(t)
191	withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
192		err := proc.Continue(p)
193		assertNoError(err, t, "Continue() returned an error")
194
195		for _, tc := range testcases {
196			variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
197			if tc.err == nil {
198				assertNoError(err, t, "EvalVariable() returned an error")
199				assertVariable(t, variable, tc)
200			} else {
201				if err == nil {
202					t.Fatalf("Expected error %s, got no error: %s\n", tc.err.Error(), api.ConvertVar(variable).SinglelineString())
203				}
204				if tc.err.Error() != err.Error() {
205					t.Fatalf("Unexpected error. Expected %s got %s", tc.err.Error(), err.Error())
206				}
207			}
208
209			if tc.alternate != "" && testBackend != "rr" {
210				assertNoError(setVariable(p, tc.name, tc.alternate), t, "SetVariable()")
211				variable, err = evalVariable(p, tc.name, pnormalLoadConfig)
212				assertNoError(err, t, "EvalVariable()")
213				assertVariable(t, variable, tc.alternateVarTest())
214
215				assertNoError(setVariable(p, tc.name, tc.value), t, "SetVariable()")
216				variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
217				assertNoError(err, t, "EvalVariable()")
218				assertVariable(t, variable, tc)
219			}
220		}
221	})
222}
223
224func TestSetVariable(t *testing.T) {
225	var testcases = []struct {
226		name     string
227		typ      string // type of <name>
228		startVal string // original value of <name>
229		expr     string
230		finalVal string // new value of <name> after executing <name> = <expr>
231	}{
232		{"b.ptr", "*main.A", "*main.A {val: 1337}", "nil", "*main.A nil"},
233		{"m2", "map[int]*main.astruct", "map[int]*main.astruct [1: *{A: 10, B: 11}, ]", "nil", "map[int]*main.astruct nil"},
234		{"fn1", "main.functype", "main.afunc", "nil", "nil"},
235		{"ch1", "chan int", "chan int 4/10", "nil", "chan int nil"},
236		{"s2", "[]main.astruct", "[]main.astruct len: 8, cap: 8, [{A: 1, B: 2},{A: 3, B: 4},{A: 5, B: 6},{A: 7, B: 8},{A: 9, B: 10},{A: 11, B: 12},{A: 13, B: 14},{A: 15, B: 16}]", "nil", "[]main.astruct len: 0, cap: 0, nil"},
237		{"err1", "error", "error(*main.astruct) *{A: 1, B: 2}", "nil", "error nil"},
238		{"s1[0]", "string", `"one"`, `""`, `""`},
239		{"as1", "main.astruct", "main.astruct {A: 1, B: 1}", `m1["Malone"]`, "main.astruct {A: 2, B: 3}"},
240
241		{"iface1", "interface {}", "interface {}(*main.astruct) *{A: 1, B: 2}", "nil", "interface {} nil"},
242		{"iface1", "interface {}", "interface {} nil", "iface2", "interface {}(string) \"test\""},
243		{"iface1", "interface {}", "interface {}(string) \"test\"", "parr", "interface {}(*[4]int) *[0,1,2,3]"},
244
245		{"s3", "[]int", `[]int len: 0, cap: 6, []`, "s4[2:5]", "[]int len: 3, cap: 3, [3,4,5]"},
246		{"s3", "[]int", "[]int len: 3, cap: 3, [3,4,5]", "arr1[:]", "[]int len: 4, cap: 4, [0,1,2,3]"},
247	}
248
249	withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
250		assertNoError(proc.Continue(p), t, "Continue()")
251
252		for _, tc := range testcases {
253			if tc.name == "iface1" && tc.expr == "parr" {
254				if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) {
255					// conversion pointer -> eface not supported prior to Go 1.11
256					continue
257				}
258			}
259			variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
260			assertNoError(err, t, "EvalVariable()")
261			assertVariable(t, variable, varTest{tc.name, true, tc.startVal, "", tc.typ, nil})
262
263			assertNoError(setVariable(p, tc.name, tc.expr), t, "SetVariable()")
264
265			variable, err = evalVariable(p, tc.name, pnormalLoadConfig)
266			assertNoError(err, t, "EvalVariable()")
267			assertVariable(t, variable, varTest{tc.name, true, tc.finalVal, "", tc.typ, nil})
268		}
269	})
270}
271
272func TestVariableEvaluationShort(t *testing.T) {
273	testcases := []varTest{
274		{"a1", true, "\"foofoofoofoofoofoo\"", "", "string", nil},
275		{"a11", true, "[3]main.FooBar [...]", "", "[3]main.FooBar", nil},
276		{"a12", true, "[]main.FooBar len: 2, cap: 2, [...]", "", "[]main.FooBar", nil},
277		{"a13", true, "[]*main.FooBar len: 3, cap: 3, [...]", "", "[]*main.FooBar", nil},
278		{"a2", true, "6", "", "int", nil},
279		{"a3", true, "7.23", "", "float64", nil},
280		{"a4", true, "[2]int [...]", "", "[2]int", nil},
281		{"a5", true, "[]int len: 5, cap: 5, [...]", "", "[]int", nil},
282		{"a6", true, "main.FooBar {Baz: 8, Bur: \"word\"}", "", "main.FooBar", nil},
283		{"a7", true, "(*main.FooBar)(0x…", "", "*main.FooBar", nil},
284		{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil},
285		{"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil},
286		{"baz", true, "\"bazburzum\"", "", "string", nil},
287		{"neg", true, "-1", "", "int", nil},
288		{"f32", true, "1.2", "", "float32", nil},
289		{"c64", true, "(1 + 2i)", "", "complex64", nil},
290		{"c128", true, "(2 + 3i)", "", "complex128", nil},
291		{"a6.Baz", true, "8", "", "int", nil},
292		{"a7.Baz", true, "5", "", "int", nil},
293		{"a8.Baz", true, "\"feh\"", "", "string", nil},
294		{"a9.Baz", true, "nil", "", "int", fmt.Errorf("a9 is nil")},
295		{"a9.NonExistent", true, "nil", "", "int", fmt.Errorf("a9 has no member NonExistent")},
296		{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil}, // reread variable after member
297		{"i32", true, "[2]int32 [...]", "", "[2]int32", nil},
298		{"b1", true, "true", "false", "bool", nil},
299		{"b2", true, "false", "true", "bool", nil},
300		{"i8", true, "1", "2", "int8", nil},
301		{"u16", true, "65535", "0", "uint16", nil},
302		{"u32", true, "4294967295", "1", "uint32", nil},
303		{"u64", true, "18446744073709551615", "2", "uint64", nil},
304		{"u8", true, "255", "3", "uint8", nil},
305		{"up", true, "5", "4", "uintptr", nil},
306		{"f", true, "main.barfoo", "", "func()", nil},
307		{"ba", true, "[]int len: 200, cap: 200, [...]", "", "[]int", nil},
308		{"ms", true, "main.Nest {Level: 0, Nest: (*main.Nest)(0x…", "", "main.Nest", nil},
309		{"ms.Nest.Nest", true, "(*main.Nest)(0x…", "", "*main.Nest", nil},
310		{"ms.Nest.Nest.Nest.Nest.Nest", true, "*main.Nest nil", "", "*main.Nest", nil},
311		{"ms.Nest.Nest.Nest.Nest.Nest.Nest", true, "", "", "*main.Nest", fmt.Errorf("ms.Nest.Nest.Nest.Nest.Nest is nil")},
312		{"main.p1", true, "10", "", "int", nil},
313		{"p1", true, "10", "", "int", nil},
314		{"NonExistent", true, "", "", "", fmt.Errorf("could not find symbol value for NonExistent")},
315	}
316
317	protest.AllowRecording(t)
318	withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
319		err := proc.Continue(p)
320		assertNoError(err, t, "Continue() returned an error")
321
322		for _, tc := range testcases {
323			variable, err := evalVariable(p, tc.name, pshortLoadConfig)
324			if tc.err == nil {
325				assertNoError(err, t, "EvalVariable() returned an error")
326				assertVariable(t, variable, tc)
327			} else {
328				if err == nil {
329					t.Fatalf("Expected error %s, got no error: %s\n", tc.err.Error(), api.ConvertVar(variable).SinglelineString())
330				}
331				if tc.err.Error() != err.Error() {
332					t.Fatalf("Unexpected error. Expected %s got %s", tc.err.Error(), err.Error())
333				}
334			}
335		}
336	})
337}
338
339func TestMultilineVariableEvaluation(t *testing.T) {
340	testcases := []varTest{
341		{"a1", true, "\"foofoofoofoofoofoo\"", "", "string", nil},
342		{"a11", true, `[3]main.FooBar [
343	{Baz: 1, Bur: "a"},
344	{Baz: 2, Bur: "b"},
345	{Baz: 3, Bur: "c"},
346]`, "", "[3]main.FooBar", nil},
347		{"a12", true, `[]main.FooBar len: 2, cap: 2, [
348	{Baz: 4, Bur: "d"},
349	{Baz: 5, Bur: "e"},
350]`, "", "[]main.FooBar", nil},
351		{"a13", true, `[]*main.FooBar len: 3, cap: 3, [
352	*{Baz: 6, Bur: "f"},
353	*{Baz: 7, Bur: "g"},
354	*{Baz: 8, Bur: "h"},
355]`, "", "[]*main.FooBar", nil},
356		{"a2", true, "6", "10", "int", nil},
357		{"a4", true, "[2]int [1,2]", "", "[2]int", nil},
358		{"a5", true, "[]int len: 5, cap: 5, [1,2,3,4,5]", "", "[]int", nil},
359		{"a6", true, "main.FooBar {Baz: 8, Bur: \"word\"}", "", "main.FooBar", nil},
360		{"a7", true, "*main.FooBar {Baz: 5, Bur: \"strum\"}", "", "*main.FooBar", nil},
361		{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil},
362		{"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil},
363		{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil}, // reread variable after member
364		{"i32", true, "[2]int32 [1,2]", "", "[2]int32", nil},
365		{"ba", true, "[]int len: 200, cap: 200, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+136 more]", "", "[]int", nil},
366		{"ms", true, `main.Nest {
367	Level: 0,
368	Nest: *main.Nest {
369		Level: 1,
370		Nest: *(*main.Nest)(…`, "", "main.Nest", nil},
371	}
372
373	protest.AllowRecording(t)
374	withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
375		err := proc.Continue(p)
376		assertNoError(err, t, "Continue() returned an error")
377
378		for _, tc := range testcases {
379			variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
380			assertNoError(err, t, "EvalVariable() returned an error")
381			if ms := api.ConvertVar(variable).MultilineString(""); !matchStringOrPrefix(ms, tc.value) {
382				t.Fatalf("Expected %s got %s (variable %s)\n", tc.value, ms, variable.Name)
383			}
384		}
385	})
386}
387
388type varArray []*proc.Variable
389
390// Len is part of sort.Interface.
391func (s varArray) Len() int {
392	return len(s)
393}
394
395// Swap is part of sort.Interface.
396func (s varArray) Swap(i, j int) {
397	s[i], s[j] = s[j], s[i]
398}
399
400// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
401func (s varArray) Less(i, j int) bool {
402	return s[i].Name < s[j].Name
403}
404
405func TestLocalVariables(t *testing.T) {
406	testcases := []struct {
407		fn     func(*proc.EvalScope, proc.LoadConfig) ([]*proc.Variable, error)
408		output []varTest
409	}{
410		{(*proc.EvalScope).LocalVariables,
411			[]varTest{
412				{"a1", true, "\"foofoofoofoofoofoo\"", "", "string", nil},
413				{"a10", true, "\"ofo\"", "", "string", nil},
414				{"a11", true, "[3]main.FooBar [{Baz: 1, Bur: \"a\"},{Baz: 2, Bur: \"b\"},{Baz: 3, Bur: \"c\"}]", "", "[3]main.FooBar", nil},
415				{"a12", true, "[]main.FooBar len: 2, cap: 2, [{Baz: 4, Bur: \"d\"},{Baz: 5, Bur: \"e\"}]", "", "[]main.FooBar", nil},
416				{"a13", true, "[]*main.FooBar len: 3, cap: 3, [*{Baz: 6, Bur: \"f\"},*{Baz: 7, Bur: \"g\"},*{Baz: 8, Bur: \"h\"}]", "", "[]*main.FooBar", nil},
417				{"a2", true, "6", "", "int", nil},
418				{"a3", true, "7.23", "", "float64", nil},
419				{"a4", true, "[2]int [1,2]", "", "[2]int", nil},
420				{"a5", true, "[]int len: 5, cap: 5, [1,2,3,4,5]", "", "[]int", nil},
421				{"a6", true, "main.FooBar {Baz: 8, Bur: \"word\"}", "", "main.FooBar", nil},
422				{"a7", true, "*main.FooBar {Baz: 5, Bur: \"strum\"}", "", "*main.FooBar", nil},
423				{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil},
424				{"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil},
425				{"b1", true, "true", "", "bool", nil},
426				{"b2", true, "false", "", "bool", nil},
427				{"ba", true, "[]int len: 200, cap: 200, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+136 more]", "", "[]int", nil},
428				{"c128", true, "(2 + 3i)", "", "complex128", nil},
429				{"c64", true, "(1 + 2i)", "", "complex64", nil},
430				{"f", true, "main.barfoo", "", "func()", nil},
431				{"f32", true, "1.2", "", "float32", nil},
432				{"i32", true, "[2]int32 [1,2]", "", "[2]int32", nil},
433				{"i8", true, "1", "", "int8", nil},
434				{"ms", true, "main.Nest {Level: 0, Nest: *main.Nest {Level: 1, Nest: *(*main.Nest)…", "", "main.Nest", nil},
435				{"neg", true, "-1", "", "int", nil},
436				{"u16", true, "65535", "", "uint16", nil},
437				{"u32", true, "4294967295", "", "uint32", nil},
438				{"u64", true, "18446744073709551615", "", "uint64", nil},
439				{"u8", true, "255", "", "uint8", nil},
440				{"up", true, "5", "", "uintptr", nil}}},
441		{(*proc.EvalScope).FunctionArguments,
442			[]varTest{
443				{"bar", true, "main.FooBar {Baz: 10, Bur: \"lorem\"}", "", "main.FooBar", nil},
444				{"baz", true, "\"bazburzum\"", "", "string", nil}}},
445	}
446
447	protest.AllowRecording(t)
448	withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
449		err := proc.Continue(p)
450		assertNoError(err, t, "Continue() returned an error")
451
452		for _, tc := range testcases {
453			var scope *proc.EvalScope
454			var err error
455
456			if testBackend == "rr" {
457				var frame proc.Stackframe
458				frame, err = findFirstNonRuntimeFrame(p)
459				if err == nil {
460					scope = proc.FrameToScope(p.BinInfo(), p.CurrentThread(), nil, frame)
461				}
462			} else {
463				scope, err = proc.GoroutineScope(p.CurrentThread())
464			}
465
466			assertNoError(err, t, "scope")
467			vars, err := tc.fn(scope, pnormalLoadConfig)
468			assertNoError(err, t, "LocalVariables() returned an error")
469
470			sort.Sort(varArray(vars))
471
472			if len(tc.output) != len(vars) {
473				t.Fatalf("Invalid variable count. Expected %d got %d.", len(tc.output), len(vars))
474			}
475
476			for i, variable := range vars {
477				assertVariable(t, variable, tc.output[i])
478			}
479		}
480	})
481}
482
483func TestEmbeddedStruct(t *testing.T) {
484	protest.AllowRecording(t)
485	withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
486		testcases := []varTest{
487			{"b.val", true, "-314", "-314", "int", nil},
488			{"b.A.val", true, "-314", "-314", "int", nil},
489			{"b.a.val", true, "42", "42", "int", nil},
490			{"b.ptr.val", true, "1337", "1337", "int", nil},
491			{"b.C.s", true, "\"hello\"", "\"hello\"", "string", nil},
492			{"b.s", true, "\"hello\"", "\"hello\"", "string", nil},
493			{"b2", true, "main.B {A: main.A {val: 42}, C: *main.C nil, a: main.A {val: 47}, ptr: *main.A nil}", "main.B {A: (*main.A)(0x…", "main.B", nil},
494		}
495		assertNoError(proc.Continue(p), t, "Continue()")
496
497		ver, _ := goversion.Parse(runtime.Version())
498		if ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
499			// on go < 1.9 embedded fields had different names
500			for i := range testcases {
501				if testcases[i].name == "b2" {
502					testcases[i].value = "main.B {main.A: main.A {val: 42}, *main.C: *main.C nil, a: main.A {val: 47}, ptr: *main.A nil}"
503					testcases[i].alternate = "main.B {main.A: (*main.A)(0x…"
504				}
505			}
506		}
507
508		for _, tc := range testcases {
509			variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
510			if tc.err == nil {
511				assertNoError(err, t, fmt.Sprintf("EvalVariable(%s) returned an error", tc.name))
512				assertVariable(t, variable, tc)
513				variable, err = evalVariable(p, tc.name, pshortLoadConfig)
514				assertNoError(err, t, fmt.Sprintf("EvalVariable(%s, pshortLoadConfig) returned an error", tc.name))
515				assertVariable(t, variable, tc.alternateVarTest())
516			} else {
517				if tc.err.Error() != err.Error() {
518					t.Fatalf("Unexpected error. Expected %s got %s", tc.err.Error(), err.Error())
519				}
520			}
521		}
522	})
523}
524
525func TestComplexSetting(t *testing.T) {
526	withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
527		err := proc.Continue(p)
528		assertNoError(err, t, "Continue() returned an error")
529
530		h := func(setExpr, value string) {
531			assertNoError(setVariable(p, "c128", setExpr), t, "SetVariable()")
532			variable, err := evalVariable(p, "c128", pnormalLoadConfig)
533			assertNoError(err, t, "EvalVariable()")
534			if s := api.ConvertVar(variable).SinglelineString(); s != value {
535				t.Fatalf("Wrong value of c128: \"%s\", expected \"%s\" after setting it to \"%s\"", s, value, setExpr)
536			}
537		}
538
539		h("3.2i", "(0 + 3.2i)")
540		h("1.1", "(1.1 + 0i)")
541		h("1 + 3.3i", "(1 + 3.3i)")
542		h("complex(1.2, 3.4)", "(1.2 + 3.4i)")
543	})
544}
545
546func TestEvalExpression(t *testing.T) {
547	testcases := []varTest{
548		// slice/array/string subscript
549		{"s1[0]", false, "\"one\"", "\"one\"", "string", nil},
550		{"s1[1]", false, "\"two\"", "\"two\"", "string", nil},
551		{"s1[2]", false, "\"three\"", "\"three\"", "string", nil},
552		{"s1[3]", false, "\"four\"", "\"four\"", "string", nil},
553		{"s1[4]", false, "\"five\"", "\"five\"", "string", nil},
554		{"s1[5]", false, "", "", "string", fmt.Errorf("index out of bounds")},
555		{"a1[0]", false, "\"one\"", "\"one\"", "string", nil},
556		{"a1[1]", false, "\"two\"", "\"two\"", "string", nil},
557		{"a1[2]", false, "\"three\"", "\"three\"", "string", nil},
558		{"a1[3]", false, "\"four\"", "\"four\"", "string", nil},
559		{"a1[4]", false, "\"five\"", "\"five\"", "string", nil},
560		{"a1[5]", false, "", "", "string", fmt.Errorf("index out of bounds")},
561		{"str1[0]", false, "48", "48", "byte", nil},
562		{"str1[1]", false, "49", "49", "byte", nil},
563		{"str1[2]", false, "50", "50", "byte", nil},
564		{"str1[10]", false, "48", "48", "byte", nil},
565		{"str1[11]", false, "", "", "byte", fmt.Errorf("index out of bounds")},
566
567		// slice/array/string reslicing
568		{"a1[2:4]", false, "[]string len: 2, cap: 2, [\"three\",\"four\"]", "[]string len: 2, cap: 2, [...]", "[]string", nil},
569		{"s1[2:4]", false, "[]string len: 2, cap: 2, [\"three\",\"four\"]", "[]string len: 2, cap: 2, [...]", "[]string", nil},
570		{"str1[2:4]", false, "\"23\"", "\"23\"", "string", nil},
571		{"str1[0:11]", false, "\"01234567890\"", "\"01234567890\"", "string", nil},
572		{"str1[:3]", false, "\"012\"", "\"012\"", "string", nil},
573		{"str1[3:]", false, "\"34567890\"", "\"34567890\"", "string", nil},
574		{"str1[0:12]", false, "", "", "string", fmt.Errorf("index out of bounds")},
575		{"str1[5:3]", false, "", "", "string", fmt.Errorf("index out of bounds")},
576
577		// NaN and Inf floats
578		{"pinf", false, "+Inf", "+Inf", "float64", nil},
579		{"ninf", false, "-Inf", "-Inf", "float64", nil},
580		{"nan", false, "NaN", "NaN", "float64", nil},
581
582		// pointers
583		{"*p2", false, "5", "5", "int", nil},
584		{"p2", true, "*5", "(*int)(0x…", "*int", nil},
585		{"p3", true, "*int nil", "*int nil", "*int", nil},
586		{"*p3", false, "", "", "int", fmt.Errorf("nil pointer dereference")},
587
588		// channels
589		{"ch1", true, "chan int 4/10", "chan int 4/10", "chan int", nil},
590		{"chnil", true, "chan int nil", "chan int nil", "chan int", nil},
591		{"ch1+1", false, "", "", "", fmt.Errorf("can not convert 1 constant to chan int")},
592
593		// maps
594		{"m1[\"Malone\"]", false, "main.astruct {A: 2, B: 3}", "main.astruct {A: 2, B: 3}", "main.astruct", nil},
595		{"m2[1].B", false, "11", "11", "int", nil},
596		{"m2[c1.sa[2].B-4].A", false, "10", "10", "int", nil},
597		{"m2[*p1].B", false, "11", "11", "int", nil},
598		{"m3[as1]", false, "42", "42", "int", nil},
599		{"mnil[\"Malone\"]", false, "", "", "", fmt.Errorf("key not found")},
600		{"m1[80:]", false, "", "", "", fmt.Errorf("map index out of bounds")},
601
602		// interfaces
603		{"err1", true, "error(*main.astruct) *{A: 1, B: 2}", "error(*main.astruct) 0x…", "error", nil},
604		{"err2", true, "error(*main.bstruct) *{a: main.astruct {A: 1, B: 2}}", "error(*main.bstruct) 0x…", "error", nil},
605		{"errnil", true, "error nil", "error nil", "error", nil},
606		{"iface1", true, "interface {}(*main.astruct) *{A: 1, B: 2}", "interface {}(*main.astruct) 0x…", "interface {}", nil},
607		{"iface1.A", false, "1", "1", "int", nil},
608		{"iface1.B", false, "2", "2", "int", nil},
609		{"iface2", true, "interface {}(string) \"test\"", "interface {}(string) \"test\"", "interface {}", nil},
610		{"iface3", true, "interface {}(map[string]go/constant.Value) []", "interface {}(map[string]go/constant.Value) []", "interface {}", nil},
611		{"iface4", true, "interface {}([]go/constant.Value) [4]", "interface {}([]go/constant.Value) [...]", "interface {}", nil},
612		{"ifacenil", true, "interface {} nil", "interface {} nil", "interface {}", nil},
613		{"err1 == err2", false, "false", "false", "", nil},
614		{"err1 == iface1", false, "", "", "", fmt.Errorf("mismatched types \"error\" and \"interface {}\"")},
615		{"errnil == nil", false, "true", "true", "", nil},
616		{"errtypednil == nil", false, "false", "false", "", nil},
617		{"nil == errnil", false, "true", "true", "", nil},
618		{"err1.(*main.astruct)", false, "*main.astruct {A: 1, B: 2}", "(*main.astruct)(0x…", "*main.astruct", nil},
619		{"err1.(*main.bstruct)", false, "", "", "", fmt.Errorf("interface conversion: error is *main.astruct, not *main.bstruct")},
620		{"errnil.(*main.astruct)", false, "", "", "", fmt.Errorf("interface conversion: error is nil, not *main.astruct")},
621		{"const1", true, "go/constant.Value(go/constant.int64Val) 3", "go/constant.Value(go/constant.int64Val) 3", "go/constant.Value", nil},
622
623		// combined expressions
624		{"c1.pb.a.A", true, "1", "1", "int", nil},
625		{"c1.sa[1].B", false, "3", "3", "int", nil},
626		{"s2[5].B", false, "12", "12", "int", nil},
627		{"s2[c1.sa[2].B].A", false, "11", "11", "int", nil},
628		{"s2[*p2].B", false, "12", "12", "int", nil},
629
630		// constants
631		{"1.1", false, "1.1", "1.1", "", nil},
632		{"10", false, "10", "10", "", nil},
633		{"1 + 2i", false, "(1 + 2i)", "(1 + 2i)", "", nil},
634		{"true", false, "true", "true", "", nil},
635		{"\"test\"", false, "\"test\"", "\"test\"", "", nil},
636
637		// binary operators
638		{"i2 + i3", false, "5", "5", "int", nil},
639		{"i2 - i3", false, "-1", "-1", "int", nil},
640		{"i3 - i2", false, "1", "1", "int", nil},
641		{"i2 * i3", false, "6", "6", "int", nil},
642		{"i2/i3", false, "0", "0", "int", nil},
643		{"f1/2.0", false, "1.5", "1.5", "float64", nil},
644		{"i2 << 2", false, "8", "8", "int", nil},
645
646		// unary operators
647		{"-i2", false, "-2", "-2", "int", nil},
648		{"+i2", false, "2", "2", "int", nil},
649		{"^i2", false, "-3", "-3", "int", nil},
650
651		// comparison operators
652		{"i2 == i3", false, "false", "false", "", nil},
653		{"i2 == 2", false, "true", "true", "", nil},
654		{"i2 == 2", false, "true", "true", "", nil},
655		{"i2 == 3", false, "false", "false", "", nil},
656		{"i2 != i3", false, "true", "true", "", nil},
657		{"i2 < i3", false, "true", "true", "", nil},
658		{"i2 <= i3", false, "true", "true", "", nil},
659		{"i2 > i3", false, "false", "false", "", nil},
660		{"i2 >= i3", false, "false", "false", "", nil},
661		{"i2 >= 2", false, "true", "true", "", nil},
662		{"str1 == \"01234567890\"", false, "true", "true", "", nil},
663		{"str1 < \"01234567890\"", false, "false", "false", "", nil},
664		{"str1 < \"11234567890\"", false, "true", "true", "", nil},
665		{"str1 > \"00234567890\"", false, "true", "true", "", nil},
666		{"str1 == str1", false, "true", "true", "", nil},
667		{"c1.pb.a == *(c1.sa[0])", false, "true", "true", "", nil},
668		{"c1.pb.a != *(c1.sa[0])", false, "false", "false", "", nil},
669		{"c1.pb.a == *(c1.sa[1])", false, "false", "false", "", nil},
670		{"c1.pb.a != *(c1.sa[1])", false, "true", "true", "", nil},
671		{`longstr == "not this"`, false, "false", "false", "", nil},
672
673		// builtins
674		{"cap(parr)", false, "4", "4", "", nil},
675		{"len(parr)", false, "4", "4", "", nil},
676		{"cap(p1)", false, "", "", "", fmt.Errorf("invalid argument p1 (type *int) for cap")},
677		{"len(p1)", false, "", "", "", fmt.Errorf("invalid argument p1 (type *int) for len")},
678		{"cap(a1)", false, "5", "5", "", nil},
679		{"len(a1)", false, "5", "5", "", nil},
680		{"cap(s3)", false, "6", "6", "", nil},
681		{"len(s3)", false, "0", "0", "", nil},
682		{"cap(nilslice)", false, "0", "0", "", nil},
683		{"len(nilslice)", false, "0", "0", "", nil},
684		{"cap(ch1)", false, "10", "10", "", nil},
685		{"len(ch1)", false, "4", "4", "", nil},
686		{"cap(chnil)", false, "0", "0", "", nil},
687		{"len(chnil)", false, "0", "0", "", nil},
688		{"len(m1)", false, "41", "41", "", nil},
689		{"len(mnil)", false, "0", "0", "", nil},
690		{"imag(cpx1)", false, "2", "2", "", nil},
691		{"real(cpx1)", false, "1", "1", "", nil},
692		{"imag(3i)", false, "3", "3", "", nil},
693		{"real(4)", false, "4", "4", "", nil},
694
695		// nil
696		{"nil", false, "nil", "nil", "", nil},
697		{"nil+1", false, "", "", "", fmt.Errorf("operator + can not be applied to \"nil\"")},
698		{"fn1", false, "main.afunc", "main.afunc", "main.functype", nil},
699		{"fn2", false, "nil", "nil", "main.functype", nil},
700		{"nilslice", false, "[]int len: 0, cap: 0, nil", "[]int len: 0, cap: 0, nil", "[]int", nil},
701		{"fn1 == fn2", false, "", "", "", fmt.Errorf("can not compare func variables")},
702		{"fn1 == nil", false, "false", "false", "", nil},
703		{"fn1 != nil", false, "true", "true", "", nil},
704		{"fn2 == nil", false, "true", "true", "", nil},
705		{"fn2 != nil", false, "false", "false", "", nil},
706		{"c1.sa == nil", false, "false", "false", "", nil},
707		{"c1.sa != nil", false, "true", "true", "", nil},
708		{"c1.sa[0] == nil", false, "false", "false", "", nil},
709		{"c1.sa[0] != nil", false, "true", "true", "", nil},
710		{"nilslice == nil", false, "true", "true", "", nil},
711		{"nil == nilslice", false, "true", "true", "", nil},
712		{"nilslice != nil", false, "false", "false", "", nil},
713		{"nilptr == nil", false, "true", "true", "", nil},
714		{"nilptr != nil", false, "false", "false", "", nil},
715		{"p1 == nil", false, "false", "false", "", nil},
716		{"p1 != nil", false, "true", "true", "", nil},
717		{"ch1 == nil", false, "false", "false", "", nil},
718		{"chnil == nil", false, "true", "true", "", nil},
719		{"ch1 == chnil", false, "", "", "", fmt.Errorf("can not compare chan variables")},
720		{"m1 == nil", false, "false", "false", "", nil},
721		{"mnil == m1", false, "", "", "", fmt.Errorf("can not compare map variables")},
722		{"mnil == nil", false, "true", "true", "", nil},
723		{"nil == 2", false, "", "", "", fmt.Errorf("can not compare int to nil")},
724		{"2 == nil", false, "", "", "", fmt.Errorf("can not compare int to nil")},
725
726		// errors
727		{"&3", false, "", "", "", fmt.Errorf("can not take address of \"3\"")},
728		{"*3", false, "", "", "", fmt.Errorf("expression \"3\" (int) can not be dereferenced")},
729		{"&(i2 + i3)", false, "", "", "", fmt.Errorf("can not take address of \"(i2 + i3)\"")},
730		{"i2 + p1", false, "", "", "", fmt.Errorf("mismatched types \"int\" and \"*int\"")},
731		{"i2 + f1", false, "", "", "", fmt.Errorf("mismatched types \"int\" and \"float64\"")},
732		{"i2 << f1", false, "", "", "", fmt.Errorf("shift count type float64, must be unsigned integer")},
733		{"i2 << -1", false, "", "", "", fmt.Errorf("shift count type int, must be unsigned integer")},
734		{"i2 << i3", false, "", "", "int", fmt.Errorf("shift count type int, must be unsigned integer")},
735		{"*(i2 + i3)", false, "", "", "", fmt.Errorf("expression \"(i2 + i3)\" (int) can not be dereferenced")},
736		{"i2.member", false, "", "", "", fmt.Errorf("i2 (type int) is not a struct")},
737		{"fmt.Println(\"hello\")", false, "", "", "", fmt.Errorf("no type entry found, use 'types' for a list of valid types")},
738		{"*nil", false, "", "", "", fmt.Errorf("nil can not be dereferenced")},
739		{"!nil", false, "", "", "", fmt.Errorf("operator ! can not be applied to \"nil\"")},
740		{"&nil", false, "", "", "", fmt.Errorf("can not take address of \"nil\"")},
741		{"nil[0]", false, "", "", "", fmt.Errorf("expression \"nil\" (nil) does not support indexing")},
742		{"nil[2:10]", false, "", "", "", fmt.Errorf("can not slice \"nil\" (type nil)")},
743		{"nil.member", false, "", "", "", fmt.Errorf("nil (type nil) is not a struct")},
744		{"(map[string]main.astruct)(0x4000)", false, "", "", "", fmt.Errorf("can not convert \"0x4000\" to map[string]main.astruct")},
745
746		// typecasts
747		{"uint(i2)", false, "2", "2", "uint", nil},
748		{"int8(i2)", false, "2", "2", "int8", nil},
749		{"int(f1)", false, "3", "3", "int", nil},
750		{"complex128(f1)", false, "(3 + 0i)", "(3 + 0i)", "complex128", nil},
751		{"uint8(i4)", false, "32", "32", "uint8", nil},
752		{"uint8(i5)", false, "253", "253", "uint8", nil},
753		{"int8(i5)", false, "-3", "-3", "int8", nil},
754		{"int8(i6)", false, "12", "12", "int8", nil},
755		{"string(byteslice[0])", false, `"t"`, `"t"`, "string", nil},
756		{"string(runeslice[0])", false, `"t"`, `"t"`, "string", nil},
757
758		// misc
759		{"i1", true, "1", "1", "int", nil},
760		{"mainMenu", true, `main.Menu len: 3, cap: 3, [{Name: "home", Route: "/", Active: 1},{Name: "About", Route: "/about", Active: 1},{Name: "Login", Route: "/login", Active: 1}]`, `main.Menu len: 3, cap: 3, [...]`, "main.Menu", nil},
761		{"mainMenu[0]", false, `main.Item {Name: "home", Route: "/", Active: 1}`, `main.Item {Name: "home", Route: "/", Active: 1}`, "main.Item", nil},
762		{"sd", false, "main.D {u1: 0, u2: 0, u3: 0, u4: 0, u5: 0, u6: 0}", "main.D {u1: 0, u2: 0, u3: 0,...+3 more}", "main.D", nil},
763
764		{"ifacearr", false, "[]error len: 2, cap: 2, [*main.astruct {A: 0, B: 0},nil]", "[]error len: 2, cap: 2, [...]", "[]error", nil},
765		{"efacearr", false, `[]interface {} len: 3, cap: 3, [*main.astruct {A: 0, B: 0},"test",nil]`, "[]interface {} len: 3, cap: 3, [...]", "[]interface {}", nil},
766
767		{"zsslice", false, `[]struct {} len: 3, cap: 3, [{},{},{}]`, `[]struct {} len: 3, cap: 3, [...]`, "[]struct {}", nil},
768		{"zsvmap", false, `map[string]struct {} ["testkey": {}, ]`, `map[string]struct {} [...]`, "map[string]struct {}", nil},
769		{"tm", false, "main.truncatedMap {v: []map[string]main.astruct len: 1, cap: 1, [[...]]}", "main.truncatedMap {v: []map[string]main.astruct len: 1, cap: 1, [...]}", "main.truncatedMap", nil},
770
771		{"emptyslice", false, `[]string len: 0, cap: 0, []`, `[]string len: 0, cap: 0, []`, "[]string", nil},
772		{"emptymap", false, `map[string]string []`, `map[string]string []`, "map[string]string", nil},
773		{"mnil", false, `map[string]main.astruct nil`, `map[string]main.astruct nil`, "map[string]main.astruct", nil},
774
775		// conversions between string/[]byte/[]rune (issue #548)
776		{"runeslice", true, `[]int32 len: 4, cap: 4, [116,232,115,116]`, `[]int32 len: 4, cap: 4, [...]`, "[]int32", nil},
777		{"byteslice", true, `[]uint8 len: 5, cap: 5, [116,195,168,115,116]`, `[]uint8 len: 5, cap: 5, [...]`, "[]uint8", nil},
778		{"[]byte(str1)", false, `[]uint8 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, `[]uint8 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, "[]uint8", nil},
779		{"[]uint8(str1)", false, `[]uint8 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, `[]uint8 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, "[]uint8", nil},
780		{"[]rune(str1)", false, `[]int32 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, `[]int32 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, "[]int32", nil},
781		{"[]int32(str1)", false, `[]int32 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, `[]int32 len: 11, cap: 11, [48,49,50,51,52,53,54,55,56,57,48]`, "[]int32", nil},
782		{"string(byteslice)", false, `"tèst"`, `""`, "string", nil},
783		{"[]int32(string(byteslice))", false, `[]int32 len: 4, cap: 4, [116,232,115,116]`, `[]int32 len: 0, cap: 0, nil`, "[]int32", nil},
784		{"string(runeslice)", false, `"tèst"`, `""`, "string", nil},
785		{"[]byte(string(runeslice))", false, `[]uint8 len: 5, cap: 5, [116,195,168,115,116]`, `[]uint8 len: 0, cap: 0, nil`, "[]uint8", nil},
786		{"*(*[5]byte)(uintptr(&byteslice[0]))", false, `[5]uint8 [116,195,168,115,116]`, `[5]uint8 [...]`, "[5]uint8", nil},
787		{"string(bytearray)", false, `"tèst"`, `""`, "string", nil},
788		{"string(runearray)", false, `"tèst"`, `""`, "string", nil},
789		{"string(str1)", false, `"01234567890"`, `"01234567890"`, "string", nil},
790
791		// access to channel field members
792		{"ch1.qcount", false, "4", "4", "uint", nil},
793		{"ch1.dataqsiz", false, "10", "10", "uint", nil},
794		{"ch1.buf", false, `*[10]int [1,4,3,2,0,0,0,0,0,0]`, `(*[10]int)(…`, "*[10]int", nil},
795		{"ch1.buf[0]", false, "1", "1", "int", nil},
796
797		// shortcircuited logical operators
798		{"nilstruct != nil && nilstruct.A == 1", false, "false", "false", "", nil},
799		{"nilstruct == nil || nilstruct.A == 1", false, "true", "true", "", nil},
800
801		{"afunc", true, `main.afunc`, `main.afunc`, `func()`, nil},
802		{"main.afunc2", true, `main.afunc2`, `main.afunc2`, `func()`, nil},
803
804		{"s2[0].Error", false, "main.(*astruct).Error", "main.(*astruct).Error", "func() string", nil},
805		{"s2[0].NonPointerRecieverMethod", false, "main.astruct.NonPointerRecieverMethod", "main.astruct.NonPointerRecieverMethod", "func()", nil},
806		{"as2.Error", false, "main.(*astruct).Error", "main.(*astruct).Error", "func() string", nil},
807		{"as2.NonPointerRecieverMethod", false, "main.astruct.NonPointerRecieverMethod", "main.astruct.NonPointerRecieverMethod", "func()", nil},
808
809		{`iface2map.(data)`, false, "…", "…", "map[string]interface {}", nil},
810	}
811
812	ver, _ := goversion.Parse(runtime.Version())
813	if ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
814		for i := range testcases {
815			if testcases[i].name == "iface3" {
816				testcases[i].value = "interface {}(*map[string]go/constant.Value) *[]"
817				testcases[i].alternate = "interface {}(*map[string]go/constant.Value) 0x…"
818			}
819		}
820	}
821
822	protest.AllowRecording(t)
823	withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
824		assertNoError(proc.Continue(p), t, "Continue() returned an error")
825		for _, tc := range testcases {
826			variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
827			if err != nil && err.Error() == "evaluating methods not supported on this version of Go" {
828				// this type of eval is unsupported with the current version of Go.
829				continue
830			}
831			if tc.err == nil {
832				assertNoError(err, t, fmt.Sprintf("EvalExpression(%s) returned an error", tc.name))
833				assertVariable(t, variable, tc)
834				variable, err := evalVariable(p, tc.name, pshortLoadConfig)
835				assertNoError(err, t, fmt.Sprintf("EvalExpression(%s, pshortLoadConfig) returned an error", tc.name))
836				assertVariable(t, variable, tc.alternateVarTest())
837			} else {
838				if err == nil {
839					t.Fatalf("Expected error %s, got no error (%s)", tc.err.Error(), tc.name)
840				}
841				if tc.err.Error() != err.Error() {
842					t.Fatalf("Unexpected error. Expected %s got %s", tc.err.Error(), err.Error())
843				}
844			}
845
846		}
847	})
848}
849
850func TestEvalAddrAndCast(t *testing.T) {
851	protest.AllowRecording(t)
852	withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
853		assertNoError(proc.Continue(p), t, "Continue() returned an error")
854		c1addr, err := evalVariable(p, "&c1", pnormalLoadConfig)
855		assertNoError(err, t, "EvalExpression(&c1)")
856		c1addrstr := api.ConvertVar(c1addr).SinglelineString()
857		t.Logf("&c1 → %s", c1addrstr)
858		if !strings.HasPrefix(c1addrstr, "(*main.cstruct)(0x") {
859			t.Fatalf("Invalid value of EvalExpression(&c1) \"%s\"", c1addrstr)
860		}
861
862		aaddr, err := evalVariable(p, "&(c1.pb.a)", pnormalLoadConfig)
863		assertNoError(err, t, "EvalExpression(&(c1.pb.a))")
864		aaddrstr := api.ConvertVar(aaddr).SinglelineString()
865		t.Logf("&(c1.pb.a) → %s", aaddrstr)
866		if !strings.HasPrefix(aaddrstr, "(*main.astruct)(0x") {
867			t.Fatalf("invalid value of EvalExpression(&(c1.pb.a)) \"%s\"", aaddrstr)
868		}
869
870		a, err := evalVariable(p, "*"+aaddrstr, pnormalLoadConfig)
871		assertNoError(err, t, fmt.Sprintf("EvalExpression(*%s)", aaddrstr))
872		t.Logf("*%s → %s", aaddrstr, api.ConvertVar(a).SinglelineString())
873		assertVariable(t, a, varTest{aaddrstr, false, "main.astruct {A: 1, B: 2}", "", "main.astruct", nil})
874	})
875}
876
877func TestMapEvaluation(t *testing.T) {
878	protest.AllowRecording(t)
879	withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
880		assertNoError(proc.Continue(p), t, "Continue() returned an error")
881		m1v, err := evalVariable(p, "m1", pnormalLoadConfig)
882		assertNoError(err, t, "EvalVariable()")
883		m1 := api.ConvertVar(m1v)
884		t.Logf("m1 = %v", m1.MultilineString(""))
885
886		if m1.Type != "map[string]main.astruct" {
887			t.Fatalf("Wrong type: %s", m1.Type)
888		}
889
890		if len(m1.Children)/2 != 41 {
891			t.Fatalf("Wrong number of children: %d", len(m1.Children)/2)
892		}
893
894		found := false
895		for i := range m1.Children {
896			if i%2 == 0 && m1.Children[i].Value == "Malone" {
897				found = true
898			}
899		}
900		if !found {
901			t.Fatalf("Could not find Malone")
902		}
903
904		m1sliced, err := evalVariable(p, "m1[10:]", pnormalLoadConfig)
905		assertNoError(err, t, "EvalVariable(m1[10:])")
906		if len(m1sliced.Children)/2 != int(m1.Len-10) {
907			t.Fatalf("Wrong number of children (after slicing): %d", len(m1sliced.Children)/2)
908		}
909	})
910}
911
912func TestUnsafePointer(t *testing.T) {
913	protest.AllowRecording(t)
914	withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
915		assertNoError(proc.Continue(p), t, "Continue() returned an error")
916		up1v, err := evalVariable(p, "up1", pnormalLoadConfig)
917		assertNoError(err, t, "EvalVariable(up1)")
918		up1 := api.ConvertVar(up1v)
919		if ss := up1.SinglelineString(); !strings.HasPrefix(ss, "unsafe.Pointer(") {
920			t.Fatalf("wrong value for up1: %s", ss)
921		}
922	})
923}
924
925type issue426TestCase struct {
926	name string
927	typ  string
928}
929
930func TestIssue426(t *testing.T) {
931	// type casts using quoted type names
932	testcases := []issue426TestCase{
933		{"iface1", `interface {}`},
934		{"mapanonstruct1", `map[string]struct {}`},
935		{"anonstruct1", `struct { val go/constant.Value }`},
936		{"anonfunc", `func(struct { i int }, interface {}, struct { val go/constant.Value })`},
937		{"anonstruct2", `struct { i int; j int }`},
938		{"anoniface1", `interface { OtherFunction(int, int); SomeFunction(struct { val go/constant.Value }) }`},
939	}
940
941	ver, _ := goversion.Parse(runtime.Version())
942	if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 8, -1, 0, 0, ""}) {
943		testcases[2].typ = `struct { main.val go/constant.Value }`
944		testcases[3].typ = `func(struct { main.i int }, interface {}, struct { main.val go/constant.Value })`
945		testcases[4].typ = `struct { main.i int; main.j int }`
946		testcases[5].typ = `interface { OtherFunction(int, int); SomeFunction(struct { main.val go/constant.Value }) }`
947	}
948
949	// Serialization of type expressions (go/ast.Expr) containing anonymous structs or interfaces
950	// differs from the serialization used by the linker to produce DWARF type information
951	protest.AllowRecording(t)
952	withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
953		assertNoError(proc.Continue(p), t, "Continue() returned an error")
954		for _, testcase := range testcases {
955			v, err := evalVariable(p, testcase.name, pnormalLoadConfig)
956			assertNoError(err, t, fmt.Sprintf("EvalVariable(%s)", testcase.name))
957			t.Logf("%s → %s", testcase.name, v.RealType.String())
958			expr := fmt.Sprintf("(*%q)(%d)", testcase.typ, v.Addr)
959			_, err = evalVariable(p, expr, pnormalLoadConfig)
960			assertNoError(err, t, fmt.Sprintf("EvalVariable(%s)", expr))
961		}
962	})
963}
964
965func TestPackageRenames(t *testing.T) {
966	// Tests that the concrete type of an interface variable is resolved
967	// correctly in a few edge cases, in particular:
968	// - in the presence of renamed imports
969	// - when two packages with the same name are imported
970	// - when a package has a canonical name that's different from its
971	// path (for example the last element of the path contains a '.' or a
972	// '-' or because the package name is different)
973	// all of those edge cases are tested within composite types
974	testcases := []varTest{
975		// Renamed imports
976		{"badexpr", true, `interface {}(*go/ast.BadExpr) *{From: 1, To: 2}`, "", "interface {}", nil},
977		{"req", true, `interface {}(*net/http.Request) *{Method: "amethod", …`, "", "interface {}", nil},
978		{"amap", true, "interface {}(map[go/ast.BadExpr]net/http.Request) [{From: 2, To: 3}: *{Method: \"othermethod\", …", "", "interface {}", nil},
979
980		// Package name that doesn't match import path
981		{"iface3", true, `interface {}(*github.com/derekparker/delve/_fixtures/internal/dir0/renamedpackage.SomeType) *{A: true}`, "", "interface {}", nil},
982
983		// Interfaces to anonymous types
984		{"amap2", true, "interface {}(*map[go/ast.BadExpr]net/http.Request) *[{From: 2, To: 3}: *{Method: \"othermethod\", …", "", "interface {}", nil},
985		{"dir0someType", true, "interface {}(*github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType) *{X: 3}", "", "interface {}", nil},
986		{"dir1someType", true, "interface {}(github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType) {X: 1, Y: 2}", "", "interface {}", nil},
987		{"amap3", true, "interface {}(map[github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType]github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType) [{X: 4}: {X: 5, Y: 6}, ]", "", "interface {}", nil},
988		{"anarray", true, `interface {}([2]github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType) [{X: 1},{X: 2}]`, "", "interface {}", nil},
989		{"achan", true, `interface {}(chan github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType) chan github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType 0/0`, "", "interface {}", nil},
990		{"aslice", true, `interface {}([]github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType) [{X: 3},{X: 4}]`, "", "interface {}", nil},
991		{"afunc", true, `interface {}(func(github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType, github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType)) main.main.func1`, "", "interface {}", nil},
992		{"astruct", true, `interface {}(*struct { A github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType; B github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType }) *{A: github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType {X: 1, Y: 2}, B: github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType {X: 3}}`, "", "interface {}", nil},
993		{"astruct2", true, `interface {}(*struct { github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType; X int }) *{SomeType: github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType {X: 1, Y: 2}, X: 10}`, "", "interface {}", nil},
994		{"iface2iface", true, `interface {}(*interface { AMethod(int) int; AnotherMethod(int) int }) **github.com/derekparker/delve/_fixtures/internal/dir0/pkg.SomeType {X: 4}`, "", "interface {}", nil},
995
996		{`"dir0/pkg".A`, false, "0", "", "int", nil},
997		{`"dir1/pkg".A`, false, "1", "", "int", nil},
998	}
999
1000	ver, _ := goversion.Parse(runtime.Version())
1001	if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
1002		// Not supported on 1.6 or earlier
1003		return
1004	}
1005
1006	protest.AllowRecording(t)
1007	withTestProcess("pkgrenames", t, func(p proc.Process, fixture protest.Fixture) {
1008		assertNoError(proc.Continue(p), t, "Continue() returned an error")
1009		for _, tc := range testcases {
1010			if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
1011				// before 1.9 embedded struct field have fieldname == type
1012				if tc.name == "astruct2" {
1013					tc.value = `interface {}(*struct { github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType; X int }) *{github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType: github.com/derekparker/delve/_fixtures/internal/dir1/pkg.SomeType {X: 1, Y: 2}, X: 10}`
1014				}
1015			}
1016			variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
1017			if tc.err == nil {
1018				assertNoError(err, t, fmt.Sprintf("EvalExpression(%s) returned an error", tc.name))
1019				assertVariable(t, variable, tc)
1020			} else {
1021				if err == nil {
1022					t.Fatalf("Expected error %s, got no error (%s)", tc.err.Error(), tc.name)
1023				}
1024				if tc.err.Error() != err.Error() {
1025					t.Fatalf("Unexpected error. Expected %s got %s", tc.err.Error(), err.Error())
1026				}
1027			}
1028		}
1029	})
1030}
1031
1032func TestConstants(t *testing.T) {
1033	testcases := []varTest{
1034		{"a", true, "constTwo", "", "main.ConstType", nil},
1035		{"b", true, "constThree", "", "main.ConstType", nil},
1036		{"c", true, "bitZero|bitOne", "", "main.BitFieldType", nil},
1037		{"d", true, "33", "", "main.BitFieldType", nil},
1038		{"e", true, "10", "", "main.ConstType", nil},
1039		{"f", true, "0", "", "main.BitFieldType", nil},
1040		{"bitZero", true, "1", "", "main.BitFieldType", nil},
1041		{"bitOne", true, "2", "", "main.BitFieldType", nil},
1042		{"constTwo", true, "2", "", "main.ConstType", nil},
1043		{"pkg.SomeConst", true, "2", "", "int", nil},
1044	}
1045	ver, _ := goversion.Parse(runtime.Version())
1046	if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) {
1047		// Not supported on 1.9 or earlier
1048		t.Skip("constants added in go 1.10")
1049	}
1050	withTestProcess("consts", t, func(p proc.Process, fixture protest.Fixture) {
1051		assertNoError(proc.Continue(p), t, "Continue")
1052		for _, testcase := range testcases {
1053			variable, err := evalVariable(p, testcase.name, pnormalLoadConfig)
1054			assertNoError(err, t, fmt.Sprintf("EvalVariable(%s)", testcase.name))
1055			assertVariable(t, variable, testcase)
1056		}
1057	})
1058}
1059
1060func setFunctionBreakpoint(p proc.Process, fname string) (*proc.Breakpoint, error) {
1061	addr, err := proc.FindFunctionLocation(p, fname, true, 0)
1062	if err != nil {
1063		return nil, err
1064	}
1065	return p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
1066}
1067
1068func TestIssue1075(t *testing.T) {
1069	withTestProcess("clientdo", t, func(p proc.Process, fixture protest.Fixture) {
1070		_, err := setFunctionBreakpoint(p, "net/http.(*Client).Do")
1071		assertNoError(err, t, "setFunctionBreakpoint")
1072		assertNoError(proc.Continue(p), t, "Continue()")
1073		for i := 0; i < 10; i++ {
1074			scope, err := proc.GoroutineScope(p.CurrentThread())
1075			assertNoError(err, t, fmt.Sprintf("GoroutineScope (%d)", i))
1076			vars, err := scope.LocalVariables(pnormalLoadConfig)
1077			assertNoError(err, t, fmt.Sprintf("LocalVariables (%d)", i))
1078			for _, v := range vars {
1079				api.ConvertVar(v).SinglelineString()
1080			}
1081		}
1082	})
1083}
1084
1085func TestCallFunction(t *testing.T) {
1086	protest.MustSupportFunctionCalls(t, testBackend)
1087
1088	var testcases = []struct {
1089		expr string   // call expression to evaluate
1090		outs []string // list of return parameters in this format: <param name>:<param type>:<param value>
1091		err  error    // if not nil should return an error
1092	}{
1093		{"call1(one, two)", []string{":int:3"}, nil},
1094		{"call1(one+two, 4)", []string{":int:7"}, nil},
1095		{"callpanic()", []string{`~panic:interface {}:interface {}(string) "callpanic panicked"`}, nil},
1096		{`stringsJoin(nil, "")`, []string{`:string:""`}, nil},
1097		{`stringsJoin(stringslice, ",")`, nil, errors.New("can not set variables of type string (not implemented)")},
1098		{`stringsJoin(stringslice, comma)`, []string{`:string:"one,two,three"`}, nil},
1099		{`stringsJoin(s1, comma)`, nil, errors.New("could not find symbol value for s1")},
1100		{`stringsJoin(intslice, comma)`, nil, errors.New("can not convert value of type []int to []string")},
1101
1102		// The following set of calls was constructed using https://docs.google.com/document/d/1bMwCey-gmqZVTpRax-ESeVuZGmjwbocYs1iHplK-cjo/pub as a reference
1103
1104		{`a.VRcvr(1)`, []string{`:string:"1 + 3 = 4"`}, nil}, // direct call of a method with value receiver / on a value
1105
1106		{`a.PRcvr(2)`, []string{`:string:"2 - 3 = -1"`}, nil},  // direct call of a method with pointer receiver / on a value
1107		{`pa.VRcvr(3)`, []string{`:string:"3 + 6 = 9"`}, nil},  // direct call of a method with value receiver / on a pointer
1108		{`pa.PRcvr(4)`, []string{`:string:"4 - 6 = -2"`}, nil}, // direct call of a method with pointer receiver / on a pointer
1109
1110		{`vable_pa.VRcvr(6)`, []string{`:string:"6 + 6 = 12"`}, nil}, // indirect call of method on interface / containing value with value method
1111		{`pable_pa.PRcvr(7)`, []string{`:string:"7 - 6 = 1"`}, nil},  // indirect call of method on interface / containing pointer with value method
1112		{`vable_a.VRcvr(5)`, []string{`:string:"5 + 3 = 8"`}, nil},   // indirect call of method on interface / containing pointer with pointer method
1113
1114		{`pa.nonexistent()`, nil, errors.New("pa has no member nonexistent")},
1115		{`a.nonexistent()`, nil, errors.New("a has no member nonexistent")},
1116		{`vable_pa.nonexistent()`, nil, errors.New("vable_pa has no member nonexistent")},
1117		{`vable_a.nonexistent()`, nil, errors.New("vable_a has no member nonexistent")},
1118		{`pable_pa.nonexistent()`, nil, errors.New("pable_pa has no member nonexistent")},
1119
1120		{`fn2glob(10, 20)`, []string{":int:30"}, nil},               // indirect call of func value / set to top-level func
1121		{`fn2clos(11)`, []string{`:string:"1 + 6 + 11 = 18"`}, nil}, // indirect call of func value / set to func literal
1122		{`fn2clos(12)`, []string{`:string:"2 + 6 + 12 = 20"`}, nil},
1123		{`fn2valmeth(13)`, []string{`:string:"13 + 6 = 19"`}, nil}, // indirect call of func value / set to value method
1124		{`fn2ptrmeth(14)`, []string{`:string:"14 - 6 = 8"`}, nil},  // indirect call of func value / set to pointer method
1125
1126		{"fn2nil()", nil, errors.New("nil pointer dereference")},
1127
1128		{"ga.PRcvr(2)", []string{`:string:"2 - 0 = 2"`}, nil},
1129
1130		{"escapeArg(&a2)", nil, errors.New("cannot use &a2 as argument pa2 in function main.escapeArg: stack object passed to escaping pointer: pa2")},
1131
1132		{"-unsafe escapeArg(&a2)", nil, nil}, // LEAVE THIS AS THE LAST ITEM, IT BREAKS THE TARGET PROCESS!!!
1133	}
1134
1135	const unsafePrefix = "-unsafe "
1136
1137	withTestProcess("fncall", t, func(p proc.Process, fixture protest.Fixture) {
1138		_, err := proc.FindFunctionLocation(p, "runtime.debugCallV1", true, 0)
1139		if err != nil {
1140			t.Skip("function calls not supported on this version of go")
1141		}
1142		assertNoError(proc.Continue(p), t, "Continue()")
1143		for _, tc := range testcases {
1144			expr := tc.expr
1145			checkEscape := true
1146			if strings.HasPrefix(expr, unsafePrefix) {
1147				expr = expr[len(unsafePrefix):]
1148				checkEscape = false
1149			}
1150			t.Logf("call %q", tc.expr)
1151			err := proc.CallFunction(p, expr, &pnormalLoadConfig, checkEscape)
1152			if tc.err != nil {
1153
1154				if err == nil {
1155					t.Fatalf("call %q: expected error %q, got no error", tc.expr, tc.err.Error())
1156				}
1157				if tc.err.Error() != err.Error() {
1158					t.Fatalf("call %q: expected error %q, got %q", tc.expr, tc.err.Error(), err.Error())
1159				}
1160				continue
1161			}
1162
1163			if err != nil {
1164				t.Fatalf("call %q: error %q", tc.expr, err.Error())
1165			}
1166
1167			retvalsVar := p.CurrentThread().Common().ReturnValues(pnormalLoadConfig)
1168			retvals := make([]*api.Variable, len(retvalsVar))
1169
1170			for i := range retvals {
1171				retvals[i] = api.ConvertVar(retvalsVar[i])
1172			}
1173
1174			for i := range retvals {
1175				t.Logf("\t%s = %s", retvals[i].Name, retvals[i].SinglelineString())
1176			}
1177
1178			if len(retvals) != len(tc.outs) {
1179				t.Fatalf("call %q: wrong number of return parameters", tc.expr)
1180			}
1181
1182			for i := range retvals {
1183				outfields := strings.SplitN(tc.outs[i], ":", 3)
1184				tgtName, tgtType, tgtValue := outfields[0], outfields[1], outfields[2]
1185
1186				if tgtName != "" && tgtName != retvals[i].Name {
1187					t.Fatalf("call %q output parameter %d: expected name %q, got %q", tc.expr, i, tgtName, retvals[i].Name)
1188				}
1189
1190				if retvals[i].Type != tgtType {
1191					t.Fatalf("call %q, output parameter %d: expected type %q, got %q", tc.expr, i, tgtType, retvals[i].Type)
1192				}
1193				if cvs := retvals[i].SinglelineString(); cvs != tgtValue {
1194					t.Fatalf("call %q, output parameter %d: expected value %q, got %q", tc.expr, i, tgtValue, cvs)
1195				}
1196			}
1197		}
1198	})
1199}
1200
Full Screen

rabin_karp.go

Source: rabin_karp.go Github

copy
1package rabinkarp
2
3import (
4	"math"
5)
6
7const defaultBase = 26
8
9// exponent get the value(base^exponent) and store the value in the result,
10// e.g., result[2]=base^2, result[1]=base^1, result[0]=base^0
11func exponent(base, exponent int) (result []int) {
12	result = make([]int, exponent+1)
13	for i := range result {
14		result[i] = int(math.Pow(float64(base), float64(i)))
15	}
16	return result
17}
18
19func rkSearch(main string, pattern string) bool {
20	lenMain := len(main)
21	lenPattern := len(pattern)
22
23	exponent := exponent(defaultBase, lenPattern)
24
25	// store the hash of main string
26	hashMain := make([]int, lenMain-lenPattern+1)
27	// store the hash of pattern
28	hashPattern := 0
29
30	// calculate the hash of pattern and hashMain[0]
31	for i := range pattern {
32		idx := lenPattern - 1 - i
33		hashPattern += exponent[idx] * int(pattern[i]-'a')
34		hashMain[0] += exponent[idx] * int(main[i]-'a')
35	}
36
37	// calculate the hash of hashMain[1:]
38	for i := 1; i < lenMain-lenPattern+1; i++ {
39		hashMain[i] = defaultBase*(hashMain[i-1]-exponent[lenPattern-1]*int(main[i-1]-'a')) + exponent[0]*int(main[i+lenPattern-1]-'a')
40	}
41
42	// compare the hash of main and pattern
43	for i := range hashMain {
44		if hashPattern == hashMain[i] {
45			return true
46		}
47	}
48	return false
49}
50
51// rkSearchMatrixString search pattern from matrix string,
52// h[0][0] represent the hash of s[0][0] -> s[1][2],
53// h[0][1] represent the hash of s[0][1] -> s[1][3],
54// h[1][0]	represent the hash of s[1][0] -> s[2][2],
55// r=lenPatternRow, c=lenPatternColumn,
56// e.g., if pattern=
57//	{"d", "a", "b"},
58//	{"e", "f", "a"},
59// r=2, c=3,
60// h[i][j]=10^(r-1)*(26^(c-1)*(s[i][j]-'a')+26^(c-2)*(s[i][j+1]-'a')+...+26^0*(s[i][j+c-1]-'a'))+
61//	10^(r-2)*(26^(c-1)*(s[i+1][j]-'a')+26^(c-2)*(s[i+1][j+1]-'a')+...+26^0*(s[i+1][j+c-1]-'a'))+...
62// 	10^0*(26^(c-1)*(s[i+r-1][j]-'a')+26^(c-2)*(s[i+r-1][j+1]-'a')+...+26^0*(s[i+r-1][j+c-1]-'a'))
63// h[i][j+1]=
64//	26*(h[i][j]-10^(r-1)*26^(c-1)*(s[i][j]-'a')-10^(r-2)*26^(c-1)*(s[i+1][j]-'a')-...-10^0*26^(c-1)*(s[i+r-1][j]-'a'))+
65//	10^(r-1)*26^0*(s[i][j+c]-'a')+10^(r-2)*26^0*(s[i+1][j+c]-'a')+...+10^0*26^0*(s[i+r-1][j+c]-'a')
66// h[i+1][j]=
67//	10*h[i][j]-10^(r)*(26^(c-1)*(s[i][j]-'a')+26^(c-2)*(s[i][j+1]-'a')+...+26^0*(s[i][j+c-1]-'a'))+
68//	10^0*(26^(c-1)*(s[i+r][j]-'a')+26^(c-2)*(s[i+r][j+1]-'a')+...+26^0*(s[i+r][j+c-1]-'a'))
69func rkSearchMatrixString(main, pattern [][]string) bool {
70	lenMainRow := len(main)
71	lenMainColumn := len(main[0])
72	lenPatternRow := len(pattern)
73	lenPatternColumn := len(pattern[0])
74
75	if 0 == lenMainRow || 0 == lenPatternRow {
76		return false
77	}
78
79	if lenMainRow < lenPatternRow || lenMainColumn < lenPatternColumn {
80		return false
81	}
82
83	exponent26 := exponent(defaultBase, lenPatternColumn)
84	exponent10 := exponent(10, lenPatternRow)
85
86	// store the hash of main string
87	hashMain := make([][]int, lenMainRow-lenPatternRow+1)
88	for i := range hashMain {
89		hashMain[i] = make([]int, lenMainColumn-lenPatternColumn+1)
90	}
91
92	// store the hash of pattern
93	hashPattern := 0
94
95	// calculate the hash of pattern and hashMain[0][0]
96	for i := range pattern {
97		tmpPattern := 0
98		tmpMain := 0
99		for j := range pattern[i] {
100			idxColumn := lenPatternColumn - 1 - j
101			tmpPattern += exponent26[idxColumn] * int([]byte(pattern[i][j])[0]-'a')
102			tmpMain += exponent26[idxColumn] * int([]byte(main[i][j])[0]-'a')
103		}
104		idxRow := lenPatternRow - 1 - i
105		hashPattern += exponent10[idxRow] * tmpPattern
106		hashMain[0][0] += exponent10[idxRow] * tmpMain
107	}
108
109	// calculate the hash of hashMain[1:][0]
110	for i := 1; i <= lenMainRow-lenPatternRow; i++ {
111		tmp := 0
112		idxColumn := lenPatternColumn - 1
113		for j := 0; j <= lenPatternColumn-1; j++ {
114			tmp += exponent26[idxColumn]*int([]byte(main[i-1+lenPatternRow][j])[0]-'a') -
115				exponent10[lenPatternRow]*(exponent26[idxColumn]*int([]byte(main[i-1][j])[0]-'a'))
116			idxColumn--
117		}
118
119		hashMain[i][0] = 10*hashMain[i-1][0] + tmp
120	}
121
122	// calculate the hash of hashMain[i][j]
123	for i := 0; i <= lenMainRow-lenPatternRow; i++ {
124		for j := 1; j <= lenMainColumn-lenPatternColumn; j++ {
125			tmp := 0
126			idxRow := lenPatternRow - 1
127			for k := i; k <= i+lenPatternRow-1; k++ {
128				tmp += exponent10[idxRow]*int([]byte(main[k][j+lenPatternColumn-1])[0]-'a') -
129					exponent26[lenPatternColumn]*exponent10[idxRow]*int([]byte(main[k][j-1])[0]-'a')
130				idxRow--
131			}
132
133			hashMain[i][j] = 26*hashMain[i][j-1] + tmp
134		}
135	}
136
137	for i := range hashMain {
138		for j := range hashMain[i] {
139			if hashPattern == hashMain[i][j] {
140				return true
141			}
142		}
143	}
144	return false
145}
146
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest