package cgo import ( "bytes" "go/format" "go/token" "strings" "testing" ) func TestParseConst(t *testing.T) { // Test converting a C constant to a Go constant. for _, tc := range []struct { C string Go string }{ {`5`, `5`}, {`(5)`, `(5)`}, {`(((5)))`, `(5)`}, {`)`, `error: 1:1: unexpected token )`}, {`5)`, `error: 1:2: unexpected token ), expected end of expression`}, {" \t)", `error: 1:4: unexpected token )`}, {`5.8f`, `5.8`}, {`foo`, `C.foo`}, {``, `error: 1:1: empty constant`}, // empty constants not allowed in Go {`"foo"`, `"foo"`}, {`"a\\n"`, `"a\\n"`}, {`"a\n"`, `"a\n"`}, {`"a\""`, `"a\""`}, {`'a'`, `'a'`}, {`0b10`, `0b10`}, {`0x1234_5678`, `0x1234_5678`}, {`5 5`, `error: 1:3: unexpected token INT, expected end of expression`}, // test for a bugfix // Binary operators. {`5+5`, `5 + 5`}, {`5-5`, `5 - 5`}, {`5*5`, `5 * 5`}, {`5/5`, `5 / 5`}, {`5%5`, `5 % 5`}, {`5&5`, `5 & 5`}, {`5|5`, `5 | 5`}, {`5^5`, `5 ^ 5`}, {`5<<5`, `5 << 5`}, {`5>>5`, `5 >> 5`}, {`5>>5 + 3`, `5 >> (5 + 3)`}, {`5>>5 ^ 3`, `5>>5 ^ 3`}, {`5||5`, `error: 1:2: unexpected token ||, expected end of expression`}, // logical binops aren't supported yet {`(5/5)`, `(5 / 5)`}, {`1 - 2`, `1 - 2`}, {`1 - 2 + 3`, `1 - 2 + 3`}, {`1 - 2 * 3`, `1 - 2*3`}, {`(1 - 2) * 3`, `(1 - 2) * 3`}, {`1 * 2 - 3`, `1*2 - 3`}, {`1 * (2 - 3)`, `1 * (2 - 3)`}, // Unary operators. {`-5`, `-5`}, {`-5-2`, `-5 - 2`}, {`5 - - 2`, `5 - -2`}, } { fset := token.NewFileSet() startPos := fset.AddFile("", -1, 1000).Pos(0) expr, err := parseConst(startPos, fset, tc.C) s := "" if err != nil { if !strings.HasPrefix(tc.Go, "error: ") { t.Errorf("expected value %#v for C constant %#v but got error %#v", tc.Go, tc.C, err.Error()) continue } s = "error: " + err.Error() } else if expr != nil { // Serialize the Go constant to a string, for more readable test // cases. buf := &bytes.Buffer{} err := format.Node(buf, fset, expr) if err != nil { t.Errorf("could not format expr from C constant %#v: %v", tc.C, err) continue } s = buf.String() } if s != tc.Go { t.Errorf("C constant %#v was parsed to %#v while expecting %#v", tc.C, s, tc.Go) } } }