debug: Make the ogler demo check that the values it reads are correct.

Remove maps from the demo until they're fixed in the printer.

Change-Id: Ib5a4a24e3d3543569f44fbeca0848bf7a5b7665d
Reviewed-on: https://go-review.googlesource.com/2687
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/ogle/demo/ogler/main.go b/ogle/demo/ogler/main.go
index dc2355e..0edc578 100644
--- a/ogle/demo/ogler/main.go
+++ b/ogle/demo/ogler/main.go
@@ -14,6 +14,86 @@
 	"golang.org/x/debug/ogle/program/client"
 )
 
+var expected_vars = map[string]string{
+	`main.Z_array`:               `[5]int8{-121, 121, 3, 2, 1}`,
+	`main.Z_array_empty`:         `[0]int8{}`,
+	`main.Z_bool_false`:          `false`,
+	`main.Z_bool_true`:           `true`,
+	`main.Z_channel`:             `0xX`,
+	`main.Z_channel_buffered`:    `0xX`,
+	`main.Z_channel_nil`:         `0x0`,
+	`main.Z_array_of_empties`:    `[2]struct struct {}{struct struct {} {}, (struct struct {} 0xX)}`,
+	`main.Z_complex128`:          `(1.987654321-2.987654321i)`,
+	`main.Z_complex64`:           `(1.54321+2.54321i)`,
+	`main.Z_float32`:             `1.54321`,
+	`main.Z_float64`:             `1.987654321`,
+	`main.Z_func_int8_r_int8`:    `func(int8, *int8) void @0xX `,
+	`main.Z_func_int8_r_pint8`:   `func(int8, **int8) void @0xX `,
+	`main.Z_func_bar`:            `func(*main.FooStruct) void @0xX `,
+	`main.Z_int`:                 `-21`,
+	`main.Z_int16`:               `-32321`,
+	`main.Z_int32`:               `-1987654321`,
+	`main.Z_int64`:               `-9012345678987654321`,
+	`main.Z_int8`:                `-121`,
+	`main.Z_interface`:           `struct runtime.iface {0xX, 0xX}`,
+	`main.Z_interface_nil`:       `struct runtime.iface {0x0, 0x0}`,
+	`main.Z_interface_typed_nil`: `struct runtime.iface {0xX, 0x0}`,
+	`main.Z_pointer`:             `0xX`,
+	`main.Z_pointer_nil`:         `0x0`,
+	`main.Z_slice`:               `[]uint8{115, 108, 105, 99, 101}`,
+	`main.Z_slice_2`:             `[]int8{-121, 121}`,
+	`main.Z_slice_nil`:           `[]uint8{}`,
+	`main.Z_string`:              `"I'm a string"`,
+	`main.Z_struct`:              `struct main.FooStruct {21, "hi"}`,
+	`main.Z_uint`:                `21`,
+	`main.Z_uint16`:              `54321`,
+	`main.Z_uint32`:              `3217654321`,
+	`main.Z_uint64`:              `12345678900987654321`,
+	`main.Z_uint8`:               `231`,
+	`main.Z_uintptr`:             `21`,
+	`main.Z_unsafe_pointer`:      `0xX`,
+	`main.Z_unsafe_pointer_nil`:  `0x0`,
+}
+
+func isHex(r uint8) bool {
+	switch {
+	case '0' <= r && r <= '9':
+		return true
+	case 'a' <= r && r <= 'f':
+		return true
+	case 'A' <= r && r <= 'F':
+		return true
+	default:
+		return false
+	}
+}
+
+// Check s matches the pattern in p.
+// An 'X' in p greedily matches one or more hex characters in s.
+func matches(p, s string) bool {
+	j := 0
+	for i := 0; i < len(p); i++ {
+		if j == len(s) {
+			return false
+		}
+		c := p[i]
+		if c == 'X' {
+			if !isHex(s[j]) {
+				return false
+			}
+			for j < len(s) && isHex(s[j]) {
+				j++
+			}
+			continue
+		}
+		if c != s[j] {
+			return false
+		}
+		j++
+	}
+	return j == len(s)
+}
+
 func main() {
 	prog, err := client.Run("localhost", "bin/tracee")
 	if err != nil {
@@ -38,21 +118,44 @@
 
 	frames, err := prog.Frames(100)
 	if err != nil {
-		log.Printf("prog.Frames error: %v", err)
+		log.Fatalf("prog.Frames error: %v", err)
 	}
 	fmt.Printf("%#v\n", frames)
 
 	varnames, err := prog.Eval(`re:main\.Z_.*`)
 	if err != nil {
-		log.Printf("prog.Eval error: %v", err)
+		log.Fatalf("prog.Eval error: %v", err)
 	}
 
+	// Evaluate each of the variables found above, and check they match
+	// expected_vars.
+	seen := make(map[string]bool)
 	for _, v := range varnames {
 		val, err := prog.Eval("val:" + v)
 		if err != nil {
-			log.Printf("prog.Eval error for %s: %v", v, err)
+			log.Fatalf("prog.Eval error for %s: %v", v, err)
 		} else {
 			fmt.Printf("%s = %v\n", v, val)
+			if seen[v] {
+				log.Fatalf("Repeated variable %s\n", v)
+			}
+			seen[v] = true
+			if len(val) != 1 {
+				log.Fatalf("Should be one value for %s\n", v)
+			}
+			expected, ok := expected_vars[v]
+			if !ok {
+				log.Fatalf("Unexpected variable %s\n", v)
+			} else {
+				if !matches(expected, val[0]) {
+					log.Fatalf("Expected %s = %s\n", v, expected)
+				}
+			}
+		}
+	}
+	for v, e := range expected_vars {
+		if !seen[v] {
+			log.Fatalf("Didn't get %s = %s\n", v, e)
 		}
 	}
 }
diff --git a/ogle/demo/tracee/main.go b/ogle/demo/tracee/main.go
index 628593e..f1426d5 100644
--- a/ogle/demo/tracee/main.go
+++ b/ogle/demo/tracee/main.go
@@ -53,7 +53,6 @@
 	Z_interface           FooInterface = &Z_struct
 	Z_interface_typed_nil FooInterface = Z_pointer_nil
 	Z_interface_nil       FooInterface
-	Z_map_nil             map[int8]float32
 	Z_pointer             *FooStruct = &Z_struct
 	Z_pointer_nil         *FooStruct
 	Z_slice               []byte = []byte{'s', 'l', 'i', 'c', 'e'}
@@ -74,7 +73,6 @@
 	fmt.Println(Z_channel, Z_channel_buffered, Z_channel_nil)
 	fmt.Println(Z_func_bar, Z_func_int8_r_int8, Z_func_int8_r_pint8)
 	fmt.Println(Z_interface, Z_interface_nil, Z_interface_typed_nil)
-	fmt.Println(Z_map_nil)
 	fmt.Println(Z_pointer, Z_pointer_nil)
 	fmt.Println(Z_slice, Z_slice_2, Z_slice_nil)
 	fmt.Println(Z_string, Z_struct)