From 143cf6aebfc0a23a57fb61420e92bd2dfe46b9b1 Mon Sep 17 00:00:00 2001 From: chainhelen Date: Sat, 13 Oct 2018 01:00:13 +0800 Subject: [PATCH] pkg/proc: extend conversion about `string` for array/str Extend `string()` 1.convert `byte/rune array`(not only `slice`) to string. 2.convert string to string(itself), just like `string(str)` in go language. --- _fixtures/testvariables2.go | 5 ++++- pkg/proc/eval.go | 16 +++++++++++++--- service/test/variables_test.go | 3 +++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/_fixtures/testvariables2.go b/_fixtures/testvariables2.go index e144f4c8..6cb787b9 100644 --- a/_fixtures/testvariables2.go +++ b/_fixtures/testvariables2.go @@ -246,6 +246,9 @@ func main() { byteslice := []byte{116, 195, 168, 115, 116} runeslice := []rune{116, 232, 115, 116} + bytearray := [5]byte{116, 195, 168, 115, 116} + runearray := [4]rune{116, 232, 115, 116} + longstr := "very long string 0123456789a0123456789b0123456789c0123456789d0123456789e0123456789f0123456789g012345678h90123456789i0123456789j0123456789" var nilstruct *astruct = nil @@ -270,5 +273,5 @@ func main() { } runtime.Breakpoint() - fmt.Println(i1, i2, i3, p1, amb1, s1, s3, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, errtypednil, emptyslice, emptymap, byteslice, runeslice, longstr, nilstruct, as2, as2.NonPointerRecieverMethod, s4, iface2map) + fmt.Println(i1, i2, i3, p1, amb1, s1, s3, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, errtypednil, emptyslice, emptymap, byteslice, runeslice, bytearray, runearray, longstr, nilstruct, as2, as2.NonPointerRecieverMethod, s4, iface2map) } diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 8f7bfbaa..e731d65c 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -114,15 +114,25 @@ func (scope *EvalScope) evalToplevelTypeCast(t ast.Expr, cfg LoadConfig) (*Varia case "string": switch argv.Kind { + case reflect.String: + s := constant.StringVal(argv.Value) + v.Value = constant.MakeString(s) + v.Len = int64(len(s)) + return v, nil case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr: b, _ := constant.Int64Val(argv.Value) s := string(b) v.Value = constant.MakeString(s) v.Len = int64(len(s)) return v, nil - - case reflect.Slice: - switch elemType := argv.RealType.(*godwarf.SliceType).ElemType.(type) { + case reflect.Slice, reflect.Array: + var elem godwarf.Type + if argv.Kind == reflect.Slice { + elem = argv.RealType.(*godwarf.SliceType).ElemType + } else { + elem = argv.RealType.(*godwarf.ArrayType).Type + } + switch elemType := elem.(type) { case *godwarf.UintType: if elemType.Name != "uint8" && elemType.Name != "byte" { return nil, nil diff --git a/service/test/variables_test.go b/service/test/variables_test.go index d85f0da0..60461b86 100644 --- a/service/test/variables_test.go +++ b/service/test/variables_test.go @@ -784,6 +784,9 @@ func TestEvalExpression(t *testing.T) { {"string(runeslice)", false, `"tèst"`, `""`, "string", nil}, {"[]byte(string(runeslice))", false, `[]uint8 len: 5, cap: 5, [116,195,168,115,116]`, `[]uint8 len: 0, cap: 0, nil`, "[]uint8", nil}, {"*(*[5]byte)(uintptr(&byteslice[0]))", false, `[5]uint8 [116,195,168,115,116]`, `[5]uint8 [...]`, "[5]uint8", nil}, + {"string(bytearray)", false, `"tèst"`, `""`, "string", nil}, + {"string(runearray)", false, `"tèst"`, `""`, "string", nil}, + {"string(str1)", false, `"01234567890"`, `"01234567890"`, "string", nil}, // access to channel field members {"ch1.qcount", false, "4", "4", "uint", nil},