mirror of https://github.com/golang/go.git
replay CL 19916 and CL 19913 now that the build can handle them
TBR=r OCL=19924 CL=19934
This commit is contained in:
parent
0a20746cac
commit
387df5e176
|
|
@ -3,8 +3,12 @@
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package bufio
|
package bufio
|
||||||
import "os"
|
|
||||||
import "io"
|
import (
|
||||||
|
"os";
|
||||||
|
"io";
|
||||||
|
"utf8";
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
@ -140,6 +144,30 @@ func (b *BufRead) UnreadByte() *os.Error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read a single Unicode character; returns the rune and its size.
|
||||||
|
func (b *BufRead) ReadRune() (rune int, size int, err *os.Error) {
|
||||||
|
for b.r + utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) {
|
||||||
|
n := b.w - b.r;
|
||||||
|
b.Fill();
|
||||||
|
if b.err != nil {
|
||||||
|
return 0, 0, b.err
|
||||||
|
}
|
||||||
|
if b.w - b.r == n {
|
||||||
|
// no bytes read
|
||||||
|
if b.r == b.w {
|
||||||
|
return 0, 0, EndOfFile
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rune, size = int(b.buf[b.r]), 1;
|
||||||
|
if rune >= 0x80 {
|
||||||
|
rune, size = utf8.DecodeRune(b.buf[b.r:b.w]);
|
||||||
|
}
|
||||||
|
b.r += size;
|
||||||
|
return rune, size, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function: look for byte c in array p,
|
// Helper function: look for byte c in array p,
|
||||||
// returning its index or -1.
|
// returning its index or -1.
|
||||||
func FindByte(p *[]byte, c byte) int {
|
func FindByte(p *[]byte, c byte) int {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package fmt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt";
|
||||||
|
"syscall";
|
||||||
|
"testing";
|
||||||
|
)
|
||||||
|
|
||||||
|
export func TestFmtInterface(t *testing.T) {
|
||||||
|
var i1 interface{};
|
||||||
|
i1 = "abc";
|
||||||
|
s := fmt.sprintf("%s", i1);
|
||||||
|
if s != "abc" {
|
||||||
|
t.Errorf(`fmt.sprintf("%%s", empty("abc")) = %q want %q`, s, "abc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FmtTest struct {
|
||||||
|
fmt string;
|
||||||
|
val interface { };
|
||||||
|
out string;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bytes(s string) *[]byte {
|
||||||
|
b := new([]byte, len(s)+1);
|
||||||
|
syscall.StringToBytes(b, s);
|
||||||
|
return b[0:len(s)];
|
||||||
|
}
|
||||||
|
|
||||||
|
const B32 uint32 = 1<<32 - 1
|
||||||
|
const B64 uint64 = 1<<64 - 1
|
||||||
|
|
||||||
|
var fmttests = []FmtTest{
|
||||||
|
// basic string
|
||||||
|
FmtTest{ "%s", "abc", "abc" },
|
||||||
|
FmtTest{ "%x", "abc", "616263" },
|
||||||
|
FmtTest{ "%x", "xyz", "78797a" },
|
||||||
|
FmtTest{ "%X", "xyz", "78797A" },
|
||||||
|
FmtTest{ "%q", "abc", `"abc"` },
|
||||||
|
|
||||||
|
// basic bytes
|
||||||
|
FmtTest{ "%s", Bytes("abc"), "abc" },
|
||||||
|
FmtTest{ "%x", Bytes("abc"), "616263" },
|
||||||
|
FmtTest{ "%x", Bytes("xyz"), "78797a" },
|
||||||
|
FmtTest{ "%X", Bytes("xyz"), "78797A" },
|
||||||
|
FmtTest{ "%q", Bytes("abc"), `"abc"` },
|
||||||
|
|
||||||
|
// escaped strings
|
||||||
|
FmtTest{ "%#q", `abc`, "`abc`" },
|
||||||
|
FmtTest{ "%#q", `"`, "`\"`" },
|
||||||
|
FmtTest{ "1 %#q", `\n`, "1 `\\n`" },
|
||||||
|
FmtTest{ "2 %#q", "\n", `2 "\n"` },
|
||||||
|
FmtTest{ "%q", `"`, `"\""` },
|
||||||
|
FmtTest{ "%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"` },
|
||||||
|
FmtTest{ "%q", "abc\xffdef", `"abc\xffdef"` },
|
||||||
|
FmtTest{ "%q", "\u263a", `"\u263a"` },
|
||||||
|
FmtTest{ "%q", "\U0010ffff", `"\U0010ffff"` },
|
||||||
|
|
||||||
|
// width
|
||||||
|
FmtTest{ "%5s", "abc", " abc" },
|
||||||
|
FmtTest{ "%-5s", "abc", "abc " },
|
||||||
|
FmtTest{ "%05s", "abc", "00abc" },
|
||||||
|
|
||||||
|
// integers
|
||||||
|
FmtTest{ "%d", 12345, "12345" },
|
||||||
|
FmtTest{ "%d", -12345, "-12345" },
|
||||||
|
FmtTest{ "%10d", 12345, " 12345" },
|
||||||
|
FmtTest{ "%10d", -12345, " -12345" },
|
||||||
|
FmtTest{ "%+10d", 12345, " +12345" },
|
||||||
|
FmtTest{ "%010d", 12345, "0000012345" },
|
||||||
|
FmtTest{ "%010d", -12345, "-000012345" },
|
||||||
|
FmtTest{ "%-10d", 12345, "12345 " },
|
||||||
|
FmtTest{ "%010.3d", 1, " 001" },
|
||||||
|
FmtTest{ "%010.3d", -1, " -001" },
|
||||||
|
FmtTest{ "%+d", 12345, "+12345" },
|
||||||
|
FmtTest{ "%+d", -12345, "-12345" },
|
||||||
|
FmtTest{ "% d", 12345, " 12345" },
|
||||||
|
FmtTest{ "% d", -12345, "-12345" },
|
||||||
|
|
||||||
|
// old test/fmt_test.go
|
||||||
|
FmtTest{ "%d", 1234, "1234" },
|
||||||
|
FmtTest{ "%d", -1234, "-1234" },
|
||||||
|
FmtTest{ "%d", uint(1234), "1234" },
|
||||||
|
FmtTest{ "%d", uint32(B32), "4294967295" },
|
||||||
|
FmtTest{ "%d", uint64(B64), "18446744073709551615" },
|
||||||
|
FmtTest{ "%o", 01234, "1234" },
|
||||||
|
FmtTest{ "%o", uint32(B32), "37777777777" },
|
||||||
|
FmtTest{ "%o", uint64(B64), "1777777777777777777777" },
|
||||||
|
FmtTest{ "%x", 0x1234abcd, "1234abcd" },
|
||||||
|
FmtTest{ "%x", B32-0x1234567, "fedcba98" },
|
||||||
|
FmtTest{ "%X", 0x1234abcd, "1234ABCD" },
|
||||||
|
FmtTest{ "%X", B32-0x1234567, "FEDCBA98" },
|
||||||
|
FmtTest{ "%x", B64, "ffffffffffffffff" },
|
||||||
|
FmtTest{ "%b", 7, "111" },
|
||||||
|
FmtTest{ "%b", B64, "1111111111111111111111111111111111111111111111111111111111111111" },
|
||||||
|
FmtTest{ "%e", float64(1), "1.000000e+00" },
|
||||||
|
FmtTest{ "%e", float64(1234.5678e3), "1.234568e+06" },
|
||||||
|
FmtTest{ "%e", float64(1234.5678e-8), "1.234568e-05" },
|
||||||
|
FmtTest{ "%e", float64(-7), "-7.000000e+00" },
|
||||||
|
FmtTest{ "%e", float64(-1e-9), "-1.000000e-09" },
|
||||||
|
FmtTest{ "%f", float64(1234.5678e3), "1234567.800000" },
|
||||||
|
FmtTest{ "%f", float64(1234.5678e-8), "0.000012" },
|
||||||
|
FmtTest{ "%f", float64(-7), "-7.000000" },
|
||||||
|
FmtTest{ "%f", float64(-1e-9), "-0.000000" },
|
||||||
|
FmtTest{ "%g", float64(1234.5678e3), "1.2345678e+06" },
|
||||||
|
FmtTest{ "%g", float32(1234.5678e3), "1.2345678e+06" },
|
||||||
|
FmtTest{ "%g", float64(1234.5678e-8), "1.2345678e-05" },
|
||||||
|
FmtTest{ "%g", float64(-7), "-7" },
|
||||||
|
FmtTest{ "%g", float64(-1e-9), "-1e-09", },
|
||||||
|
FmtTest{ "%g", float32(-1e-9), "-1e-09" },
|
||||||
|
FmtTest{ "%c", 'x', "x" },
|
||||||
|
FmtTest{ "%c", 0xe4, "ä" },
|
||||||
|
FmtTest{ "%c", 0x672c, "本" },
|
||||||
|
FmtTest{ "%c", '日', "日" },
|
||||||
|
FmtTest{ "%20.8d", 1234, " 00001234" },
|
||||||
|
FmtTest{ "%20.8d", -1234, " -00001234" },
|
||||||
|
FmtTest{ "%20d", 1234, " 1234" },
|
||||||
|
FmtTest{ "%-20.8d", 1234, "00001234 " },
|
||||||
|
FmtTest{ "%-20.8d", -1234, "-00001234 " },
|
||||||
|
FmtTest{ "%.20b", 7, "00000000000000000111" },
|
||||||
|
FmtTest{ "%20.5s", "qwertyuiop", " qwert" },
|
||||||
|
FmtTest{ "%.5s", "qwertyuiop", "qwert" },
|
||||||
|
FmtTest{ "%-20.5s", "qwertyuiop", "qwert " },
|
||||||
|
FmtTest{ "%20c", 'x', " x" },
|
||||||
|
FmtTest{ "%-20c", 'x', "x " },
|
||||||
|
FmtTest{ "%20.6e", 1.2345e3, " 1.234500e+03" },
|
||||||
|
FmtTest{ "%20.6e", 1.2345e-3, " 1.234500e-03" },
|
||||||
|
FmtTest{ "%20e", 1.2345e3, " 1.234500e+03" },
|
||||||
|
FmtTest{ "%20e", 1.2345e-3, " 1.234500e-03" },
|
||||||
|
FmtTest{ "%20.8e", 1.2345e3, " 1.23450000e+03" },
|
||||||
|
FmtTest{ "%20f", float64(1.23456789e3), " 1234.567890" },
|
||||||
|
FmtTest{ "%20f", float64(1.23456789e-3), " 0.001235" },
|
||||||
|
FmtTest{ "%20f", float64(12345678901.23456789), " 12345678901.234568" },
|
||||||
|
FmtTest{ "%-20f", float64(1.23456789e3), "1234.567890 " },
|
||||||
|
FmtTest{ "%20.8f", float64(1.23456789e3), " 1234.56789000" },
|
||||||
|
FmtTest{ "%20.8f", float64(1.23456789e-3), " 0.00123457" },
|
||||||
|
FmtTest{ "%g", float64(1.23456789e3), "1234.56789" },
|
||||||
|
FmtTest{ "%g", float64(1.23456789e-3), "0.00123456789" },
|
||||||
|
FmtTest{ "%g", float64(1.23456789e20), "1.23456789e+20" },
|
||||||
|
FmtTest{ "%20e", sys.Inf(1), " +Inf" },
|
||||||
|
FmtTest{ "%-20f", sys.Inf(-1), "-Inf " },
|
||||||
|
FmtTest{ "%20g", sys.NaN(), " NaN" },
|
||||||
|
}
|
||||||
|
|
||||||
|
export func TestSprintf(t *testing.T) {
|
||||||
|
for i := 0; i < len(fmttests); i++ {
|
||||||
|
tt := fmttests[i];
|
||||||
|
s := fmt.sprintf(tt.fmt, tt.val);
|
||||||
|
if s != tt.out {
|
||||||
|
if ss, ok := tt.val.(string); ok {
|
||||||
|
// Don't requote the already-quoted strings.
|
||||||
|
// It's too confusing to read the errors.
|
||||||
|
t.Errorf("fmt.sprintf(%q, %q) = %s want %s", tt.fmt, tt.val, s, tt.out);
|
||||||
|
} else {
|
||||||
|
t.Errorf("fmt.sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
package fmt
|
package fmt
|
||||||
|
|
||||||
import "strconv"
|
import (
|
||||||
|
"strconv";
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Raw formatter. See print.go for a more palatable interface.
|
Raw formatter. See print.go for a more palatable interface.
|
||||||
|
|
@ -39,11 +41,22 @@ export type Fmt struct {
|
||||||
wid_present bool;
|
wid_present bool;
|
||||||
prec int;
|
prec int;
|
||||||
prec_present bool;
|
prec_present bool;
|
||||||
|
// flags
|
||||||
|
minus bool;
|
||||||
|
plus bool;
|
||||||
|
sharp bool;
|
||||||
|
space bool;
|
||||||
|
zero bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fmt) clearflags() {
|
func (f *Fmt) clearflags() {
|
||||||
f.wid_present = false;
|
f.wid_present = false;
|
||||||
f.prec_present = false;
|
f.prec_present = false;
|
||||||
|
f.minus = false;
|
||||||
|
f.plus = false;
|
||||||
|
f.sharp = false;
|
||||||
|
f.space = false;
|
||||||
|
f.zero = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fmt) clearbuf() {
|
func (f *Fmt) clearbuf() {
|
||||||
|
|
@ -101,24 +114,28 @@ func (f *Fmt) w(x int) *Fmt {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// append s to buf, padded on left (w > 0) or right (w < 0)
|
// append s to buf, padded on left (w > 0) or right (w < 0 or f.minus)
|
||||||
// padding is in bytes, not characters (agrees with ANSIC C, not Plan 9 C)
|
// padding is in bytes, not characters (agrees with ANSIC C, not Plan 9 C)
|
||||||
func (f *Fmt) pad(s string) {
|
func (f *Fmt) pad(s string) {
|
||||||
if f.wid_present && f.wid != 0 {
|
if f.wid_present && f.wid != 0 {
|
||||||
left := true;
|
left := !f.minus;
|
||||||
w := f.wid;
|
w := f.wid;
|
||||||
if w < 0 {
|
if w < 0 {
|
||||||
left = false;
|
left = false;
|
||||||
w = -w;
|
w = -w;
|
||||||
}
|
}
|
||||||
w -= len(s);
|
w -= len(s);
|
||||||
|
padchar := byte(' ');
|
||||||
|
if left && f.zero {
|
||||||
|
padchar = '0';
|
||||||
|
}
|
||||||
if w > 0 {
|
if w > 0 {
|
||||||
if w > NByte {
|
if w > NByte {
|
||||||
w = NByte;
|
w = NByte;
|
||||||
}
|
}
|
||||||
buf := new([]byte, w);
|
buf := new([]byte, w);
|
||||||
for i := 0; i < w; i++ {
|
for i := 0; i < w; i++ {
|
||||||
buf[i] = ' ';
|
buf[i] = padchar;
|
||||||
}
|
}
|
||||||
if left {
|
if left {
|
||||||
s = string(buf) + s;
|
s = string(buf) + s;
|
||||||
|
|
@ -163,16 +180,35 @@ func (f *Fmt) integer(a int64, base uint, is_signed bool, digits *string) string
|
||||||
if negative {
|
if negative {
|
||||||
a = -a;
|
a = -a;
|
||||||
}
|
}
|
||||||
i := putint(&buf, NByte-1, uint64(base), uint64(a), digits);
|
|
||||||
|
// two ways to ask for extra leading zero digits: %.3d or %03d.
|
||||||
|
// apparently the first cancels the second.
|
||||||
|
prec := 0;
|
||||||
if f.prec_present {
|
if f.prec_present {
|
||||||
for i > 0 && f.prec > (NByte-1-i) {
|
prec = f.prec;
|
||||||
|
f.zero = false;
|
||||||
|
} else if f.zero && f.wid_present && !f.minus && f.wid > 0{
|
||||||
|
prec = f.wid;
|
||||||
|
if negative || f.plus || f.space {
|
||||||
|
prec--; // leave room for sign
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i := putint(&buf, NByte-1, uint64(base), uint64(a), digits);
|
||||||
|
for i > 0 && prec > (NByte-1-i) {
|
||||||
buf[i] = '0';
|
buf[i] = '0';
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if negative {
|
if negative {
|
||||||
buf[i] = '-';
|
buf[i] = '-';
|
||||||
i--;
|
i--;
|
||||||
|
} else if f.plus {
|
||||||
|
buf[i] = '+';
|
||||||
|
i--;
|
||||||
|
} else if f.space {
|
||||||
|
buf[i] = ' ';
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
return string(buf)[i+1:NByte];
|
return string(buf)[i+1:NByte];
|
||||||
}
|
}
|
||||||
|
|
@ -334,6 +370,44 @@ func (f *Fmt) s(s string) *Fmt {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hexadecimal string
|
||||||
|
func (f *Fmt) sx(s string) *Fmt {
|
||||||
|
t := "";
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
v := s[i];
|
||||||
|
t += string(ldigits[v>>4]);
|
||||||
|
t += string(ldigits[v&0xF]);
|
||||||
|
}
|
||||||
|
f.pad(t);
|
||||||
|
f.clearflags();
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Fmt) sX(s string) *Fmt {
|
||||||
|
t := "";
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
v := s[i];
|
||||||
|
t += string(udigits[v>>4]);
|
||||||
|
t += string(udigits[v&0xF]);
|
||||||
|
}
|
||||||
|
f.pad(t);
|
||||||
|
f.clearflags();
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// quoted string
|
||||||
|
func (f *Fmt) q(s string) *Fmt {
|
||||||
|
var quoted string;
|
||||||
|
if f.sharp && strconv.CanBackquote(s) {
|
||||||
|
quoted = "`"+s+"`";
|
||||||
|
} else {
|
||||||
|
quoted = strconv.Quote(s);
|
||||||
|
}
|
||||||
|
f.pad(quoted);
|
||||||
|
f.clearflags();
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
// floating-point
|
// floating-point
|
||||||
|
|
||||||
func Prec(f *Fmt, def int) int {
|
func Prec(f *Fmt, def int) int {
|
||||||
|
|
@ -370,7 +444,7 @@ func (f *Fmt) fb64(a float64) *Fmt {
|
||||||
// cannot defer to float64 versions
|
// cannot defer to float64 versions
|
||||||
// because it will get rounding wrong in corner cases.
|
// because it will get rounding wrong in corner cases.
|
||||||
func (f *Fmt) e32(a float32) *Fmt {
|
func (f *Fmt) e32(a float32) *Fmt {
|
||||||
return FmtString(f, strconv.ftoa32(a, 'e', Prec(f, -1)));
|
return FmtString(f, strconv.ftoa32(a, 'e', Prec(f, 6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fmt) f32(a float32) *Fmt {
|
func (f *Fmt) f32(a float32) *Fmt {
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,19 @@ export func sprintln(a ...) string {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get the i'th arg of the struct value.
|
||||||
|
// If the arg itself is an interface, return a value for
|
||||||
|
// the thing inside the interface, not the interface itself.
|
||||||
|
func getField(v reflect.StructValue, i int) reflect.Value {
|
||||||
|
val := v.Field(i);
|
||||||
|
if val.Kind() == reflect.InterfaceKind {
|
||||||
|
inter := val.(reflect.InterfaceValue).Get();
|
||||||
|
return reflect.NewValue(inter);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
// Getters for the fields of the argument structure.
|
// Getters for the fields of the argument structure.
|
||||||
|
|
||||||
func getBool(v reflect.Value) (val bool, ok bool) {
|
func getBool(v reflect.Value) (val bool, ok bool) {
|
||||||
|
|
@ -227,6 +240,9 @@ func getString(v reflect.Value) (val string, ok bool) {
|
||||||
case reflect.StringKind:
|
case reflect.StringKind:
|
||||||
return v.(reflect.StringValue).Get(), true;
|
return v.(reflect.StringValue).Get(), true;
|
||||||
}
|
}
|
||||||
|
if valb, okb := v.Interface().(*[]byte); okb {
|
||||||
|
return string(valb), true;
|
||||||
|
}
|
||||||
return "", false;
|
return "", false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,12 +296,6 @@ func parsenum(s string, start, end int) (n int, got bool, newi int) {
|
||||||
if start >= end {
|
if start >= end {
|
||||||
return 0, false, end
|
return 0, false, end
|
||||||
}
|
}
|
||||||
if s[start] == '-' {
|
|
||||||
a, b, c := parsenum(s, start+1, end);
|
|
||||||
if b {
|
|
||||||
return -a, b, c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isnum := false;
|
isnum := false;
|
||||||
num := 0;
|
num := 0;
|
||||||
for '0' <= s[start] && s[start] <= '9' {
|
for '0' <= s[start] && s[start] <= '9' {
|
||||||
|
|
@ -371,10 +381,28 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
||||||
i += w;
|
i += w;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// saw % - do we have %20 (width)?
|
i++;
|
||||||
p.wid, p.wid_ok, i = parsenum(format, i+1, end);
|
// flags
|
||||||
|
F: for ; i < end; i++ {
|
||||||
|
switch format[i] {
|
||||||
|
case '#':
|
||||||
|
p.fmt.sharp = true;
|
||||||
|
case '0':
|
||||||
|
p.fmt.zero = true;
|
||||||
|
case '+':
|
||||||
|
p.fmt.plus = true;
|
||||||
|
case '-':
|
||||||
|
p.fmt.minus = true;
|
||||||
|
case ' ':
|
||||||
|
p.fmt.space = true;
|
||||||
|
default:
|
||||||
|
break F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// do we have 20 (width)?
|
||||||
|
p.wid, p.wid_ok, i = parsenum(format, i, end);
|
||||||
p.prec_ok = false;
|
p.prec_ok = false;
|
||||||
// do we have %.20 (precision)?
|
// do we have .20 (precision)?
|
||||||
if i < end && format[i] == '.' {
|
if i < end && format[i] == '.' {
|
||||||
p.prec, p.prec_ok, i = parsenum(format, i+1, end);
|
p.prec, p.prec_ok, i = parsenum(format, i+1, end);
|
||||||
}
|
}
|
||||||
|
|
@ -391,7 +419,7 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
||||||
p.addstr("(missing)");
|
p.addstr("(missing)");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
field := v.Field(fieldnum);
|
field := getField(v, fieldnum);
|
||||||
fieldnum++;
|
fieldnum++;
|
||||||
if c != 'T' { // don't want thing to describe itself if we're asking for its type
|
if c != 'T' { // don't want thing to describe itself if we're asking for its type
|
||||||
if formatter, ok := field.Interface().(Format); ok {
|
if formatter, ok := field.Interface().(Format); ok {
|
||||||
|
|
@ -463,6 +491,20 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
||||||
} else {
|
} else {
|
||||||
s = p.fmt.ux64(uint64(v)).str()
|
s = p.fmt.ux64(uint64(v)).str()
|
||||||
}
|
}
|
||||||
|
} else if v, ok := getString(field); ok {
|
||||||
|
s = p.fmt.sx(v).str();
|
||||||
|
} else {
|
||||||
|
goto badtype
|
||||||
|
}
|
||||||
|
case 'X':
|
||||||
|
if v, signed, ok := getInt(field); ok {
|
||||||
|
if signed {
|
||||||
|
s = p.fmt.X64(v).str()
|
||||||
|
} else {
|
||||||
|
s = p.fmt.uX64(uint64(v)).str()
|
||||||
|
}
|
||||||
|
} else if v, ok := getString(field); ok {
|
||||||
|
s = p.fmt.sX(v).str();
|
||||||
} else {
|
} else {
|
||||||
goto badtype
|
goto badtype
|
||||||
}
|
}
|
||||||
|
|
@ -500,6 +542,12 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
||||||
} else {
|
} else {
|
||||||
goto badtype
|
goto badtype
|
||||||
}
|
}
|
||||||
|
case 'q':
|
||||||
|
if v, ok := getString(field); ok {
|
||||||
|
s = p.fmt.q(v).str()
|
||||||
|
} else {
|
||||||
|
goto badtype
|
||||||
|
}
|
||||||
|
|
||||||
// pointer
|
// pointer
|
||||||
case 'p':
|
case 'p':
|
||||||
|
|
@ -530,7 +578,7 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
||||||
if fieldnum < v.Len() {
|
if fieldnum < v.Len() {
|
||||||
p.addstr("?(extra ");
|
p.addstr("?(extra ");
|
||||||
for ; fieldnum < v.Len(); fieldnum++ {
|
for ; fieldnum < v.Len(); fieldnum++ {
|
||||||
p.addstr(v.Field(fieldnum).Type().String());
|
p.addstr(getField(v, fieldnum).Type().String());
|
||||||
if fieldnum + 1 < v.Len() {
|
if fieldnum + 1 < v.Len() {
|
||||||
p.addstr(", ");
|
p.addstr(", ");
|
||||||
}
|
}
|
||||||
|
|
@ -543,7 +591,7 @@ func (p *P) doprint(v reflect.StructValue, addspace, addnewline bool) {
|
||||||
prev_string := false;
|
prev_string := false;
|
||||||
for fieldnum := 0; fieldnum < v.Len(); fieldnum++ {
|
for fieldnum := 0; fieldnum < v.Len(); fieldnum++ {
|
||||||
// always add spaces if we're doing println
|
// always add spaces if we're doing println
|
||||||
field := v.Field(fieldnum);
|
field := getField(v, fieldnum);
|
||||||
if fieldnum > 0 {
|
if fieldnum > 0 {
|
||||||
if addspace {
|
if addspace {
|
||||||
p.add(' ')
|
p.add(' ')
|
||||||
|
|
|
||||||
|
|
@ -283,3 +283,14 @@ export func TestAll(tt *testing.T) { // TODO(r): wrap up better
|
||||||
println(a[i]);
|
println(a[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export func TestInterfaceGet(t *testing.T) {
|
||||||
|
var inter struct { e interface{ } };
|
||||||
|
inter.e = 123.456;
|
||||||
|
v1 := reflect.NewValue(&inter);
|
||||||
|
v2 := v1.(reflect.PtrValue).Sub().(reflect.StructValue).Field(0);
|
||||||
|
assert(v2.Type().String(), "interface { }");
|
||||||
|
i2 := v2.(reflect.InterfaceValue).Get();
|
||||||
|
v3 := reflect.NewValue(i2);
|
||||||
|
assert(v3.Type().String(), "float");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -181,3 +181,13 @@ TEXT reflect·PtrRuntimeArrayToAddr(SB),7,$-8
|
||||||
MOVQ AX, 16(SP)
|
MOVQ AX, 16(SP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
TEXT reflect·AddrToPtrInterface(SB),7,$-8
|
||||||
|
MOVQ 8(SP), AX
|
||||||
|
MOVQ AX, 16(SP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT reflect·PtrInterfaceToAddr(SB),7,$-8
|
||||||
|
MOVQ 8(SP), AX
|
||||||
|
MOVQ AX, 16(SP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,4 +38,5 @@ Float80
|
||||||
String
|
String
|
||||||
Bool
|
Bool
|
||||||
RuntimeArray
|
RuntimeArray
|
||||||
|
Interface
|
||||||
!
|
!
|
||||||
|
|
|
||||||
|
|
@ -36,14 +36,13 @@ func AddrToPtrString(Addr) *string
|
||||||
func AddrToPtrBool(Addr) *bool
|
func AddrToPtrBool(Addr) *bool
|
||||||
func AddrToPtrRuntimeArray(Addr) *RuntimeArray
|
func AddrToPtrRuntimeArray(Addr) *RuntimeArray
|
||||||
func PtrRuntimeArrayToAddr(*RuntimeArray) Addr
|
func PtrRuntimeArrayToAddr(*RuntimeArray) Addr
|
||||||
|
func AddrToPtrInterface(Addr) *interface{}
|
||||||
export type Empty interface {} // TODO(r): Delete when no longer needed?
|
|
||||||
|
|
||||||
export type Value interface {
|
export type Value interface {
|
||||||
Kind() int;
|
Kind() int;
|
||||||
Type() Type;
|
Type() Type;
|
||||||
Addr() Addr;
|
Addr() Addr;
|
||||||
Interface() Empty;
|
Interface() interface {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common fields and functionality for all values
|
// Common fields and functionality for all values
|
||||||
|
|
@ -66,7 +65,7 @@ func (c *Common) Addr() Addr {
|
||||||
return c.addr
|
return c.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Common) Interface() Empty {
|
func (c *Common) Interface() interface {} {
|
||||||
return sys.unreflect(*AddrToPtrAddr(c.addr), c.typ.String());
|
return sys.unreflect(*AddrToPtrAddr(c.addr), c.typ.String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -714,12 +713,17 @@ func StructCreator(typ Type, addr Addr) Value {
|
||||||
export type InterfaceValue interface {
|
export type InterfaceValue interface {
|
||||||
Kind() int;
|
Kind() int;
|
||||||
Type() Type;
|
Type() Type;
|
||||||
|
Get() interface {};
|
||||||
}
|
}
|
||||||
|
|
||||||
type InterfaceValueStruct struct {
|
type InterfaceValueStruct struct {
|
||||||
Common
|
Common
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *InterfaceValueStruct) Get() interface{} {
|
||||||
|
return *AddrToPtrInterface(v.addr);
|
||||||
|
}
|
||||||
|
|
||||||
func InterfaceCreator(typ Type, addr Addr) Value {
|
func InterfaceCreator(typ Type, addr Addr) Value {
|
||||||
return &InterfaceValueStruct{ Common{InterfaceKind, typ, addr} }
|
return &InterfaceValueStruct{ Common{InterfaceKind, typ, addr} }
|
||||||
}
|
}
|
||||||
|
|
@ -824,7 +828,7 @@ export func NewOpenArrayValue(typ ArrayType, len, cap int) ArrayValue {
|
||||||
return NewValueAddr(typ, PtrRuntimeArrayToAddr(array));
|
return NewValueAddr(typ, PtrRuntimeArrayToAddr(array));
|
||||||
}
|
}
|
||||||
|
|
||||||
export func NewValue(e Empty) Value {
|
export func NewValue(e interface {}) Value {
|
||||||
value, typestring := sys.reflect(e);
|
value, typestring := sys.reflect(e);
|
||||||
p, ok := typecache[typestring];
|
p, ok := typecache[typestring];
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,9 @@ coverage: packages
|
||||||
|
|
||||||
O1=\
|
O1=\
|
||||||
atoi.$O\
|
atoi.$O\
|
||||||
decimal.$O\
|
|
||||||
itoa.$O\
|
itoa.$O\
|
||||||
|
decimal.$O\
|
||||||
|
quote.$O\
|
||||||
|
|
||||||
O2=\
|
O2=\
|
||||||
ftoa.$O\
|
ftoa.$O\
|
||||||
|
|
@ -45,7 +46,7 @@ O3=\
|
||||||
strconv.a: a1 a2 a3
|
strconv.a: a1 a2 a3
|
||||||
|
|
||||||
a1: $(O1)
|
a1: $(O1)
|
||||||
$(AR) grc strconv.a atoi.$O decimal.$O itoa.$O
|
$(AR) grc strconv.a atoi.$O itoa.$O decimal.$O quote.$O
|
||||||
rm -f $(O1)
|
rm -f $(O1)
|
||||||
|
|
||||||
a2: $(O2)
|
a2: $(O2)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ var ftests = []Test {
|
||||||
Test{ 1, 'g', 5, "1" },
|
Test{ 1, 'g', 5, "1" },
|
||||||
Test{ 1, 'g', -1, "1" },
|
Test{ 1, 'g', -1, "1" },
|
||||||
Test{ 20, 'g', -1, "20" },
|
Test{ 20, 'g', -1, "20" },
|
||||||
|
Test{ 1234567.8, 'g', -1, "1.2345678e+06" },
|
||||||
Test{ 200000, 'g', -1, "200000" },
|
Test{ 200000, 'g', -1, "200000" },
|
||||||
Test{ 2000000, 'g', -1, "2e+06" },
|
Test{ 2000000, 'g', -1, "2e+06" },
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package strconv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"utf8";
|
||||||
|
)
|
||||||
|
|
||||||
|
const ldigits = "0123456789abcdef"
|
||||||
|
const udigits = "0123456789ABCDEF"
|
||||||
|
|
||||||
|
export func Quote(s string) string {
|
||||||
|
t := `"`;
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
switch {
|
||||||
|
case s[i] == '"':
|
||||||
|
t += `\"`;
|
||||||
|
case s[i] == '\\':
|
||||||
|
t += `\\`;
|
||||||
|
case ' ' <= s[i] && s[i] <= '~':
|
||||||
|
t += string(s[i]);
|
||||||
|
case s[i] == '\a':
|
||||||
|
t += `\a`;
|
||||||
|
case s[i] == '\b':
|
||||||
|
t += `\b`;
|
||||||
|
case s[i] == '\f':
|
||||||
|
t += `\f`;
|
||||||
|
case s[i] == '\n':
|
||||||
|
t += `\n`;
|
||||||
|
case s[i] == '\r':
|
||||||
|
t += `\r`;
|
||||||
|
case s[i] == '\t':
|
||||||
|
t += `\t`;
|
||||||
|
case s[i] == '\v':
|
||||||
|
t += `\v`;
|
||||||
|
|
||||||
|
case utf8.FullRuneInString(s, i):
|
||||||
|
r, size := utf8.DecodeRuneInString(s, i);
|
||||||
|
if r == utf8.RuneError && size == 1 {
|
||||||
|
goto EscX;
|
||||||
|
}
|
||||||
|
i += size-1; // i++ on next iteration
|
||||||
|
if r < 0x10000 {
|
||||||
|
t += `\u`;
|
||||||
|
for j:=uint(0); j<4; j++ {
|
||||||
|
t += string(ldigits[(r>>(12-4*j))&0xF]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t += `\U`;
|
||||||
|
for j:=uint(0); j<8; j++ {
|
||||||
|
t += string(ldigits[(r>>(28-4*j))&0xF]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
EscX:
|
||||||
|
t += `\x`;
|
||||||
|
t += string(ldigits[s[i]>>4]);
|
||||||
|
t += string(ldigits[s[i]&0xF]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t += `"`;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
export func CanBackquote(s string) bool {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] < ' ' || s[i] == '`' {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package strconv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv";
|
||||||
|
"testing";
|
||||||
|
)
|
||||||
|
|
||||||
|
type QuoteTest struct {
|
||||||
|
in string;
|
||||||
|
out string;
|
||||||
|
}
|
||||||
|
|
||||||
|
var quotetests = []QuoteTest {
|
||||||
|
QuoteTest{ "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"` },
|
||||||
|
QuoteTest{ "\\", `"\\"` },
|
||||||
|
QuoteTest{ "abc\xffdef", `"abc\xffdef"` },
|
||||||
|
QuoteTest{ "\u263a", `"\u263a"` },
|
||||||
|
QuoteTest{ "\U0010ffff", `"\U0010ffff"` },
|
||||||
|
}
|
||||||
|
|
||||||
|
export func TestQuote(t *testing.T) {
|
||||||
|
for i := 0; i < len(quotetests); i++ {
|
||||||
|
tt := quotetests[i];
|
||||||
|
if out := Quote(tt.in); out != tt.out {
|
||||||
|
t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CanBackquoteTest struct {
|
||||||
|
in string;
|
||||||
|
out bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
var canbackquotetests = []CanBackquoteTest {
|
||||||
|
CanBackquoteTest{ "`", false },
|
||||||
|
CanBackquoteTest{ string(0), false },
|
||||||
|
CanBackquoteTest{ string(1), false },
|
||||||
|
CanBackquoteTest{ string(2), false },
|
||||||
|
CanBackquoteTest{ string(3), false },
|
||||||
|
CanBackquoteTest{ string(4), false },
|
||||||
|
CanBackquoteTest{ string(5), false },
|
||||||
|
CanBackquoteTest{ string(6), false },
|
||||||
|
CanBackquoteTest{ string(7), false },
|
||||||
|
CanBackquoteTest{ string(8), false },
|
||||||
|
CanBackquoteTest{ string(9), false },
|
||||||
|
CanBackquoteTest{ string(10), false },
|
||||||
|
CanBackquoteTest{ string(11), false },
|
||||||
|
CanBackquoteTest{ string(12), false },
|
||||||
|
CanBackquoteTest{ string(13), false },
|
||||||
|
CanBackquoteTest{ string(14), false },
|
||||||
|
CanBackquoteTest{ string(15), false },
|
||||||
|
CanBackquoteTest{ string(16), false },
|
||||||
|
CanBackquoteTest{ string(17), false },
|
||||||
|
CanBackquoteTest{ string(18), false },
|
||||||
|
CanBackquoteTest{ string(19), false },
|
||||||
|
CanBackquoteTest{ string(20), false },
|
||||||
|
CanBackquoteTest{ string(21), false },
|
||||||
|
CanBackquoteTest{ string(22), false },
|
||||||
|
CanBackquoteTest{ string(23), false },
|
||||||
|
CanBackquoteTest{ string(24), false },
|
||||||
|
CanBackquoteTest{ string(25), false },
|
||||||
|
CanBackquoteTest{ string(26), false },
|
||||||
|
CanBackquoteTest{ string(27), false },
|
||||||
|
CanBackquoteTest{ string(28), false },
|
||||||
|
CanBackquoteTest{ string(29), false },
|
||||||
|
CanBackquoteTest{ string(30), false },
|
||||||
|
CanBackquoteTest{ string(31), false },
|
||||||
|
CanBackquoteTest{ `' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true },
|
||||||
|
CanBackquoteTest{ `0123456789`, true },
|
||||||
|
CanBackquoteTest{ `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true },
|
||||||
|
CanBackquoteTest{ `abcdefghijklmnopqrstuvwxyz`, true },
|
||||||
|
CanBackquoteTest{ `☺`, true },
|
||||||
|
}
|
||||||
|
|
||||||
|
export func TestCanBackquote(t *testing.T) {
|
||||||
|
for i := 0; i < len(canbackquotetests); i++ {
|
||||||
|
tt := canbackquotetests[i];
|
||||||
|
if out := CanBackquote(tt.in); out != tt.out {
|
||||||
|
t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,8 @@ package utf8
|
||||||
export const (
|
export const (
|
||||||
RuneError = 0xFFFD;
|
RuneError = 0xFFFD;
|
||||||
RuneSelf = 0x80;
|
RuneSelf = 0x80;
|
||||||
RuneMax = 1<<21 - 1;
|
RuneMax = 0x10FFFF;
|
||||||
|
UTFMax = 4;
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -32,7 +33,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func DecodeRuneInternal(p *[]byte) (rune, size int, short bool) {
|
func DecodeRuneInternal(p *[]byte) (rune, size int, short bool) {
|
||||||
if len(p) < 1 {
|
n := len(p);
|
||||||
|
if n < 1 {
|
||||||
return RuneError, 0, true;
|
return RuneError, 0, true;
|
||||||
}
|
}
|
||||||
c0 := p[0];
|
c0 := p[0];
|
||||||
|
|
@ -48,7 +50,7 @@ func DecodeRuneInternal(p *[]byte) (rune, size int, short bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// need first continuation byte
|
// need first continuation byte
|
||||||
if len(p) < 2 {
|
if n < 2 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true
|
||||||
}
|
}
|
||||||
c1 := p[1];
|
c1 := p[1];
|
||||||
|
|
@ -66,7 +68,7 @@ func DecodeRuneInternal(p *[]byte) (rune, size int, short bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// need second continuation byte
|
// need second continuation byte
|
||||||
if len(p) < 3 {
|
if n < 3 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true
|
||||||
}
|
}
|
||||||
c2 := p[2];
|
c2 := p[2];
|
||||||
|
|
@ -84,7 +86,7 @@ func DecodeRuneInternal(p *[]byte) (rune, size int, short bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// need third continuation byte
|
// need third continuation byte
|
||||||
if len(p) < 4 {
|
if n < 4 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true
|
||||||
}
|
}
|
||||||
c3 := p[3];
|
c3 := p[3];
|
||||||
|
|
@ -105,17 +107,103 @@ func DecodeRuneInternal(p *[]byte) (rune, size int, short bool) {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DecodeRuneInStringInternal(s string, i int) (rune, size int, short bool) {
|
||||||
|
n := len(s) - i;
|
||||||
|
if n < 1 {
|
||||||
|
return RuneError, 0, true;
|
||||||
|
}
|
||||||
|
c0 := s[i];
|
||||||
|
|
||||||
|
// 1-byte, 7-bit sequence?
|
||||||
|
if c0 < Tx {
|
||||||
|
return int(c0), 1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// unexpected continuation byte?
|
||||||
|
if c0 < T2 {
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// need first continuation byte
|
||||||
|
if n < 2 {
|
||||||
|
return RuneError, 1, true
|
||||||
|
}
|
||||||
|
c1 := s[i+1];
|
||||||
|
if c1 < Tx || T2 <= c1 {
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-byte, 11-bit sequence?
|
||||||
|
if c0 < T3 {
|
||||||
|
rune = int(c0&Mask2)<<6 | int(c1&Maskx);
|
||||||
|
if rune <= Rune1Max {
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
return rune, 2, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// need second continuation byte
|
||||||
|
if n < 3 {
|
||||||
|
return RuneError, 1, true
|
||||||
|
}
|
||||||
|
c2 := s[i+2];
|
||||||
|
if c2 < Tx || T2 <= c2 {
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3-byte, 16-bit sequence?
|
||||||
|
if c0 < T4 {
|
||||||
|
rune = int(c0&Mask3)<<12 | int(c1&Maskx)<<6 | int(c2&Maskx);
|
||||||
|
if rune <= Rune2Max {
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
return rune, 3, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// need third continuation byte
|
||||||
|
if n < 4 {
|
||||||
|
return RuneError, 1, true
|
||||||
|
}
|
||||||
|
c3 := s[i+3];
|
||||||
|
if c3 < Tx || T2 <= c3 {
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4-byte, 21-bit sequence?
|
||||||
|
if c0 < T5 {
|
||||||
|
rune = int(c0&Mask4)<<18 | int(c1&Maskx)<<12 | int(c2&Maskx)<<6 | int(c3&Maskx);
|
||||||
|
if rune <= Rune3Max {
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
return rune, 4, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
return RuneError, 1, false
|
||||||
|
}
|
||||||
|
|
||||||
export func FullRune(p *[]byte) bool {
|
export func FullRune(p *[]byte) bool {
|
||||||
rune, size, short := DecodeRuneInternal(p);
|
rune, size, short := DecodeRuneInternal(p);
|
||||||
return !short
|
return !short
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export func FullRuneInString(s string, i int) bool {
|
||||||
|
rune, size, short := DecodeRuneInStringInternal(s, i);
|
||||||
|
return !short
|
||||||
|
}
|
||||||
|
|
||||||
export func DecodeRune(p *[]byte) (rune, size int) {
|
export func DecodeRune(p *[]byte) (rune, size int) {
|
||||||
var short bool;
|
var short bool;
|
||||||
rune, size, short = DecodeRuneInternal(p);
|
rune, size, short = DecodeRuneInternal(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export func DecodeRuneInString(s string, i int) (rune, size int) {
|
||||||
|
var short bool;
|
||||||
|
rune, size, short = DecodeRuneInStringInternal(s, i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
export func RuneLen(rune int) int {
|
export func RuneLen(rune int) int {
|
||||||
switch {
|
switch {
|
||||||
case rune <= Rune1Max:
|
case rune <= Rune1Max:
|
||||||
|
|
|
||||||
|
|
@ -44,27 +44,6 @@ var utf8map = []Utf8Map {
|
||||||
Utf8Map{ 0x10ffff, "\xf4\x8f\xbf\xbf" },
|
Utf8Map{ 0x10ffff, "\xf4\x8f\xbf\xbf" },
|
||||||
}
|
}
|
||||||
|
|
||||||
func CEscape(s *[]byte) string {
|
|
||||||
t := "\"";
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
switch {
|
|
||||||
case s[i] == '\\' || s[i] == '"':
|
|
||||||
t += `\`;
|
|
||||||
t += string(s[i]);
|
|
||||||
case s[i] == '\n':
|
|
||||||
t += `\n`;
|
|
||||||
case s[i] == '\t':
|
|
||||||
t += `\t`;
|
|
||||||
case ' ' <= s[i] && s[i] <= '~':
|
|
||||||
t += string(s[i]);
|
|
||||||
default:
|
|
||||||
t += fmt.sprintf(`\x%02x`, s[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t += "\"";
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
func Bytes(s string) *[]byte {
|
func Bytes(s string) *[]byte {
|
||||||
b := new([]byte, len(s)+1);
|
b := new([]byte, len(s)+1);
|
||||||
if !syscall.StringToBytes(b, s) {
|
if !syscall.StringToBytes(b, s) {
|
||||||
|
|
@ -78,10 +57,19 @@ export func TestFullRune(t *testing.T) {
|
||||||
m := utf8map[i];
|
m := utf8map[i];
|
||||||
b := Bytes(m.str);
|
b := Bytes(m.str);
|
||||||
if !utf8.FullRune(b) {
|
if !utf8.FullRune(b) {
|
||||||
t.Errorf("FullRune(%s) (rune %04x) = false, want true", CEscape(b), m.rune);
|
t.Errorf("FullRune(%q) (rune %04x) = false, want true", b, m.rune);
|
||||||
}
|
}
|
||||||
if b1 := b[0:len(b)-1]; utf8.FullRune(b1) {
|
s := "xx"+m.str;
|
||||||
t.Errorf("FullRune(%s) = true, want false", CEscape(b1));
|
if !utf8.FullRuneInString(s, 2) {
|
||||||
|
t.Errorf("FullRuneInString(%q, 2) (rune %04x) = false, want true", s, m.rune);
|
||||||
|
}
|
||||||
|
b1 := b[0:len(b)-1];
|
||||||
|
if utf8.FullRune(b1) {
|
||||||
|
t.Errorf("FullRune(%q) = true, want false", b1);
|
||||||
|
}
|
||||||
|
s1 := "xxx"+string(b1);
|
||||||
|
if utf8.FullRuneInString(s1, 3) {
|
||||||
|
t.Errorf("FullRune(%q, 3) = true, want false", s1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +94,7 @@ export func TestEncodeRune(t *testing.T) {
|
||||||
n := utf8.EncodeRune(m.rune, &buf);
|
n := utf8.EncodeRune(m.rune, &buf);
|
||||||
b1 := (&buf)[0:n];
|
b1 := (&buf)[0:n];
|
||||||
if !EqualBytes(b, b1) {
|
if !EqualBytes(b, b1) {
|
||||||
t.Errorf("EncodeRune(0x%04x) = %s want %s", m.rune, CEscape(b1), CEscape(b));
|
t.Errorf("EncodeRune(0x%04x) = %q want %q", m.rune, b1, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,23 +105,38 @@ export func TestDecodeRune(t *testing.T) {
|
||||||
b := Bytes(m.str);
|
b := Bytes(m.str);
|
||||||
rune, size := utf8.DecodeRune(b);
|
rune, size := utf8.DecodeRune(b);
|
||||||
if rune != m.rune || size != len(b) {
|
if rune != m.rune || size != len(b) {
|
||||||
t.Errorf("DecodeRune(%s) = 0x%04x, %d want 0x%04x, %d", CEscape(b), rune, size, m.rune, len(b));
|
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b, rune, size, m.rune, len(b));
|
||||||
|
}
|
||||||
|
s := "xx"+m.str;
|
||||||
|
rune, size = utf8.DecodeRuneInString(s, 2);
|
||||||
|
if rune != m.rune || size != len(b) {
|
||||||
|
t.Errorf("DecodeRune(%q, 2) = 0x%04x, %d want 0x%04x, %d", s, rune, size, m.rune, len(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
// there's an extra byte that Bytes left behind - make sure trailing byte works
|
// there's an extra byte that Bytes left behind - make sure trailing byte works
|
||||||
rune, size = utf8.DecodeRune(b[0:cap(b)]);
|
rune, size = utf8.DecodeRune(b[0:cap(b)]);
|
||||||
if rune != m.rune || size != len(b) {
|
if rune != m.rune || size != len(b) {
|
||||||
t.Errorf("DecodeRune(%s) = 0x%04x, %d want 0x%04x, %d", CEscape(b), rune, size, m.rune, len(b));
|
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b, rune, size, m.rune, len(b));
|
||||||
|
}
|
||||||
|
s = "x"+m.str+"\x00";
|
||||||
|
rune, size = utf8.DecodeRuneInString(s, 1);
|
||||||
|
if rune != m.rune || size != len(b) {
|
||||||
|
t.Errorf("DecodeRuneInString(%q, 1) = 0x%04x, %d want 0x%04x, %d", s, rune, size, m.rune, len(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure missing bytes fail
|
// make sure missing bytes fail
|
||||||
rune, size = utf8.DecodeRune(b[0:len(b)-1]);
|
|
||||||
wantsize := 1;
|
wantsize := 1;
|
||||||
if wantsize >= len(b) {
|
if wantsize >= len(b) {
|
||||||
wantsize = 0;
|
wantsize = 0;
|
||||||
}
|
}
|
||||||
|
rune, size = utf8.DecodeRune(b[0:len(b)-1]);
|
||||||
if rune != RuneError || size != wantsize {
|
if rune != RuneError || size != wantsize {
|
||||||
t.Errorf("DecodeRune(%s) = 0x%04x, %d want 0x%04x, %d", CEscape(b[0:len(b)-1]), rune, size, RuneError, wantsize);
|
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b[0:len(b)-1], rune, size, RuneError, wantsize);
|
||||||
|
}
|
||||||
|
s = "xxx"+m.str[0:len(m.str)-1];
|
||||||
|
rune, size = utf8.DecodeRuneInString(s, 3);
|
||||||
|
if rune != RuneError || size != wantsize {
|
||||||
|
t.Errorf("DecodeRuneInString(%q, 3) = 0x%04x, %d want 0x%04x, %d", s, rune, size, RuneError, wantsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure bad sequences fail
|
// make sure bad sequences fail
|
||||||
|
|
@ -144,7 +147,12 @@ export func TestDecodeRune(t *testing.T) {
|
||||||
}
|
}
|
||||||
rune, size = utf8.DecodeRune(b);
|
rune, size = utf8.DecodeRune(b);
|
||||||
if rune != RuneError || size != 1 {
|
if rune != RuneError || size != 1 {
|
||||||
t.Errorf("DecodeRune(%s) = 0x%04x, %d want 0x%04x, %d", CEscape(b), rune, size, RuneError, 1);
|
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b, rune, size, RuneError, 1);
|
||||||
|
}
|
||||||
|
s = "xxxx"+string(b);
|
||||||
|
rune, size = utf8.DecodeRune(b);
|
||||||
|
if rune != RuneError || size != 1 {
|
||||||
|
t.Errorf("DecodeRuneInString(%q, 4) = 0x%04x, %d want 0x%04x, %d", s, rune, size, RuneError, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// $G $F.go && $L $F.$A && ./$A.out
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import fmt "fmt" // BUG: shouldn't need the first 'fmt'.
|
|
||||||
|
|
||||||
func E(f *fmt.Fmt, e string) {
|
|
||||||
g := f.str();
|
|
||||||
if sys.argc() > 1 {
|
|
||||||
print(g, "\n");
|
|
||||||
if g != e {
|
|
||||||
print("expected <", e, ">\n");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if g != e {
|
|
||||||
print("expected <", e, ">\n");
|
|
||||||
print("got <", g, ">\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const B32 = 1<<32 - 1
|
|
||||||
const B64 = 1<<64 - 1
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
f := fmt.New();
|
|
||||||
E(f.s("d ").d(1234), "d 1234");
|
|
||||||
E(f.s("Simple output\n"), "Simple output\n");
|
|
||||||
E(f.s("\td ").d(-1234), "\td -1234");
|
|
||||||
E(f.s("\tud ").ud(B32), "\tud 4294967295");
|
|
||||||
E(f.s("\tud64 ").ud64(B64), "\tud64 18446744073709551615");
|
|
||||||
E(f.s("\to ").o(01234), "\to 1234");
|
|
||||||
E(f.s("\tuo ").uo(B32), "\tuo 37777777777");
|
|
||||||
E(f.s("\tuo64 ").uo64(B64), "\tuo64 1777777777777777777777");
|
|
||||||
E(f.s("\tx ").x(0x1234abcd), "\tx 1234abcd");
|
|
||||||
E(f.s("\tux ").ux(B32 - 0x01234567), "\tux fedcba98");
|
|
||||||
E(f.s("\tX ").X(0x1234abcd), "\tX 1234ABCD");
|
|
||||||
E(f.s("\tuX ").uX(B32 - 0x01234567), "\tuX FEDCBA98");
|
|
||||||
E(f.s("\tux64 ").ux64(B64), "\tux64 ffffffffffffffff");
|
|
||||||
E(f.s("\tb ").b(7), "\tb 111");
|
|
||||||
E(f.s("\tb64 ").b64(B64), "\tb64 1111111111111111111111111111111111111111111111111111111111111111");
|
|
||||||
E(f.s("\te ").e64(1.), "\te 1.000000e+00");
|
|
||||||
E(f.s("\te ").e64(1234.5678e3), "\te 1.234568e+06");
|
|
||||||
E(f.s("\te ").e64(1234.5678e-8), "\te 1.234568e-05");
|
|
||||||
E(f.s("\te ").e64(-7.0), "\te -7.000000e+00");
|
|
||||||
E(f.s("\te ").e64(-1e-9), "\te -1.000000e-09");
|
|
||||||
E(f.s("\tf ").f64(1234.5678e3), "\tf 1234567.800000");
|
|
||||||
E(f.s("\tf ").f64(1234.5678e-8), "\tf 0.000012");
|
|
||||||
E(f.s("\tf ").f64(-7.0), "\tf -7.000000");
|
|
||||||
E(f.s("\tf ").f64(-1e-9), "\tf -0.000000");
|
|
||||||
E(f.s("\tg ").g64(1234.5678e3), "\tg 1.2345678e+06");
|
|
||||||
E(f.s("\tg ").g64(1234.5678e-8), "\tg 1.2345678e-05");
|
|
||||||
E(f.s("\tg ").g64(-7.0), "\tg -7");
|
|
||||||
E(f.s("\tg ").g64(-1e-9), "\tg -1e-09");
|
|
||||||
E(f.s("\tc ").c('x'), "\tc x");
|
|
||||||
E(f.s("\tc ").c(0xe4), "\tc ä");
|
|
||||||
E(f.s("\tc ").c(0x672c), "\tc 本");
|
|
||||||
E(f.s("\tc ").c('日'), "\tc 日");
|
|
||||||
|
|
||||||
E(f.s("Flags, width, and precision"), "Flags, width, and precision");
|
|
||||||
E(f.s("\t\t|123456789_123456789_"), "\t\t|123456789_123456789_");
|
|
||||||
E(f.s("\t20.8d\t|").wp(20,8).d(1234).s("|"), "\t20.8d\t| 00001234|");
|
|
||||||
E(f.s("\t20.8d\t|").wp(20,8).d(-1234).s("|"), "\t20.8d\t| -00001234|");
|
|
||||||
E(f.s("\t20d\t|").w(20).d(1234).s("|"), "\t20d\t| 1234|");
|
|
||||||
E(f.s("\t-20.8d\t|").wp(-20,8).d(1234).s("|"), "\t-20.8d\t|00001234 |");
|
|
||||||
E(f.s("\t-20.8d\t|").wp(-20,8).d(-1234).s("|"), "\t-20.8d\t|-00001234 |");
|
|
||||||
E(f.s("\t.20b\t|").p(20).b(7).s("|"), "\t.20b\t|00000000000000000111|");
|
|
||||||
E(f.s("\t20.5s\t|").wp(20,5).s("qwertyuiop").s("|"), "\t20.5s\t| qwert|");
|
|
||||||
E(f.s("\t.5s\t|").p(5).s("qwertyuiop").s("|"), "\t.5s\t|qwert|");
|
|
||||||
E(f.s("\t-20.5s\t|").wp(-20,5).s("qwertyuiop").s("|"), "\t-20.5s\t|qwert |");
|
|
||||||
E(f.s("\t20c\t|").w(20).c('x').s("|"), "\t20c\t| x|");
|
|
||||||
E(f.s("\t-20c\t|").w(-20).c('x').s("|"), "\t-20c\t|x |");
|
|
||||||
E(f.s("\t20e\t|").wp(20, 6).e(1.2345e3).s("|"), "\t20e\t| 1.234500e+03|");
|
|
||||||
E(f.s("\t20e\t|").wp(20, 6).e(1.2345e-3).s("|"), "\t20e\t| 1.234500e-03|");
|
|
||||||
E(f.s("\t-20e\t|").wp(-20, 6).e(1.2345e3).s("|"), "\t-20e\t|1.234500e+03 |");
|
|
||||||
E(f.s("\t20.8e\t|").wp(20,8).e(1.2345e3).s("|"), "\t20.8e\t| 1.23450000e+03|");
|
|
||||||
E(f.s("\t20f\t|").w(20).f64(1.23456789e3).s("|"), "\t20f\t| 1234.567890|");
|
|
||||||
E(f.s("\t20f\t|").w(20).f64(1.23456789e-3).s("|"), "\t20f\t| 0.001235|");
|
|
||||||
E(f.s("\t20f\t|").w(20).f64(12345678901.23456789).s("|"), "\t20f\t| 12345678901.234568|");
|
|
||||||
E(f.s("\t-20f\t|").w(-20).f64(1.23456789e3).s("|"), "\t-20f\t|1234.567890 |");
|
|
||||||
E(f.s("\t20.8f\t|").wp(20,8).f64(1.23456789e3).s("|"), "\t20.8f\t| 1234.56789000|");
|
|
||||||
E(f.s("\t20.8f\t|").wp(20,8).f64(1.23456789e-3).s("|"), "\t20.8f\t| 0.00123457|");
|
|
||||||
E(f.s("\tg\t|").g64(1.23456789e3).s("|"), "\tg\t|1234.56789|");
|
|
||||||
E(f.s("\tg\t|").g64(1.23456789e-3).s("|"), "\tg\t|0.00123456789|");
|
|
||||||
E(f.s("\tg\t|").g64(1.23456789e20).s("|"), "\tg\t|1.23456789e+20|");
|
|
||||||
|
|
||||||
E(f.s("\tE\t|").w(20).g64(sys.Inf(1)).s("|"), "\tE\t| +Inf|");
|
|
||||||
E(f.s("\tF\t|").w(-20).g64(sys.Inf(-1)).s("|"), "\tF\t|-Inf |");
|
|
||||||
E(f.s("\tG\t|").w(20).g64(sys.NaN()).s("|"), "\tG\t| NaN|");
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue