mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
more lgtm files from gofmt
R=gri OCL=35485 CL=35488
This commit is contained in:
parent
8231548365
commit
094f1d5990
78 changed files with 1517 additions and 1441 deletions
|
|
@ -50,7 +50,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
const Pkg = "/pkg/"; // name for auto-generated package documentation tree
|
const Pkg = "/pkg/" // name for auto-generated package documentation tree
|
||||||
|
|
||||||
|
|
||||||
type delayTime struct {
|
type delayTime struct {
|
||||||
|
|
@ -70,7 +70,7 @@ func (dt *delayTime) backoff(max int) {
|
||||||
dt.mutex.Lock();
|
dt.mutex.Lock();
|
||||||
dt.minutes *= 2;
|
dt.minutes *= 2;
|
||||||
if dt.minutes > max {
|
if dt.minutes > max {
|
||||||
dt.minutes = max
|
dt.minutes = max;
|
||||||
}
|
}
|
||||||
dt.mutex.Unlock();
|
dt.mutex.Unlock();
|
||||||
}
|
}
|
||||||
|
|
@ -140,8 +140,7 @@ func init() {
|
||||||
// Support
|
// Support
|
||||||
|
|
||||||
func isGoFile(dir *os.Dir) bool {
|
func isGoFile(dir *os.Dir) bool {
|
||||||
return
|
return dir.IsRegular() &&
|
||||||
dir.IsRegular() &&
|
|
||||||
!strings.HasPrefix(dir.Name, ".") && // ignore .files
|
!strings.HasPrefix(dir.Name, ".") && // ignore .files
|
||||||
pathutil.Ext(dir.Name) == ".go" &&
|
pathutil.Ext(dir.Name) == ".go" &&
|
||||||
!strings.HasSuffix(dir.Name, "_test.go"); // ignore test files
|
!strings.HasSuffix(dir.Name, "_test.go"); // ignore test files
|
||||||
|
|
@ -289,7 +288,9 @@ func textFmt(w io.Writer, x interface{}, format string) {
|
||||||
|
|
||||||
// Template formatter for "link" format.
|
// Template formatter for "link" format.
|
||||||
func linkFmt(w io.Writer, x interface{}, format string) {
|
func linkFmt(w io.Writer, x interface{}, format string) {
|
||||||
type Positioner interface { Pos() token.Position }
|
type Positioner interface {
|
||||||
|
Pos() token.Position;
|
||||||
|
}
|
||||||
if node, ok := x.(Positioner); ok {
|
if node, ok := x.(Positioner); ok {
|
||||||
pos := node.Pos();
|
pos := node.Pos();
|
||||||
if pos.IsValid() {
|
if pos.IsValid() {
|
||||||
|
|
@ -326,8 +327,8 @@ func readTemplate(name string) *template.Template {
|
||||||
var godocHtml *template.Template
|
var godocHtml *template.Template
|
||||||
var packageHtml *template.Template
|
var packageHtml *template.Template
|
||||||
var packageText *template.Template
|
var packageText *template.Template
|
||||||
var parseerrorHtml *template.Template;
|
var parseerrorHtml *template.Template
|
||||||
var parseerrorText *template.Template;
|
var parseerrorText *template.Template
|
||||||
|
|
||||||
func readTemplates() {
|
func readTemplates() {
|
||||||
// have to delay until after flags processing,
|
// have to delay until after flags processing,
|
||||||
|
|
@ -436,7 +437,7 @@ func serveGoSource(c *http.Conn, filename string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var fileServer = http.FileServer(".", "");
|
var fileServer = http.FileServer(".", "")
|
||||||
|
|
||||||
func serveFile(c *http.Conn, r *http.Request) {
|
func serveFile(c *http.Conn, r *http.Request) {
|
||||||
path := r.Url.Path;
|
path := r.Url.Path;
|
||||||
|
|
@ -471,9 +472,15 @@ func serveFile(c *http.Conn, r *http.Request) {
|
||||||
// TODO if we don't plan to use the directory information, simplify to []string
|
// TODO if we don't plan to use the directory information, simplify to []string
|
||||||
type dirList []*os.Dir
|
type dirList []*os.Dir
|
||||||
|
|
||||||
func (d dirList) Len() int { return len(d) }
|
func (d dirList) Len() int {
|
||||||
func (d dirList) Less(i, j int) bool { return d[i].Name < d[j].Name }
|
return len(d);
|
||||||
func (d dirList) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
}
|
||||||
|
func (d dirList) Less(i, j int) bool {
|
||||||
|
return d[i].Name < d[j].Name;
|
||||||
|
}
|
||||||
|
func (d dirList) Swap(i, j int) {
|
||||||
|
d[i], d[j] = d[j], d[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func pkgName(filename string) string {
|
func pkgName(filename string) string {
|
||||||
|
|
@ -593,7 +600,7 @@ func loggingHandler(h http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
|
return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
|
||||||
log.Stderrf("%s\t%s", c.RemoteAddr, req.Url);
|
log.Stderrf("%s\t%s", c.RemoteAddr, req.Url);
|
||||||
h.ServeHTTP(c, req);
|
h.ServeHTTP(c, req);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -659,8 +666,7 @@ func dosync(c *http.Conn, r *http.Request) {
|
||||||
func usage() {
|
func usage() {
|
||||||
fmt.Fprintf(os.Stderr,
|
fmt.Fprintf(os.Stderr,
|
||||||
"usage: godoc package [name ...]\n"
|
"usage: godoc package [name ...]\n"
|
||||||
" godoc -http=:6060\n"
|
" godoc -http=:6060\n");
|
||||||
);
|
|
||||||
flag.PrintDefaults();
|
flag.PrintDefaults();
|
||||||
os.Exit(2);
|
os.Exit(2);
|
||||||
}
|
}
|
||||||
|
|
@ -725,7 +731,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := http.ListenAndServe(*httpaddr, handler); err != nil {
|
if err := http.ListenAndServe(*httpaddr, handler); err != nil {
|
||||||
log.Exitf("ListenAndServe %s: %v", *httpaddr, err)
|
log.Exitf("ListenAndServe %s: %v", *httpaddr, err);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,7 @@ func (p *ebnfParser) parseTerm() bool {
|
||||||
|
|
||||||
|
|
||||||
func (p *ebnfParser) parseSequence() {
|
func (p *ebnfParser) parseSequence() {
|
||||||
for p.parseTerm() {
|
for p.parseTerm() {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
// - buffered output
|
// - buffered output
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultBufSize = 4096
|
defaultBufSize = 4096;
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errors introduced by this package.
|
// Errors introduced by this package.
|
||||||
|
|
@ -38,13 +38,14 @@ var (
|
||||||
|
|
||||||
// BufSizeError is the error representing an invalid buffer size.
|
// BufSizeError is the error representing an invalid buffer size.
|
||||||
type BufSizeError int
|
type BufSizeError int
|
||||||
|
|
||||||
func (b BufSizeError) String() string {
|
func (b BufSizeError) String() string {
|
||||||
return "bufio: bad buffer size " + strconv.Itoa(int(b));
|
return "bufio: bad buffer size " + strconv.Itoa(int(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
func copySlice(dst []byte, src []byte) {
|
func copySlice(dst []byte, src []byte) {
|
||||||
for i := 0; i < len(dst); i++ {
|
for i := 0; i < len(dst); i++ {
|
||||||
dst[i] = src[i]
|
dst[i] = src[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,18 +67,18 @@ type Reader struct {
|
||||||
// It returns the Reader and any error.
|
// It returns the Reader and any error.
|
||||||
func NewReaderSize(rd io.Reader, size int) (*Reader, os.Error) {
|
func NewReaderSize(rd io.Reader, size int) (*Reader, os.Error) {
|
||||||
if size <= 0 {
|
if size <= 0 {
|
||||||
return nil, BufSizeError(size)
|
return nil, BufSizeError(size);
|
||||||
}
|
}
|
||||||
// Is it already a Reader?
|
// Is it already a Reader?
|
||||||
b, ok := rd.(*Reader);
|
b, ok := rd.(*Reader);
|
||||||
if ok && len(b.buf) >= size {
|
if ok && len(b.buf) >= size {
|
||||||
return b, nil
|
return b, nil;
|
||||||
}
|
}
|
||||||
b = new(Reader);
|
b = new(Reader);
|
||||||
b.buf = make([]byte, size);
|
b.buf = make([]byte, size);
|
||||||
b.rd = rd;
|
b.rd = rd;
|
||||||
b.lastbyte = -1;
|
b.lastbyte = -1;
|
||||||
return b, nil
|
return b, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReader returns a new Reader whose buffer has the default size.
|
// NewReader returns a new Reader whose buffer has the default size.
|
||||||
|
|
@ -97,7 +98,7 @@ func (b *Reader) fill() {
|
||||||
copySlice(b.buf[0 : b.w - b.r], b.buf[b.r : b.w]);
|
copySlice(b.buf[0 : b.w - b.r], b.buf[b.r : b.w]);
|
||||||
b.w -= b.r;
|
b.w -= b.r;
|
||||||
} else {
|
} else {
|
||||||
b.w = 0
|
b.w = 0;
|
||||||
}
|
}
|
||||||
b.r = 0;
|
b.r = 0;
|
||||||
|
|
||||||
|
|
@ -120,7 +121,7 @@ func (b *Reader) Read(p []byte) (nn int, err os.Error) {
|
||||||
n := len(p);
|
n := len(p);
|
||||||
if b.w == b.r {
|
if b.w == b.r {
|
||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
return nn, b.err
|
return nn, b.err;
|
||||||
}
|
}
|
||||||
if len(p) >= len(b.buf) {
|
if len(p) >= len(b.buf) {
|
||||||
// Large read, empty buffer.
|
// Large read, empty buffer.
|
||||||
|
|
@ -137,15 +138,15 @@ func (b *Reader) Read(p []byte) (nn int, err os.Error) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if n > b.w - b.r {
|
if n > b.w - b.r {
|
||||||
n = b.w - b.r
|
n = b.w - b.r;
|
||||||
}
|
}
|
||||||
copySlice(p[0:n], b.buf[b.r : b.r + n]);
|
copySlice(p[0:n], b.buf[b.r : b.r + n]);
|
||||||
p = p[n:len(p)];
|
p = p[n:len(p)];
|
||||||
b.r += n;
|
b.r += n;
|
||||||
b.lastbyte = int(b.buf[b.r - 1]);
|
b.lastbyte = int(b.buf[b.r - 1]);
|
||||||
nn += n
|
nn += n;
|
||||||
}
|
}
|
||||||
return nn, nil
|
return nn, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadByte reads and returns a single byte.
|
// ReadByte reads and returns a single byte.
|
||||||
|
|
@ -153,14 +154,14 @@ func (b *Reader) Read(p []byte) (nn int, err os.Error) {
|
||||||
func (b *Reader) ReadByte() (c byte, err os.Error) {
|
func (b *Reader) ReadByte() (c byte, err os.Error) {
|
||||||
for b.w == b.r {
|
for b.w == b.r {
|
||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
return 0, b.err
|
return 0, b.err;
|
||||||
}
|
}
|
||||||
b.fill();
|
b.fill();
|
||||||
}
|
}
|
||||||
c = b.buf[b.r];
|
c = b.buf[b.r];
|
||||||
b.r++;
|
b.r++;
|
||||||
b.lastbyte = int(c);
|
b.lastbyte = int(c);
|
||||||
return c, nil
|
return c, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnreadByte unreads the last byte. Only the most recently read byte can be unread.
|
// UnreadByte unreads the last byte. Only the most recently read byte can be unread.
|
||||||
|
|
@ -173,11 +174,11 @@ func (b *Reader) UnreadByte() os.Error {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if b.r <= 0 {
|
if b.r <= 0 {
|
||||||
return ErrInvalidUnreadByte
|
return ErrInvalidUnreadByte;
|
||||||
}
|
}
|
||||||
b.r--;
|
b.r--;
|
||||||
b.lastbyte = -1;
|
b.lastbyte = -1;
|
||||||
return nil
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadRune reads a single UTF-8 encoded Unicode character and returns the
|
// ReadRune reads a single UTF-8 encoded Unicode character and returns the
|
||||||
|
|
@ -195,7 +196,7 @@ func (b *Reader) ReadRune() (rune int, size int, err os.Error) {
|
||||||
}
|
}
|
||||||
b.r += size;
|
b.r += size;
|
||||||
b.lastbyte = int(b.buf[b.r - 1]);
|
b.lastbyte = int(b.buf[b.r - 1]);
|
||||||
return rune, size, nil
|
return rune, size, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function: look for byte c in array p,
|
// Helper function: look for byte c in array p,
|
||||||
|
|
@ -203,10 +204,10 @@ func (b *Reader) ReadRune() (rune int, size int, err os.Error) {
|
||||||
func findByte(p []byte, c byte) int {
|
func findByte(p []byte, c byte) int {
|
||||||
for i := 0; i < len(p); i++ {
|
for i := 0; i < len(p); i++ {
|
||||||
if p[i] == c {
|
if p[i] == c {
|
||||||
return i
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffered returns the number of bytes that can be read from the current buffer.
|
// Buffered returns the number of bytes that can be read from the current buffer.
|
||||||
|
|
@ -229,7 +230,7 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err os.Error) {
|
||||||
if i := findByte(b.buf[b.r : b.w], delim); i >= 0 {
|
if i := findByte(b.buf[b.r : b.w], delim); i >= 0 {
|
||||||
line1 := b.buf[b.r : b.r + i + 1];
|
line1 := b.buf[b.r : b.r + i + 1];
|
||||||
b.r += i+1;
|
b.r += i+1;
|
||||||
return line1, nil
|
return line1, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read more into buffer, until buffer fills or we find delim.
|
// Read more into buffer, until buffer fills or we find delim.
|
||||||
|
|
@ -237,7 +238,7 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err os.Error) {
|
||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
line := b.buf[b.r : b.w];
|
line := b.buf[b.r : b.w];
|
||||||
b.r = b.w;
|
b.r = b.w;
|
||||||
return line, b.err
|
return line, b.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
n := b.Buffered();
|
n := b.Buffered();
|
||||||
|
|
@ -247,12 +248,12 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err os.Error) {
|
||||||
if i := findByte(b.buf[n : b.w], delim); i >= 0 {
|
if i := findByte(b.buf[n : b.w], delim); i >= 0 {
|
||||||
line := b.buf[0 : n+i+1];
|
line := b.buf[0 : n+i+1];
|
||||||
b.r = n+i+1;
|
b.r = n+i+1;
|
||||||
return line, nil
|
return line, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer is full?
|
// Buffer is full?
|
||||||
if b.Buffered() >= len(b.buf) {
|
if b.Buffered() >= len(b.buf) {
|
||||||
return nil, ErrBufferFull
|
return nil, ErrBufferFull;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic("not reached");
|
panic("not reached");
|
||||||
|
|
@ -275,11 +276,11 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
|
||||||
var e os.Error;
|
var e os.Error;
|
||||||
frag, e = b.ReadSlice(delim);
|
frag, e = b.ReadSlice(delim);
|
||||||
if e == nil { // got final fragment
|
if e == nil { // got final fragment
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
if e != ErrBufferFull { // unexpected error
|
if e != ErrBufferFull { // unexpected error
|
||||||
err = e;
|
err = e;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read bytes out of buffer.
|
// Read bytes out of buffer.
|
||||||
|
|
@ -289,12 +290,12 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
|
||||||
if e != nil {
|
if e != nil {
|
||||||
frag = buf[0:n];
|
frag = buf[0:n];
|
||||||
err = e;
|
err = e;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
if n != len(buf) {
|
if n != len(buf) {
|
||||||
frag = buf[0:n];
|
frag = buf[0:n];
|
||||||
err = errInternal;
|
err = errInternal;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grow list if needed.
|
// Grow list if needed.
|
||||||
|
|
@ -305,7 +306,7 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
|
||||||
for i := 0; i < len(full); i++ {
|
for i := 0; i < len(full); i++ {
|
||||||
newfull[i] = full[i];
|
newfull[i] = full[i];
|
||||||
}
|
}
|
||||||
full = newfull
|
full = newfull;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save buffer
|
// Save buffer
|
||||||
|
|
@ -316,7 +317,7 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
|
||||||
// Allocate new buffer to hold the full pieces and the fragment.
|
// Allocate new buffer to hold the full pieces and the fragment.
|
||||||
n := 0;
|
n := 0;
|
||||||
for i := 0; i < nfull; i++ {
|
for i := 0; i < nfull; i++ {
|
||||||
n += len(full[i])
|
n += len(full[i]);
|
||||||
}
|
}
|
||||||
n += len(frag);
|
n += len(frag);
|
||||||
|
|
||||||
|
|
@ -325,10 +326,10 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
|
||||||
n = 0;
|
n = 0;
|
||||||
for i := 0; i < nfull; i++ {
|
for i := 0; i < nfull; i++ {
|
||||||
copySlice(buf[n : n+len(full[i])], full[i]);
|
copySlice(buf[n : n+len(full[i])], full[i]);
|
||||||
n += len(full[i])
|
n += len(full[i]);
|
||||||
}
|
}
|
||||||
copySlice(buf[n : n+len(frag)], frag);
|
copySlice(buf[n : n+len(frag)], frag);
|
||||||
return buf, err
|
return buf, err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadString reads until the first occurrence of delim in the input,
|
// ReadString reads until the first occurrence of delim in the input,
|
||||||
|
|
@ -358,17 +359,17 @@ type Writer struct {
|
||||||
// It returns the Writer and any error.
|
// It returns the Writer and any error.
|
||||||
func NewWriterSize(wr io.Writer, size int) (*Writer, os.Error) {
|
func NewWriterSize(wr io.Writer, size int) (*Writer, os.Error) {
|
||||||
if size <= 0 {
|
if size <= 0 {
|
||||||
return nil, BufSizeError(size)
|
return nil, BufSizeError(size);
|
||||||
}
|
}
|
||||||
// Is it already a Writer?
|
// Is it already a Writer?
|
||||||
b, ok := wr.(*Writer);
|
b, ok := wr.(*Writer);
|
||||||
if ok && len(b.buf) >= size {
|
if ok && len(b.buf) >= size {
|
||||||
return b, nil
|
return b, nil;
|
||||||
}
|
}
|
||||||
b = new(Writer);
|
b = new(Writer);
|
||||||
b.buf = make([]byte, size);
|
b.buf = make([]byte, size);
|
||||||
b.wr = wr;
|
b.wr = wr;
|
||||||
return b, nil
|
return b, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWriter returns a new Writer whose buffer has the default size.
|
// NewWriter returns a new Writer whose buffer has the default size.
|
||||||
|
|
@ -384,7 +385,7 @@ func NewWriter(wr io.Writer) *Writer {
|
||||||
// Flush writes any buffered data to the underlying io.Writer.
|
// Flush writes any buffered data to the underlying io.Writer.
|
||||||
func (b *Writer) Flush() os.Error {
|
func (b *Writer) Flush() os.Error {
|
||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
return b.err
|
return b.err;
|
||||||
}
|
}
|
||||||
n, e := b.wr.Write(b.buf[0 : b.n]);
|
n, e := b.wr.Write(b.buf[0 : b.n]);
|
||||||
if n < b.n && e == nil {
|
if n < b.n && e == nil {
|
||||||
|
|
@ -392,24 +393,24 @@ func (b *Writer) Flush() os.Error {
|
||||||
}
|
}
|
||||||
if e != nil {
|
if e != nil {
|
||||||
if n > 0 && n < b.n {
|
if n > 0 && n < b.n {
|
||||||
copySlice(b.buf[0:b.n-n], b.buf[n:b.n])
|
copySlice(b.buf[0 : b.n - n], b.buf[n : b.n]);
|
||||||
}
|
}
|
||||||
b.n -= n;
|
b.n -= n;
|
||||||
b.err = e;
|
b.err = e;
|
||||||
return e
|
return e;
|
||||||
}
|
}
|
||||||
b.n = 0;
|
b.n = 0;
|
||||||
return nil
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Available returns how many bytes are unused in the buffer.
|
// Available returns how many bytes are unused in the buffer.
|
||||||
func (b *Writer) Available() int {
|
func (b *Writer) Available() int {
|
||||||
return len(b.buf) - b.n
|
return len(b.buf) - b.n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffered returns the number of bytes that have been written into the current buffer.
|
// Buffered returns the number of bytes that have been written into the current buffer.
|
||||||
func (b *Writer) Buffered() int {
|
func (b *Writer) Buffered() int {
|
||||||
return b.n
|
return b.n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes the contents of p into the buffer.
|
// Write writes the contents of p into the buffer.
|
||||||
|
|
@ -418,16 +419,16 @@ func (b *Writer) Buffered() int {
|
||||||
// why the write is short.
|
// why the write is short.
|
||||||
func (b *Writer) Write(p []byte) (nn int, err os.Error) {
|
func (b *Writer) Write(p []byte) (nn int, err os.Error) {
|
||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
return 0, b.err
|
return 0, b.err;
|
||||||
}
|
}
|
||||||
nn = 0;
|
nn = 0;
|
||||||
for len(p) > 0 {
|
for len(p) > 0 {
|
||||||
n := b.Available();
|
n := b.Available();
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
if b.Flush(); b.err != nil {
|
if b.Flush(); b.err != nil {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
n = b.Available()
|
n = b.Available();
|
||||||
}
|
}
|
||||||
if b.Available() == 0 && len(p) >= len(b.buf) {
|
if b.Available() == 0 && len(p) >= len(b.buf) {
|
||||||
// Large write, empty buffer.
|
// Large write, empty buffer.
|
||||||
|
|
@ -441,33 +442,33 @@ func (b *Writer) Write(p []byte) (nn int, err os.Error) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if n > len(p) {
|
if n > len(p) {
|
||||||
n = len(p)
|
n = len(p);
|
||||||
}
|
}
|
||||||
copySlice(b.buf[b.n : b.n + n], p[0:n]);
|
copySlice(b.buf[b.n : b.n + n], p[0:n]);
|
||||||
b.n += n;
|
b.n += n;
|
||||||
nn += n;
|
nn += n;
|
||||||
p = p[n:len(p)]
|
p = p[n:len(p)];
|
||||||
}
|
}
|
||||||
return nn, b.err
|
return nn, b.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteByte writes a single byte.
|
// WriteByte writes a single byte.
|
||||||
func (b *Writer) WriteByte(c byte) os.Error {
|
func (b *Writer) WriteByte(c byte) os.Error {
|
||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
return b.err
|
return b.err;
|
||||||
}
|
}
|
||||||
if b.Available() <= 0 && b.Flush() != nil {
|
if b.Available() <= 0 && b.Flush() != nil {
|
||||||
return b.err
|
return b.err;
|
||||||
}
|
}
|
||||||
b.buf[b.n] = c;
|
b.buf[b.n] = c;
|
||||||
b.n++;
|
b.n++;
|
||||||
return nil
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteString writes a string.
|
// WriteString writes a string.
|
||||||
func (b *Writer) WriteString(s string) os.Error {
|
func (b *Writer) WriteString(s string) os.Error {
|
||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
return b.err
|
return b.err;
|
||||||
}
|
}
|
||||||
// Common case, worth making fast.
|
// Common case, worth making fast.
|
||||||
if b.Available() >= len(s) || len(b.buf) >= len(s) && b.Flush() == nil {
|
if b.Available() >= len(s) || len(b.buf) >= len(s) && b.Flush() == nil {
|
||||||
|
|
@ -480,7 +481,7 @@ func (b *Writer) WriteString(s string) os.Error {
|
||||||
for i := 0; i < len(s); i++ { // loop over bytes, not runes.
|
for i := 0; i < len(s); i++ { // loop over bytes, not runes.
|
||||||
b.WriteByte(s[i]);
|
b.WriteByte(s[i]);
|
||||||
}
|
}
|
||||||
return b.err
|
return b.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// buffered input and output
|
// buffered input and output
|
||||||
|
|
@ -494,6 +495,5 @@ type ReadWriter struct {
|
||||||
|
|
||||||
// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
|
// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
|
||||||
func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
|
func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
|
||||||
return &ReadWriter{r, w}
|
return &ReadWriter{r, w};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,19 +38,19 @@ type Buffer struct {
|
||||||
// Bytes returns the contents of the unread portion of the buffer;
|
// Bytes returns the contents of the unread portion of the buffer;
|
||||||
// len(b.Bytes()) == b.Len().
|
// len(b.Bytes()) == b.Len().
|
||||||
func (b *Buffer) Bytes() []byte {
|
func (b *Buffer) Bytes() []byte {
|
||||||
return b.buf[b.off : len(b.buf)]
|
return b.buf[b.off : len(b.buf)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the contents of the unread portion of the buffer
|
// String returns the contents of the unread portion of the buffer
|
||||||
// as a string.
|
// as a string.
|
||||||
func (b *Buffer) String() string {
|
func (b *Buffer) String() string {
|
||||||
return string(b.buf[b.off : len(b.buf)])
|
return string(b.buf[b.off : len(b.buf)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of bytes of the unread portion of the buffer;
|
// Len returns the number of bytes of the unread portion of the buffer;
|
||||||
// b.Len() == len(b.Bytes()).
|
// b.Len() == len(b.Bytes()).
|
||||||
func (b *Buffer) Len() int {
|
func (b *Buffer) Len() int {
|
||||||
return len(b.buf) - b.off
|
return len(b.buf) - b.off;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncate discards all but the first n unread bytes from the buffer.
|
// Truncate discards all but the first n unread bytes from the buffer.
|
||||||
|
|
@ -80,16 +80,16 @@ func (b *Buffer) Write(p []byte) (n int, err os.Error) {
|
||||||
buf := b.buf;
|
buf := b.buf;
|
||||||
if m+n > cap(b.buf) {
|
if m+n > cap(b.buf) {
|
||||||
// not enough space anywhere
|
// not enough space anywhere
|
||||||
buf = make([]byte, 2*cap(b.buf) + n)
|
buf = make([]byte, 2*cap(b.buf) + n);
|
||||||
}
|
}
|
||||||
copyBytes(buf, 0, b.buf[b.off : b.off + m]);
|
copyBytes(buf, 0, b.buf[b.off : b.off + m]);
|
||||||
b.buf = buf;
|
b.buf = buf;
|
||||||
b.off = 0
|
b.off = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
b.buf = b.buf[0 : b.off + m + n];
|
b.buf = b.buf[0 : b.off + m + n];
|
||||||
copyBytes(b.buf, b.off + m, p);
|
copyBytes(b.buf, b.off + m, p);
|
||||||
return n, nil
|
return n, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteString appends the contents of s to the buffer. The return
|
// WriteString appends the contents of s to the buffer. The return
|
||||||
|
|
@ -103,16 +103,16 @@ func (b *Buffer) WriteString(s string) (n int, err os.Error) {
|
||||||
buf := b.buf;
|
buf := b.buf;
|
||||||
if m+n > cap(b.buf) {
|
if m+n > cap(b.buf) {
|
||||||
// not enough space anywhere
|
// not enough space anywhere
|
||||||
buf = make([]byte, 2*cap(b.buf) + n)
|
buf = make([]byte, 2*cap(b.buf) + n);
|
||||||
}
|
}
|
||||||
copyBytes(buf, 0, b.buf[b.off : b.off + m]);
|
copyBytes(buf, 0, b.buf[b.off : b.off + m]);
|
||||||
b.buf = buf;
|
b.buf = buf;
|
||||||
b.off = 0
|
b.off = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
b.buf = b.buf[0 : b.off + m + n];
|
b.buf = b.buf[0 : b.off + m + n];
|
||||||
copyString(b.buf, b.off + m, s);
|
copyString(b.buf, b.off + m, s);
|
||||||
return n, nil
|
return n, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteByte appends the byte c to the buffer.
|
// WriteByte appends the byte c to the buffer.
|
||||||
|
|
@ -134,19 +134,19 @@ func (b *Buffer) WriteByte(c byte) os.Error {
|
||||||
// otherwise it is nil.
|
// otherwise it is nil.
|
||||||
func (b *Buffer) Read(p []byte) (n int, err os.Error) {
|
func (b *Buffer) Read(p []byte) (n int, err os.Error) {
|
||||||
if b.off >= len(b.buf) {
|
if b.off >= len(b.buf) {
|
||||||
return 0, os.EOF
|
return 0, os.EOF;
|
||||||
}
|
}
|
||||||
m := b.Len();
|
m := b.Len();
|
||||||
n = len(p);
|
n = len(p);
|
||||||
|
|
||||||
if n > m {
|
if n > m {
|
||||||
// more bytes requested than available
|
// more bytes requested than available
|
||||||
n = m
|
n = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
copyBytes(p, 0, b.buf[b.off : b.off + n]);
|
copyBytes(p, 0, b.buf[b.off : b.off + n]);
|
||||||
b.off += n;
|
b.off += n;
|
||||||
return n, err
|
return n, err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadByte reads and returns the next byte from the buffer.
|
// ReadByte reads and returns the next byte from the buffer.
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@ func eq(a, b []string) bool {
|
||||||
func arrayOfString(a [][]byte) []string {
|
func arrayOfString(a [][]byte) []string {
|
||||||
result := make([]string, len(a));
|
result := make([]string, len(a));
|
||||||
for j := 0; j < len(a); j++ {
|
for j := 0; j < len(a); j++ {
|
||||||
result[j] = string(a[j])
|
result[j] = string(a[j]);
|
||||||
}
|
}
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For ease of reading, the test cases use strings that are converted to byte
|
// For ease of reading, the test cases use strings that are converted to byte
|
||||||
|
|
@ -44,6 +44,7 @@ type CompareTest struct {
|
||||||
b string;
|
b string;
|
||||||
cmp int;
|
cmp int;
|
||||||
}
|
}
|
||||||
|
|
||||||
var comparetests = []CompareTest{
|
var comparetests = []CompareTest{
|
||||||
CompareTest{"", "", 0},
|
CompareTest{"", "", 0},
|
||||||
CompareTest{"a", "", 1},
|
CompareTest{"a", "", 1},
|
||||||
|
|
@ -79,11 +80,13 @@ type ExplodeTest struct {
|
||||||
n int;
|
n int;
|
||||||
a []string;
|
a []string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var explodetests = []ExplodeTest{
|
var explodetests = []ExplodeTest{
|
||||||
ExplodeTest{abcd, 0, []string{"a", "b", "c", "d"}},
|
ExplodeTest{abcd, 0, []string{"a", "b", "c", "d"}},
|
||||||
ExplodeTest{faces, 0, []string{"☺", "☻", "☹"}},
|
ExplodeTest{faces, 0, []string{"☺", "☻", "☹"}},
|
||||||
ExplodeTest{abcd, 2, []string{"a", "bcd"}},
|
ExplodeTest{abcd, 2, []string{"a", "bcd"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExplode(t *testing.T) {
|
func TestExplode(t *testing.T) {
|
||||||
for _, tt := range (explodetests) {
|
for _, tt := range (explodetests) {
|
||||||
a := Split(strings.Bytes(tt.s), nil, tt.n);
|
a := Split(strings.Bytes(tt.s), nil, tt.n);
|
||||||
|
|
@ -106,6 +109,7 @@ type SplitTest struct {
|
||||||
n int;
|
n int;
|
||||||
a []string;
|
a []string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var splittests = []SplitTest{
|
var splittests = []SplitTest{
|
||||||
SplitTest{abcd, "a", 0, []string{"", "bcd"}},
|
SplitTest{abcd, "a", 0, []string{"", "bcd"}},
|
||||||
SplitTest{abcd, "z", 0, []string{"abcd"}},
|
SplitTest{abcd, "z", 0, []string{"abcd"}},
|
||||||
|
|
@ -143,6 +147,7 @@ type CopyTest struct {
|
||||||
n int;
|
n int;
|
||||||
res string;
|
res string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var copytests = []CopyTest{
|
var copytests = []CopyTest{
|
||||||
CopyTest{"", "", 0, ""},
|
CopyTest{"", "", 0, ""},
|
||||||
CopyTest{"a", "", 0, "a"},
|
CopyTest{"a", "", 0, "a"},
|
||||||
|
|
@ -227,23 +232,27 @@ func runStringTests(t *testing.T, f func([]byte) []byte, funcName string, testCa
|
||||||
func tenRunes(rune int) string {
|
func tenRunes(rune int) string {
|
||||||
r := make([]int, 10);
|
r := make([]int, 10);
|
||||||
for i := range r {
|
for i := range r {
|
||||||
r[i] = rune
|
r[i] = rune;
|
||||||
}
|
}
|
||||||
return string(r)
|
return string(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
// Run a couple of awful growth/shrinkage tests
|
// Run a couple of awful growth/shrinkage tests
|
||||||
a := tenRunes('a');
|
a := tenRunes('a');
|
||||||
// 1. Grow. This triggers two reallocations in Map.
|
// 1. Grow. This triggers two reallocations in Map.
|
||||||
maxRune := func(rune int) int { return unicode.MaxRune };
|
maxRune := func(rune int) int {
|
||||||
|
return unicode.MaxRune;
|
||||||
|
};
|
||||||
m := Map(maxRune, Bytes(a));
|
m := Map(maxRune, Bytes(a));
|
||||||
expect := tenRunes(unicode.MaxRune);
|
expect := tenRunes(unicode.MaxRune);
|
||||||
if string(m) != expect {
|
if string(m) != expect {
|
||||||
t.Errorf("growing: expected %q got %q", expect, m);
|
t.Errorf("growing: expected %q got %q", expect, m);
|
||||||
}
|
}
|
||||||
// 2. Shrink
|
// 2. Shrink
|
||||||
minRune := func(rune int) int { return 'a' };
|
minRune := func(rune int) int {
|
||||||
|
return 'a';
|
||||||
|
};
|
||||||
m = Map(minRune, Bytes(tenRunes(unicode.MaxRune)));
|
m = Map(minRune, Bytes(tenRunes(unicode.MaxRune)));
|
||||||
expect = a;
|
expect = a;
|
||||||
if string(m) != expect {
|
if string(m) != expect {
|
||||||
|
|
@ -267,6 +276,7 @@ type AddTest struct {
|
||||||
s, t string;
|
s, t string;
|
||||||
cap int;
|
cap int;
|
||||||
}
|
}
|
||||||
|
|
||||||
var addtests = []AddTest{
|
var addtests = []AddTest{
|
||||||
AddTest{"", "", 0},
|
AddTest{"", "", 0},
|
||||||
AddTest{"a", "", 1},
|
AddTest{"a", "", 1},
|
||||||
|
|
@ -278,7 +288,7 @@ func TestAdd(t *testing.T) {
|
||||||
for _, test := range addtests {
|
for _, test := range addtests {
|
||||||
b := make([]byte, len(test.s), test.cap);
|
b := make([]byte, len(test.s), test.cap);
|
||||||
for i := 0; i < len(test.s); i++ {
|
for i := 0; i < len(test.s); i++ {
|
||||||
b[i] = test.s[i]
|
b[i] = test.s[i];
|
||||||
}
|
}
|
||||||
b = Add(b, strings.Bytes(test.t));
|
b = Add(b, strings.Bytes(test.t));
|
||||||
if string(b) != test.s + test.t {
|
if string(b) != test.s + test.t {
|
||||||
|
|
@ -291,7 +301,7 @@ func TestAddByte(t *testing.T) {
|
||||||
const N = 2e5;
|
const N = 2e5;
|
||||||
b := make([]byte, 0);
|
b := make([]byte, 0);
|
||||||
for i := 0; i < N; i++ {
|
for i := 0; i < N; i++ {
|
||||||
b = AddByte(b, byte(i))
|
b = AddByte(b, byte(i));
|
||||||
}
|
}
|
||||||
if len(b) != N {
|
if len(b) != N {
|
||||||
t.Errorf("AddByte: too small; expected %d got %d", N, len(b));
|
t.Errorf("AddByte: too small; expected %d got %d", N, len(b));
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ const (
|
||||||
fastCompression = 3;
|
fastCompression = 3;
|
||||||
BestCompression = 9;
|
BestCompression = 9;
|
||||||
DefaultCompression = -1;
|
DefaultCompression = -1;
|
||||||
|
|
||||||
logMaxOffsetSize = 15; // Standard DEFLATE
|
logMaxOffsetSize = 15; // Standard DEFLATE
|
||||||
wideLogMaxOffsetSize = 22; // Wide DEFLATE
|
wideLogMaxOffsetSize = 22; // Wide DEFLATE
|
||||||
minMatchLength = 3; // The smallest match that the deflater looks for
|
minMatchLength = 3; // The smallest match that the deflater looks for
|
||||||
|
|
@ -57,8 +56,8 @@ type compressionLevel struct {
|
||||||
var levels = []compressionLevel{
|
var levels = []compressionLevel{
|
||||||
compressionLevel{}, // 0
|
compressionLevel{}, // 0
|
||||||
// For levels 1-3 we don't bother trying with lazy matches
|
// For levels 1-3 we don't bother trying with lazy matches
|
||||||
compressionLevel { 3, 0, 8, 4, 4, },
|
compressionLevel{3, 0, 8, 4, 4},
|
||||||
compressionLevel { 3, 0, 16, 8, 5, },
|
compressionLevel{3, 0, 16, 8, 5},
|
||||||
compressionLevel{3, 0, 32, 32, 6},
|
compressionLevel{3, 0, 32, 32, 6},
|
||||||
// Levels 4-9 use increasingly more lazy matching
|
// Levels 4-9 use increasingly more lazy matching
|
||||||
// and increasingly stringent conditions for "good enough".
|
// and increasingly stringent conditions for "good enough".
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,8 @@ var deflateTests = []*deflateTest {
|
||||||
&deflateTest{[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}},
|
&deflateTest{[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}},
|
||||||
&deflateTest{[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}},
|
&deflateTest{[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}},
|
||||||
&deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0,
|
&deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0,
|
||||||
[]byte{ 0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255 } },
|
[]byte{0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255},
|
||||||
|
},
|
||||||
&deflateTest{[]byte{}, 1, []byte{1, 0, 0, 255, 255}},
|
&deflateTest{[]byte{}, 1, []byte{1, 0, 0, 255, 255}},
|
||||||
&deflateTest{[]byte{0x11}, 1, []byte{18, 4, 4, 0, 0, 255, 255}},
|
&deflateTest{[]byte{0x11}, 1, []byte{18, 4, 4, 0, 0, 255, 255}},
|
||||||
&deflateTest{[]byte{0x11, 0x12}, 1, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
|
&deflateTest{[]byte{0x11, 0x12}, 1, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ const (
|
||||||
|
|
||||||
// The number of codegen codes.
|
// The number of codegen codes.
|
||||||
codegenCodeCount = 19;
|
codegenCodeCount = 19;
|
||||||
|
|
||||||
badCode = 255;
|
badCode = 255;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -42,7 +41,7 @@ var lengthExtraBits = []int8 {
|
||||||
var lengthBase = []uint32{
|
var lengthBase = []uint32{
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 10,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 10,
|
||||||
12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
|
12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
|
||||||
64, 80, 96, 112, 128, 160, 192, 224, 255
|
64, 80, 96, 112, 128, 160, 192, 224, 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
// offset code word extra bits.
|
// offset code word extra bits.
|
||||||
|
|
@ -66,13 +65,11 @@ var offsetBase = []uint32 {
|
||||||
/* extended window */
|
/* extended window */
|
||||||
0x008000, 0x00c000, 0x010000, 0x018000, 0x020000,
|
0x008000, 0x00c000, 0x010000, 0x018000, 0x020000,
|
||||||
0x030000, 0x040000, 0x060000, 0x080000, 0x0c0000,
|
0x030000, 0x040000, 0x060000, 0x080000, 0x0c0000,
|
||||||
0x100000, 0x180000, 0x200000, 0x300000
|
0x100000, 0x180000, 0x200000, 0x300000,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The odd order in which the codegen code sizes are written.
|
// The odd order in which the codegen code sizes are written.
|
||||||
var codegenOrder = []uint32 {
|
var codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
|
||||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
|
||||||
}
|
|
||||||
|
|
||||||
type huffmanBitWriter struct {
|
type huffmanBitWriter struct {
|
||||||
w io.Writer;
|
w io.Writer;
|
||||||
|
|
@ -507,4 +504,3 @@ func (w *huffmanBitWriter) writeBlock(tokens []token, eof bool, input []byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ var gzipTests = []gzipTest {
|
||||||
0x74, 0x78, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
|
0x74, 0x78, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
},
|
},
|
||||||
nil
|
nil,
|
||||||
},
|
},
|
||||||
gzipTest{ // has 1 non-empty fixed huffman block
|
gzipTest{ // has 1 non-empty fixed huffman block
|
||||||
"hello.txt",
|
"hello.txt",
|
||||||
|
|
@ -44,7 +44,7 @@ var gzipTests = []gzipTest {
|
||||||
0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
|
0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
|
||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
},
|
},
|
||||||
nil
|
nil,
|
||||||
},
|
},
|
||||||
gzipTest{ // concatenation
|
gzipTest{ // concatenation
|
||||||
"hello.txt",
|
"hello.txt",
|
||||||
|
|
@ -65,7 +65,7 @@ var gzipTests = []gzipTest {
|
||||||
0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
|
0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
|
||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
},
|
},
|
||||||
nil
|
nil,
|
||||||
},
|
},
|
||||||
gzipTest{ // has a fixed huffman block with some length-distance pairs
|
gzipTest{ // has a fixed huffman block with some length-distance pairs
|
||||||
"shesells.txt",
|
"shesells.txt",
|
||||||
|
|
@ -81,7 +81,7 @@ var gzipTests = []gzipTest {
|
||||||
0x94, 0xca, 0x05, 0x00, 0x76, 0xb0, 0x3b, 0xeb,
|
0x94, 0xca, 0x05, 0x00, 0x76, 0xb0, 0x3b, 0xeb,
|
||||||
0x24, 0x00, 0x00, 0x00,
|
0x24, 0x00, 0x00, 0x00,
|
||||||
},
|
},
|
||||||
nil
|
nil,
|
||||||
},
|
},
|
||||||
gzipTest{ // has dynamic huffman blocks
|
gzipTest{ // has dynamic huffman blocks
|
||||||
"gettysburg",
|
"gettysburg",
|
||||||
|
|
@ -219,7 +219,7 @@ var gzipTests = []gzipTest {
|
||||||
0x4a, 0x65, 0x8f, 0x08, 0x42, 0x60, 0xf7, 0x0f,
|
0x4a, 0x65, 0x8f, 0x08, 0x42, 0x60, 0xf7, 0x0f,
|
||||||
0xb9, 0x16, 0x0b, 0x0c, 0x1a, 0x06, 0x00, 0x00,
|
0xb9, 0x16, 0x0b, 0x0c, 0x1a, 0x06, 0x00, 0x00,
|
||||||
},
|
},
|
||||||
nil
|
nil,
|
||||||
},
|
},
|
||||||
gzipTest{ // has 1 non-empty fixed huffman block then garbage
|
gzipTest{ // has 1 non-empty fixed huffman block then garbage
|
||||||
"hello.txt",
|
"hello.txt",
|
||||||
|
|
@ -303,4 +303,3 @@ func TestInflater(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,8 +128,7 @@ func decryptBlock(xk []uint32, src, dst []byte) {
|
||||||
|
|
||||||
// Apply sbox0 to each byte in w.
|
// Apply sbox0 to each byte in w.
|
||||||
func subw(w uint32) uint32 {
|
func subw(w uint32) uint32 {
|
||||||
return
|
return uint32(sbox0[w>>24])<<24 |
|
||||||
uint32(sbox0[w>>24])<<24 |
|
|
||||||
uint32(sbox0[w>>16&0xff])<<16 |
|
uint32(sbox0[w>>16&0xff])<<16 |
|
||||||
uint32(sbox0[w>>8&0xff])<<8 |
|
uint32(sbox0[w>>8&0xff])<<8 |
|
||||||
uint32(sbox0[w&0xff]);
|
uint32(sbox0[w&0xff]);
|
||||||
|
|
@ -177,4 +176,3 @@ func expandKey(key []byte, enc, dec []uint32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,13 +318,18 @@ type ValueDoc struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type sortValueDoc []*ValueDoc
|
type sortValueDoc []*ValueDoc
|
||||||
func (p sortValueDoc) Len() int { return len(p); }
|
|
||||||
func (p sortValueDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
|
func (p sortValueDoc) Len() int {
|
||||||
|
return len(p);
|
||||||
|
}
|
||||||
|
func (p sortValueDoc) Swap(i, j int) {
|
||||||
|
p[i], p[j] = p[j], p[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func declName(d *ast.GenDecl) string {
|
func declName(d *ast.GenDecl) string {
|
||||||
if len(d.Specs) != 1 {
|
if len(d.Specs) != 1 {
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
switch v := d.Specs[0].(type) {
|
switch v := d.Specs[0].(type) {
|
||||||
|
|
@ -377,9 +382,16 @@ type FuncDoc struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type sortFuncDoc []*FuncDoc
|
type sortFuncDoc []*FuncDoc
|
||||||
func (p sortFuncDoc) Len() int { return len(p); }
|
|
||||||
func (p sortFuncDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
|
func (p sortFuncDoc) Len() int {
|
||||||
func (p sortFuncDoc) Less(i, j int) bool { return p[i].Name < p[j].Name; }
|
return len(p);
|
||||||
|
}
|
||||||
|
func (p sortFuncDoc) Swap(i, j int) {
|
||||||
|
p[i], p[j] = p[j], p[i];
|
||||||
|
}
|
||||||
|
func (p sortFuncDoc) Less(i, j int) bool {
|
||||||
|
return p[i].Name < p[j].Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func makeFuncDocs(m map[string]*ast.FuncDecl) []*FuncDoc {
|
func makeFuncDocs(m map[string]*ast.FuncDecl) []*FuncDoc {
|
||||||
|
|
@ -418,8 +430,13 @@ type TypeDoc struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type sortTypeDoc []*TypeDoc
|
type sortTypeDoc []*TypeDoc
|
||||||
func (p sortTypeDoc) Len() int { return len(p); }
|
|
||||||
func (p sortTypeDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
|
func (p sortTypeDoc) Len() int {
|
||||||
|
return len(p);
|
||||||
|
}
|
||||||
|
func (p sortTypeDoc) Swap(i, j int) {
|
||||||
|
p[i], p[j] = p[j], p[i];
|
||||||
|
}
|
||||||
func (p sortTypeDoc) Less(i, j int) bool {
|
func (p sortTypeDoc) Less(i, j int) bool {
|
||||||
// sort by name
|
// sort by name
|
||||||
// pull blocks (name = "") up to top
|
// pull blocks (name = "") up to top
|
||||||
|
|
@ -544,11 +561,11 @@ func isRegexp(s string) bool {
|
||||||
for _, c := range s {
|
for _, c := range s {
|
||||||
for _, m := range metachars {
|
for _, m := range metachars {
|
||||||
if c == m {
|
if c == m {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -643,4 +660,3 @@ func (p *PackageDoc) Filter(names []string) {
|
||||||
p.Funcs = filterFuncDocs(p.Funcs, names);
|
p.Funcs = filterFuncDocs(p.Funcs, names);
|
||||||
p.Doc = ""; // don't show top-level package doc
|
p.Doc = ""; // don't show top-level package doc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,9 @@ const (
|
||||||
|
|
||||||
// HTTP request parsing errors.
|
// HTTP request parsing errors.
|
||||||
type ProtocolError struct {
|
type ProtocolError struct {
|
||||||
os.ErrorString
|
os.ErrorString;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrLineTooLong = &ProtocolError{"header line too long"};
|
ErrLineTooLong = &ProtocolError{"header line too long"};
|
||||||
ErrHeaderTooLong = &ProtocolError{"header too long"};
|
ErrHeaderTooLong = &ProtocolError{"header too long"};
|
||||||
|
|
@ -104,14 +105,13 @@ type Request struct {
|
||||||
|
|
||||||
// The parsed form. Only available after ParseForm is called.
|
// The parsed form. Only available after ParseForm is called.
|
||||||
Form map[string][]string;
|
Form map[string][]string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtoAtLeast returns whether the HTTP protocol used
|
// ProtoAtLeast returns whether the HTTP protocol used
|
||||||
// in the request is at least major.minor.
|
// in the request is at least major.minor.
|
||||||
func (r *Request) ProtoAtLeast(major, minor int) bool {
|
func (r *Request) ProtoAtLeast(major, minor int) bool {
|
||||||
return r.ProtoMajor > major ||
|
return r.ProtoMajor > major ||
|
||||||
r.ProtoMajor == major && r.ProtoMinor >= minor
|
r.ProtoMajor == major && r.ProtoMinor >= minor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return value if nonempty, def otherwise.
|
// Return value if nonempty, def otherwise.
|
||||||
|
|
@ -123,7 +123,7 @@ func valueOrDefault(value, def string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(rsc): Change default UserAgent before open-source release.
|
// TODO(rsc): Change default UserAgent before open-source release.
|
||||||
const defaultUserAgent = "http.Client";
|
const defaultUserAgent = "http.Client"
|
||||||
|
|
||||||
// Write an HTTP/1.1 request -- header and body -- in wire format.
|
// Write an HTTP/1.1 request -- header and body -- in wire format.
|
||||||
// This method consults the following fields of req:
|
// This method consults the following fields of req:
|
||||||
|
|
@ -183,7 +183,7 @@ func (req *Request) write(w io.Writer) os.Error {
|
||||||
switch {
|
switch {
|
||||||
case er != nil:
|
case er != nil:
|
||||||
if er == os.EOF {
|
if er == os.EOF {
|
||||||
break Loop
|
break Loop;
|
||||||
}
|
}
|
||||||
return er;
|
return er;
|
||||||
case ew != nil:
|
case ew != nil:
|
||||||
|
|
@ -210,29 +210,29 @@ func readLineBytes(b *bufio.Reader) (p []byte, err os.Error) {
|
||||||
if err == os.EOF {
|
if err == os.EOF {
|
||||||
err = io.ErrUnexpectedEOF;
|
err = io.ErrUnexpectedEOF;
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err;
|
||||||
}
|
}
|
||||||
if len(p) >= maxLineLength {
|
if len(p) >= maxLineLength {
|
||||||
return nil, ErrLineTooLong
|
return nil, ErrLineTooLong;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chop off trailing white space.
|
// Chop off trailing white space.
|
||||||
var i int;
|
var i int;
|
||||||
for i = len(p); i > 0; i-- {
|
for i = len(p); i > 0; i-- {
|
||||||
if c := p[i-1]; c != ' ' && c != '\r' && c != '\t' && c != '\n' {
|
if c := p[i-1]; c != ' ' && c != '\r' && c != '\t' && c != '\n' {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p[0:i], nil
|
return p[0:i], nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// readLineBytes, but convert the bytes into a string.
|
// readLineBytes, but convert the bytes into a string.
|
||||||
func readLine(b *bufio.Reader) (s string, err os.Error) {
|
func readLine(b *bufio.Reader) (s string, err os.Error) {
|
||||||
p, e := readLineBytes(b);
|
p, e := readLineBytes(b);
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return "", e
|
return "", e;
|
||||||
}
|
}
|
||||||
return string(p), nil
|
return string(p), nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
var colon = []byte{':'}
|
var colon = []byte{':'}
|
||||||
|
|
@ -244,10 +244,10 @@ var colon = []byte{':'}
|
||||||
func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) {
|
func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) {
|
||||||
line, e := readLineBytes(b);
|
line, e := readLineBytes(b);
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return "", "", e
|
return "", "", e;
|
||||||
}
|
}
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
return "", "", nil
|
return "", "", nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan first line for colon.
|
// Scan first line for colon.
|
||||||
|
|
@ -265,7 +265,7 @@ func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) {
|
||||||
// Skip initial space before value.
|
// Skip initial space before value.
|
||||||
for i++; i < len(line); i++ {
|
for i++; i < len(line); i++ {
|
||||||
if line[i] != ' ' {
|
if line[i] != ' ' {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value = string(line[i:len(line)]);
|
value = string(line[i:len(line)]);
|
||||||
|
|
@ -286,14 +286,14 @@ func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) {
|
||||||
if e == os.EOF {
|
if e == os.EOF {
|
||||||
e = io.ErrUnexpectedEOF;
|
e = io.ErrUnexpectedEOF;
|
||||||
}
|
}
|
||||||
return "", "", e
|
return "", "", e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.UnreadByte();
|
b.UnreadByte();
|
||||||
|
|
||||||
// Read the rest of the line and add to value.
|
// Read the rest of the line and add to value.
|
||||||
if line, e = readLineBytes(b); e != nil {
|
if line, e = readLineBytes(b); e != nil {
|
||||||
return "", "", e
|
return "", "", e;
|
||||||
}
|
}
|
||||||
value += " "+string(line);
|
value += " "+string(line);
|
||||||
|
|
||||||
|
|
@ -313,33 +313,33 @@ Malformed:
|
||||||
func atoi(s string, i int) (n, i1 int, ok bool) {
|
func atoi(s string, i int) (n, i1 int, ok bool) {
|
||||||
const Big = 1000000;
|
const Big = 1000000;
|
||||||
if i >= len(s) || s[i] < '0' || s[i] > '9' {
|
if i >= len(s) || s[i] < '0' || s[i] > '9' {
|
||||||
return 0, 0, false
|
return 0, 0, false;
|
||||||
}
|
}
|
||||||
n = 0;
|
n = 0;
|
||||||
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
|
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
|
||||||
n = n*10 + int(s[i]-'0');
|
n = n*10 + int(s[i]-'0');
|
||||||
if n > Big {
|
if n > Big {
|
||||||
return 0, 0, false
|
return 0, 0, false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n, i, true
|
return n, i, true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse HTTP version: "HTTP/1.2" -> (1, 2, true).
|
// Parse HTTP version: "HTTP/1.2" -> (1, 2, true).
|
||||||
func parseHTTPVersion(vers string) (int, int, bool) {
|
func parseHTTPVersion(vers string) (int, int, bool) {
|
||||||
if vers[0:5] != "HTTP/" {
|
if vers[0:5] != "HTTP/" {
|
||||||
return 0, 0, false
|
return 0, 0, false;
|
||||||
}
|
}
|
||||||
major, i, ok := atoi(vers, 5);
|
major, i, ok := atoi(vers, 5);
|
||||||
if !ok || i >= len(vers) || vers[i] != '.' {
|
if !ok || i >= len(vers) || vers[i] != '.' {
|
||||||
return 0, 0, false
|
return 0, 0, false;
|
||||||
}
|
}
|
||||||
var minor int;
|
var minor int;
|
||||||
minor, i, ok = atoi(vers, i+1);
|
minor, i, ok = atoi(vers, i+1);
|
||||||
if !ok || i != len(vers) {
|
if !ok || i != len(vers) {
|
||||||
return 0, 0, false
|
return 0, 0, false;
|
||||||
}
|
}
|
||||||
return major, minor, true
|
return major, minor, true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmap = make(map[string]string)
|
var cmap = make(map[string]string)
|
||||||
|
|
@ -384,7 +384,7 @@ type chunkedReader struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChunkedReader(r *bufio.Reader) *chunkedReader {
|
func newChunkedReader(r *bufio.Reader) *chunkedReader {
|
||||||
return &chunkedReader{ r: r }
|
return &chunkedReader{r: r};
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *chunkedReader) beginChunk() {
|
func (cr *chunkedReader) beginChunk() {
|
||||||
|
|
@ -392,21 +392,21 @@ func (cr *chunkedReader) beginChunk() {
|
||||||
var line string;
|
var line string;
|
||||||
line, cr.err = readLine(cr.r);
|
line, cr.err = readLine(cr.r);
|
||||||
if cr.err != nil {
|
if cr.err != nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
cr.n, cr.err = strconv.Btoui64(line, 16);
|
cr.n, cr.err = strconv.Btoui64(line, 16);
|
||||||
if cr.err != nil {
|
if cr.err != nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if cr.n == 0 {
|
if cr.n == 0 {
|
||||||
// trailer CRLF
|
// trailer CRLF
|
||||||
for {
|
for {
|
||||||
line, cr.err = readLine(cr.r);
|
line, cr.err = readLine(cr.r);
|
||||||
if cr.err != nil {
|
if cr.err != nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if line == "" {
|
if line == "" {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cr.err = os.EOF;
|
cr.err = os.EOF;
|
||||||
|
|
@ -415,12 +415,12 @@ func (cr *chunkedReader) beginChunk() {
|
||||||
|
|
||||||
func (cr *chunkedReader) Read(b []uint8) (n int, err os.Error) {
|
func (cr *chunkedReader) Read(b []uint8) (n int, err os.Error) {
|
||||||
if cr.err != nil {
|
if cr.err != nil {
|
||||||
return 0, cr.err
|
return 0, cr.err;
|
||||||
}
|
}
|
||||||
if cr.n == 0 {
|
if cr.n == 0 {
|
||||||
cr.beginChunk();
|
cr.beginChunk();
|
||||||
if cr.err != nil {
|
if cr.err != nil {
|
||||||
return 0, cr.err
|
return 0, cr.err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if uint64(len(b)) > cr.n {
|
if uint64(len(b)) > cr.n {
|
||||||
|
|
@ -437,7 +437,7 @@ func (cr *chunkedReader) Read(b []uint8) (n int, err os.Error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n, cr.err
|
return n, cr.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadRequest reads and parses a request from b.
|
// ReadRequest reads and parses a request from b.
|
||||||
|
|
@ -447,7 +447,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
||||||
// First line: GET /index.html HTTP/1.0
|
// First line: GET /index.html HTTP/1.0
|
||||||
var s string;
|
var s string;
|
||||||
if s, err = readLine(b); err != nil {
|
if s, err = readLine(b); err != nil {
|
||||||
return nil, err
|
return nil, err;
|
||||||
}
|
}
|
||||||
|
|
||||||
var f []string;
|
var f []string;
|
||||||
|
|
@ -461,7 +461,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Url, err = ParseURL(req.RawUrl); err != nil {
|
if req.Url, err = ParseURL(req.RawUrl); err != nil {
|
||||||
return nil, err
|
return nil, err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subsequent lines: Key: value.
|
// Subsequent lines: Key: value.
|
||||||
|
|
@ -470,13 +470,13 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
||||||
for {
|
for {
|
||||||
var key, value string;
|
var key, value string;
|
||||||
if key, value, err = readKeyValue(b); err != nil {
|
if key, value, err = readKeyValue(b); err != nil {
|
||||||
return nil, err
|
return nil, err;
|
||||||
}
|
}
|
||||||
if key == "" {
|
if key == "" {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
if nheader++; nheader >= maxHeaderLines {
|
if nheader++; nheader >= maxHeaderLines {
|
||||||
return nil, ErrHeaderTooLong
|
return nil, ErrHeaderTooLong;
|
||||||
}
|
}
|
||||||
|
|
||||||
key = CanonicalHeaderKey(key);
|
key = CanonicalHeaderKey(key);
|
||||||
|
|
@ -486,9 +486,9 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
||||||
// to concatenating the values separated by commas.
|
// to concatenating the values separated by commas.
|
||||||
oldvalue, present := req.Header[key];
|
oldvalue, present := req.Header[key];
|
||||||
if present {
|
if present {
|
||||||
req.Header[key] = oldvalue+","+value
|
req.Header[key] = oldvalue+","+value;
|
||||||
} else {
|
} else {
|
||||||
req.Header[key] = value
|
req.Header[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,7 +500,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
||||||
// Host: doesntmatter
|
// Host: doesntmatter
|
||||||
// the same. In the second case, any Host line is ignored.
|
// the same. In the second case, any Host line is ignored.
|
||||||
if v, present := req.Header["Host"]; present && req.Url.Host == "" {
|
if v, present := req.Header["Host"]; present && req.Url.Host == "" {
|
||||||
req.Host = v
|
req.Host = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RFC2616: Should treat
|
// RFC2616: Should treat
|
||||||
|
|
@ -509,27 +509,27 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
||||||
// Cache-Control: no-cache
|
// Cache-Control: no-cache
|
||||||
if v, present := req.Header["Pragma"]; present && v == "no-cache" {
|
if v, present := req.Header["Pragma"]; present && v == "no-cache" {
|
||||||
if _, presentcc := req.Header["Cache-Control"]; !presentcc {
|
if _, presentcc := req.Header["Cache-Control"]; !presentcc {
|
||||||
req.Header["Cache-Control"] = "no-cache"
|
req.Header["Cache-Control"] = "no-cache";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine whether to hang up after sending the reply.
|
// Determine whether to hang up after sending the reply.
|
||||||
if req.ProtoMajor < 1 || (req.ProtoMajor == 1 && req.ProtoMinor < 1) {
|
if req.ProtoMajor < 1 || (req.ProtoMajor == 1 && req.ProtoMinor < 1) {
|
||||||
req.Close = true
|
req.Close = true;
|
||||||
} else if v, present := req.Header["Connection"]; present {
|
} else if v, present := req.Header["Connection"]; present {
|
||||||
// TODO: Should split on commas, toss surrounding white space,
|
// TODO: Should split on commas, toss surrounding white space,
|
||||||
// and check each field.
|
// and check each field.
|
||||||
if v == "close" {
|
if v == "close" {
|
||||||
req.Close = true
|
req.Close = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull out useful fields as a convenience to clients.
|
// Pull out useful fields as a convenience to clients.
|
||||||
if v, present := req.Header["Referer"]; present {
|
if v, present := req.Header["Referer"]; present {
|
||||||
req.Referer = v
|
req.Referer = v;
|
||||||
}
|
}
|
||||||
if v, present := req.Header["User-Agent"]; present {
|
if v, present := req.Header["User-Agent"]; present {
|
||||||
req.UserAgent = v
|
req.UserAgent = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Parse specific header values:
|
// TODO: Parse specific header values:
|
||||||
|
|
@ -571,12 +571,12 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
||||||
raw := make([]byte, length);
|
raw := make([]byte, length);
|
||||||
n, err := b.Read(raw);
|
n, err := b.Read(raw);
|
||||||
if err != nil || uint64(n) < length {
|
if err != nil || uint64(n) < length {
|
||||||
return nil, ErrShortBody
|
return nil, ErrShortBody;
|
||||||
}
|
}
|
||||||
req.Body = bytes.NewBuffer(raw);
|
req.Body = bytes.NewBuffer(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
return req, nil
|
return req, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseForm(query string) (m map[string][]string, err os.Error) {
|
func parseForm(query string) (m map[string][]string, err os.Error) {
|
||||||
|
|
@ -607,14 +607,14 @@ func parseForm(query string) (m map[string] []string, err os.Error) {
|
||||||
m[k] = vec.Data();
|
m[k] = vec.Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseForm parses the request body as a form for POST requests, or the raw query for GET requests.
|
// ParseForm parses the request body as a form for POST requests, or the raw query for GET requests.
|
||||||
// It is idempotent.
|
// It is idempotent.
|
||||||
func (r *Request) ParseForm() (err os.Error) {
|
func (r *Request) ParseForm() (err os.Error) {
|
||||||
if r.Form != nil {
|
if r.Form != nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var query string;
|
var query string;
|
||||||
|
|
@ -624,23 +624,23 @@ func (r *Request) ParseForm() (err os.Error) {
|
||||||
query = r.Url.RawQuery;
|
query = r.Url.RawQuery;
|
||||||
case "POST":
|
case "POST":
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
return os.ErrorString("missing form body")
|
return os.ErrorString("missing form body");
|
||||||
}
|
}
|
||||||
ct, _ := r.Header["Content-Type"];
|
ct, _ := r.Header["Content-Type"];
|
||||||
switch strings.Split(ct, ";", 2)[0] {
|
switch strings.Split(ct, ";", 2)[0] {
|
||||||
case "text/plain", "application/x-www-form-urlencoded", "":
|
case "text/plain", "application/x-www-form-urlencoded", "":
|
||||||
var b []byte;
|
var b []byte;
|
||||||
if b, err = io.ReadAll(r.Body); err != nil {
|
if b, err = io.ReadAll(r.Body); err != nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
query = string(b);
|
query = string(b);
|
||||||
// TODO(dsymonds): Handle multipart/form-data
|
// TODO(dsymonds): Handle multipart/form-data
|
||||||
default:
|
default:
|
||||||
return &badStringError{"unknown Content-Type", ct}
|
return &badStringError{"unknown Content-Type", ct};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.Form, err = parseForm(query);
|
r.Form, err = parseForm(query);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormValue returns the first value for the named component of the query.
|
// FormValue returns the first value for the named component of the query.
|
||||||
|
|
@ -650,7 +650,7 @@ func (r *Request) FormValue(key string) string {
|
||||||
r.ParseForm();
|
r.ParseForm();
|
||||||
}
|
}
|
||||||
if vs, ok := r.Form[key]; ok && len(vs) > 0 {
|
if vs, ok := r.Form[key]; ok && len(vs) > 0 {
|
||||||
return vs[0]
|
return vs[0];
|
||||||
}
|
}
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import "strings"
|
||||||
// http://plan9.bell-labs.com/sys/doc/lexnames.html
|
// http://plan9.bell-labs.com/sys/doc/lexnames.html
|
||||||
func Clean(path string) string {
|
func Clean(path string) string {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
return "."
|
return ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
rooted := path[0] == '/';
|
rooted := path[0] == '/';
|
||||||
|
|
@ -108,7 +108,7 @@ func Split(path string) (dir, file string) {
|
||||||
return path[0 : i+1], path[i+1 : len(path)];
|
return path[0 : i+1], path[i+1 : len(path)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", path
|
return "", path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join joins dir and file into a single path, adding a separating
|
// Join joins dir and file into a single path, adding a separating
|
||||||
|
|
@ -130,6 +130,5 @@ func Ext(path string) string {
|
||||||
return path[i:len(path)];
|
return path[i:len(path)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@
|
||||||
package path
|
package path
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing";
|
||||||
)
|
)
|
||||||
|
|
||||||
type CleanTest struct {
|
type CleanTest struct {
|
||||||
path, clean string
|
path, clean string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cleantests = []CleanTest{
|
var cleantests = []CleanTest{
|
||||||
|
|
@ -71,7 +71,7 @@ func TestClean(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SplitTest struct {
|
type SplitTest struct {
|
||||||
path, dir, file string
|
path, dir, file string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var splittests = []SplitTest{
|
var splittests = []SplitTest{
|
||||||
|
|
@ -91,7 +91,7 @@ func TestSplit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type JoinTest struct {
|
type JoinTest struct {
|
||||||
dir, file, path string
|
dir, file, path string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jointests = []JoinTest{
|
var jointests = []JoinTest{
|
||||||
|
|
@ -113,7 +113,7 @@ func TestJoin(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtTest struct {
|
type ExtTest struct {
|
||||||
path, ext string
|
path, ext string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var exttests = []ExtTest{
|
var exttests = []ExtTest{
|
||||||
|
|
@ -131,4 +131,3 @@ func TestExt(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ type floatInfo struct {
|
||||||
expbits uint;
|
expbits uint;
|
||||||
bias int;
|
bias int;
|
||||||
}
|
}
|
||||||
|
|
||||||
var float32info = floatInfo{23, 8, -127}
|
var float32info = floatInfo{23, 8, -127}
|
||||||
var float64info = floatInfo{52, 11, -1023}
|
var float64info = floatInfo{52, 11, -1023}
|
||||||
|
|
||||||
|
|
@ -151,7 +152,7 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||||
// if precision was the shortest possible, use precision 6 for this decision.
|
// if precision was the shortest possible, use precision 6 for this decision.
|
||||||
eprec := prec;
|
eprec := prec;
|
||||||
if shortest {
|
if shortest {
|
||||||
eprec = 6
|
eprec = 6;
|
||||||
}
|
}
|
||||||
exp := d.dp - 1;
|
exp := d.dp - 1;
|
||||||
if exp < -4 || exp >= eprec {
|
if exp < -4 || exp >= eprec {
|
||||||
|
|
@ -379,7 +380,7 @@ func fmtB(neg bool, mant uint64, exp int, flt *floatInfo) string {
|
||||||
n++;
|
n++;
|
||||||
w--;
|
w--;
|
||||||
buf[w] = byte(exp%10 + '0');
|
buf[w] = byte(exp%10 + '0');
|
||||||
exp /= 10
|
exp /= 10;
|
||||||
}
|
}
|
||||||
w--;
|
w--;
|
||||||
buf[w] = esign;
|
buf[w] = esign;
|
||||||
|
|
@ -405,4 +406,3 @@ func max(a, b int) int {
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Test struct {
|
type Test struct {
|
||||||
in, out, err string
|
in, out, err string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type T struct {
|
type T struct {
|
||||||
|
|
@ -46,7 +46,7 @@ func uppercase(v interface{}) string {
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
c := s[i];
|
c := s[i];
|
||||||
if 'a' <= c && c <= 'z' {
|
if 'a' <= c && c <= 'z' {
|
||||||
c = c + 'A' - 'a'
|
c = c+'A'-'a';
|
||||||
}
|
}
|
||||||
t += string(c);
|
t += string(c);
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ func plus1(v interface{}) string {
|
||||||
func writer(f func(interface{}) string) (func(io.Writer, interface{}, string)) {
|
func writer(f func(interface{}) string) (func(io.Writer, interface{}, string)) {
|
||||||
return func(w io.Writer, v interface{}, format string) {
|
return func(w io.Writer, v interface{}, format string) {
|
||||||
io.WriteString(w, f(v));
|
io.WriteString(w, f(v));
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ var tests = []*Test {
|
||||||
&Test{
|
&Test{
|
||||||
in: "{header}={integer}\n",
|
in: "{header}={integer}\n",
|
||||||
|
|
||||||
out: "Header=77\n"
|
out: "Header=77\n",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Section
|
// Section
|
||||||
|
|
@ -93,21 +93,21 @@ var tests = []*Test {
|
||||||
"some text for the section\n"
|
"some text for the section\n"
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "some text for the section\n"
|
out: "some text for the section\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section data }\n"
|
in: "{.section data }\n"
|
||||||
"{header}={integer}\n"
|
"{header}={integer}\n"
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "Header=77\n"
|
out: "Header=77\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section pdata }\n"
|
in: "{.section pdata }\n"
|
||||||
"{header}={integer}\n"
|
"{header}={integer}\n"
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "Header=77\n"
|
out: "Header=77\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section pdata }\n"
|
in: "{.section pdata }\n"
|
||||||
|
|
@ -116,7 +116,7 @@ var tests = []*Test {
|
||||||
"data not present\n"
|
"data not present\n"
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "data present\n"
|
out: "data present\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section empty }\n"
|
in: "{.section empty }\n"
|
||||||
|
|
@ -125,7 +125,7 @@ var tests = []*Test {
|
||||||
"data not present\n"
|
"data not present\n"
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "data not present\n"
|
out: "data not present\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section null }\n"
|
in: "{.section null }\n"
|
||||||
|
|
@ -134,7 +134,7 @@ var tests = []*Test {
|
||||||
"data not present\n"
|
"data not present\n"
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "data not present\n"
|
out: "data not present\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section pdata }\n"
|
in: "{.section pdata }\n"
|
||||||
|
|
@ -145,12 +145,12 @@ var tests = []*Test {
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "Header=77\n"
|
out: "Header=77\n"
|
||||||
"Header=77\n"
|
"Header=77\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section data}{.end} {header}\n",
|
in: "{.section data}{.end} {header}\n",
|
||||||
|
|
||||||
out: " Header\n"
|
out: " Header\n",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Repeated
|
// Repeated
|
||||||
|
|
@ -162,7 +162,7 @@ var tests = []*Test {
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "ItemNumber1=ValueNumber1\n"
|
out: "ItemNumber1=ValueNumber1\n"
|
||||||
"ItemNumber2=ValueNumber2\n"
|
"ItemNumber2=ValueNumber2\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section pdata }\n"
|
in: "{.section pdata }\n"
|
||||||
|
|
@ -174,7 +174,7 @@ var tests = []*Test {
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "ItemNumber1=ValueNumber1\n"
|
out: "ItemNumber1=ValueNumber1\n"
|
||||||
"ItemNumber2=ValueNumber2\n"
|
"ItemNumber2=ValueNumber2\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section @ }\n"
|
in: "{.section @ }\n"
|
||||||
|
|
@ -185,7 +185,7 @@ var tests = []*Test {
|
||||||
"{.end}\n"
|
"{.end}\n"
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "this should appear: empty field\n"
|
out: "this should appear: empty field\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.repeated section pdata }\n"
|
in: "{.repeated section pdata }\n"
|
||||||
|
|
@ -196,7 +196,7 @@ var tests = []*Test {
|
||||||
|
|
||||||
out: "ItemNumber1\n"
|
out: "ItemNumber1\n"
|
||||||
"is\nover\nmultiple\nlines\n"
|
"is\nover\nmultiple\nlines\n"
|
||||||
"ItemNumber2\n"
|
"ItemNumber2\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section pdata }\n"
|
in: "{.section pdata }\n"
|
||||||
|
|
@ -210,7 +210,7 @@ var tests = []*Test {
|
||||||
|
|
||||||
out: "ItemNumber1=ValueNumber1\n"
|
out: "ItemNumber1=ValueNumber1\n"
|
||||||
"DIVIDER\n"
|
"DIVIDER\n"
|
||||||
"ItemNumber2=ValueNumber2\n"
|
"ItemNumber2=ValueNumber2\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.repeated section vec }\n"
|
in: "{.repeated section vec }\n"
|
||||||
|
|
@ -218,7 +218,7 @@ var tests = []*Test {
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "elt1\n"
|
out: "elt1\n"
|
||||||
"elt2\n"
|
"elt2\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.repeated section integer}{.end}",
|
in: "{.repeated section integer}{.end}",
|
||||||
|
|
@ -232,14 +232,14 @@ var tests = []*Test {
|
||||||
"{innerT.item}={innerT.value}\n"
|
"{innerT.item}={innerT.value}\n"
|
||||||
"{.end}",
|
"{.end}",
|
||||||
|
|
||||||
out: "ItemNumber1=ValueNumber1\n"
|
out: "ItemNumber1=ValueNumber1\n",
|
||||||
},
|
},
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section @ }\n"
|
in: "{.section @ }\n"
|
||||||
"{innerT.item}={.section innerT}{.section value}{@}{.end}{.end}\n"
|
"{innerT.item}={.section innerT}{.section value}{@}{.end}{.end}\n"
|
||||||
"{.end}",
|
"{.end}",
|
||||||
|
|
||||||
out: "ItemNumber1=ValueNumber1\n"
|
out: "ItemNumber1=ValueNumber1\n",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -251,7 +251,7 @@ var tests = []*Test {
|
||||||
"{.end}\n",
|
"{.end}\n",
|
||||||
|
|
||||||
out: "HEADER=78\n"
|
out: "HEADER=78\n"
|
||||||
"Header=77\n"
|
"Header=77\n",
|
||||||
},
|
},
|
||||||
|
|
||||||
&Test{
|
&Test{
|
||||||
|
|
@ -259,21 +259,21 @@ var tests = []*Test {
|
||||||
"{raw|html}\n",
|
"{raw|html}\n",
|
||||||
|
|
||||||
out: "&<>!@ #$%^\n"
|
out: "&<>!@ #$%^\n"
|
||||||
"&<>!@ #$%^\n"
|
"&<>!@ #$%^\n",
|
||||||
},
|
},
|
||||||
|
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section emptystring}emptystring{.end}\n"
|
in: "{.section emptystring}emptystring{.end}\n"
|
||||||
"{.section header}header{.end}\n",
|
"{.section header}header{.end}\n",
|
||||||
|
|
||||||
out: "\nheader\n"
|
out: "\nheader\n",
|
||||||
},
|
},
|
||||||
|
|
||||||
&Test{
|
&Test{
|
||||||
in: "{.section true}1{.or}2{.end}\n"
|
in: "{.section true}1{.or}2{.end}\n"
|
||||||
"{.section false}3{.or}4{.end}\n",
|
"{.section false}3{.or}4{.end}\n",
|
||||||
|
|
||||||
out: "1\n4\n"
|
out: "1\n4\n",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,28 +321,28 @@ func TestAll(t *testing.T) {
|
||||||
func TestStringDriverType(t *testing.T) {
|
func TestStringDriverType(t *testing.T) {
|
||||||
tmpl, err := Parse("template: {@}", nil);
|
tmpl, err := Parse("template: {@}", nil);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("unexpected parse error:", err)
|
t.Error("unexpected parse error:", err);
|
||||||
}
|
}
|
||||||
var b bytes.Buffer;
|
var b bytes.Buffer;
|
||||||
err = tmpl.Execute("hello", &b);
|
err = tmpl.Execute("hello", &b);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("unexpected execute error:", err)
|
t.Error("unexpected execute error:", err);
|
||||||
}
|
}
|
||||||
s := b.String();
|
s := b.String();
|
||||||
if s != "template: hello" {
|
if s != "template: hello" {
|
||||||
t.Errorf("failed passing string as data: expected %q got %q", "template: hello", s)
|
t.Errorf("failed passing string as data: expected %q got %q", "template: hello", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTwice(t *testing.T) {
|
func TestTwice(t *testing.T) {
|
||||||
tmpl, err := Parse("template: {@}", nil);
|
tmpl, err := Parse("template: {@}", nil);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("unexpected parse error:", err)
|
t.Error("unexpected parse error:", err);
|
||||||
}
|
}
|
||||||
var b bytes.Buffer;
|
var b bytes.Buffer;
|
||||||
err = tmpl.Execute("hello", &b);
|
err = tmpl.Execute("hello", &b);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("unexpected parse error:", err)
|
t.Error("unexpected parse error:", err);
|
||||||
}
|
}
|
||||||
s := b.String();
|
s := b.String();
|
||||||
text := "template: hello";
|
text := "template: hello";
|
||||||
|
|
@ -351,7 +351,7 @@ func TestTwice(t *testing.T) {
|
||||||
}
|
}
|
||||||
err = tmpl.Execute("hello", &b);
|
err = tmpl.Execute("hello", &b);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("unexpected parse error:", err)
|
t.Error("unexpected parse error:", err);
|
||||||
}
|
}
|
||||||
s = b.String();
|
s = b.String();
|
||||||
text += text;
|
text += text;
|
||||||
|
|
@ -377,9 +377,9 @@ func TestCustomDelims(t *testing.T) {
|
||||||
err := tmpl.Parse(text);
|
err := tmpl.Parse(text);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if i == 0 || j == 0 { // expected
|
if i == 0 || j == 0 { // expected
|
||||||
continue
|
continue;
|
||||||
}
|
}
|
||||||
t.Error("unexpected parse error:", err)
|
t.Error("unexpected parse error:", err);
|
||||||
} else if i == 0 || j == 0 {
|
} else if i == 0 || j == 0 {
|
||||||
t.Errorf("expected parse error for empty delimiter: %d %d %q %q", i, j, ldelim, rdelim);
|
t.Errorf("expected parse error for empty delimiter: %d %d %q %q", i, j, ldelim, rdelim);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -388,7 +388,7 @@ func TestCustomDelims(t *testing.T) {
|
||||||
err = tmpl.Execute("hello", &b);
|
err = tmpl.Execute("hello", &b);
|
||||||
s := b.String();
|
s := b.String();
|
||||||
if s != "template: hello" + ldelim + rdelim {
|
if s != "template: hello" + ldelim + rdelim {
|
||||||
t.Errorf("failed delim check(%q %q) %q got %q", ldelim, rdelim, text, s)
|
t.Errorf("failed delim check(%q %q) %q got %q", ldelim, rdelim, text, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -408,7 +408,7 @@ func TestVarIndirection(t *testing.T) {
|
||||||
}
|
}
|
||||||
err = tmpl.Execute(s, &buf);
|
err = tmpl.Execute(s, &buf);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected execute error:", err)
|
t.Fatal("unexpected execute error:", err);
|
||||||
}
|
}
|
||||||
expect := fmt.Sprintf("%v", &t1); // output should be hex address of t1
|
expect := fmt.Sprintf("%v", &t1); // output should be hex address of t1
|
||||||
if buf.String() != expect {
|
if buf.String() != expect {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import (
|
||||||
"utf8";
|
"utf8";
|
||||||
)
|
)
|
||||||
|
|
||||||
var debug = false;
|
var debug = false
|
||||||
|
|
||||||
// Error codes returned by failures to parse an expression.
|
// Error codes returned by failures to parse an expression.
|
||||||
var (
|
var (
|
||||||
|
|
@ -61,10 +61,18 @@ type common struct {
|
||||||
_index int;
|
_index int;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *common) next() instr { return c._next }
|
func (c *common) next() instr {
|
||||||
func (c *common) setNext(i instr) { c._next = i }
|
return c._next;
|
||||||
func (c *common) index() int { return c._index }
|
}
|
||||||
func (c *common) setIndex(i int) { c._index = i }
|
func (c *common) setNext(i instr) {
|
||||||
|
c._next = i;
|
||||||
|
}
|
||||||
|
func (c *common) index() int {
|
||||||
|
return c._index;
|
||||||
|
}
|
||||||
|
func (c *common) setIndex(i int) {
|
||||||
|
c._index = i;
|
||||||
|
}
|
||||||
|
|
||||||
// The representation of a compiled regular expression.
|
// The representation of a compiled regular expression.
|
||||||
// The public interface is entirely through methods.
|
// The public interface is entirely through methods.
|
||||||
|
|
@ -78,8 +86,8 @@ type Regexp struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_START // beginning of program
|
_START = // beginning of program
|
||||||
= iota;
|
iota;
|
||||||
_END; // end of program: success
|
_END; // end of program: success
|
||||||
_BOT; // '^' beginning of text
|
_BOT; // '^' beginning of text
|
||||||
_EOT; // '$' end of text
|
_EOT; // '$' end of text
|
||||||
|
|
@ -95,35 +103,51 @@ const (
|
||||||
|
|
||||||
// --- START start of program
|
// --- START start of program
|
||||||
type _Start struct {
|
type _Start struct {
|
||||||
common
|
common;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (start *_Start) kind() int { return _START }
|
func (start *_Start) kind() int {
|
||||||
func (start *_Start) print() { print("start") }
|
return _START;
|
||||||
|
}
|
||||||
|
func (start *_Start) print() {
|
||||||
|
print("start");
|
||||||
|
}
|
||||||
|
|
||||||
// --- END end of program
|
// --- END end of program
|
||||||
type _End struct {
|
type _End struct {
|
||||||
common
|
common;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (end *_End) kind() int { return _END }
|
func (end *_End) kind() int {
|
||||||
func (end *_End) print() { print("end") }
|
return _END;
|
||||||
|
}
|
||||||
|
func (end *_End) print() {
|
||||||
|
print("end");
|
||||||
|
}
|
||||||
|
|
||||||
// --- BOT beginning of text
|
// --- BOT beginning of text
|
||||||
type _Bot struct {
|
type _Bot struct {
|
||||||
common
|
common;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bot *_Bot) kind() int { return _BOT }
|
func (bot *_Bot) kind() int {
|
||||||
func (bot *_Bot) print() { print("bot") }
|
return _BOT;
|
||||||
|
}
|
||||||
|
func (bot *_Bot) print() {
|
||||||
|
print("bot");
|
||||||
|
}
|
||||||
|
|
||||||
// --- EOT end of text
|
// --- EOT end of text
|
||||||
type _Eot struct {
|
type _Eot struct {
|
||||||
common
|
common;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eot *_Eot) kind() int { return _EOT }
|
func (eot *_Eot) kind() int {
|
||||||
func (eot *_Eot) print() { print("eot") }
|
return _EOT;
|
||||||
|
}
|
||||||
|
func (eot *_Eot) print() {
|
||||||
|
print("eot");
|
||||||
|
}
|
||||||
|
|
||||||
// --- CHAR a regular character
|
// --- CHAR a regular character
|
||||||
type _Char struct {
|
type _Char struct {
|
||||||
|
|
@ -131,8 +155,12 @@ type _Char struct {
|
||||||
char int;
|
char int;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (char *_Char) kind() int { return _CHAR }
|
func (char *_Char) kind() int {
|
||||||
func (char *_Char) print() { print("char ", string(char.char)) }
|
return _CHAR;
|
||||||
|
}
|
||||||
|
func (char *_Char) print() {
|
||||||
|
print("char ", string(char.char));
|
||||||
|
}
|
||||||
|
|
||||||
func newChar(char int) *_Char {
|
func newChar(char int) *_Char {
|
||||||
c := new(_Char);
|
c := new(_Char);
|
||||||
|
|
@ -150,7 +178,9 @@ type _CharClass struct {
|
||||||
ranges []int;
|
ranges []int;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cclass *_CharClass) kind() int { return _CHARCLASS }
|
func (cclass *_CharClass) kind() int {
|
||||||
|
return _CHARCLASS;
|
||||||
|
}
|
||||||
|
|
||||||
func (cclass *_CharClass) print() {
|
func (cclass *_CharClass) print() {
|
||||||
print("charclass");
|
print("charclass");
|
||||||
|
|
@ -174,7 +204,7 @@ func (cclass *_CharClass) addRange(a, b int) {
|
||||||
if n >= cap(cclass.ranges) {
|
if n >= cap(cclass.ranges) {
|
||||||
nr := make([]int, n, 2*n);
|
nr := make([]int, n, 2*n);
|
||||||
for i, j := range nr {
|
for i, j := range nr {
|
||||||
nr[i] = j
|
nr[i] = j;
|
||||||
}
|
}
|
||||||
cclass.ranges = nr;
|
cclass.ranges = nr;
|
||||||
}
|
}
|
||||||
|
|
@ -190,10 +220,10 @@ func (cclass *_CharClass) matches(c int) bool {
|
||||||
min := cclass.ranges[i];
|
min := cclass.ranges[i];
|
||||||
max := cclass.ranges[i+1];
|
max := cclass.ranges[i+1];
|
||||||
if min <= c && c <= max {
|
if min <= c && c <= max {
|
||||||
return !cclass.negate
|
return !cclass.negate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cclass.negate
|
return cclass.negate;
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCharClass() *_CharClass {
|
func newCharClass() *_CharClass {
|
||||||
|
|
@ -204,19 +234,27 @@ func newCharClass() *_CharClass {
|
||||||
|
|
||||||
// --- ANY any character
|
// --- ANY any character
|
||||||
type _Any struct {
|
type _Any struct {
|
||||||
common
|
common;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *_Any) kind() int { return _ANY }
|
func (any *_Any) kind() int {
|
||||||
func (any *_Any) print() { print("any") }
|
return _ANY;
|
||||||
|
}
|
||||||
|
func (any *_Any) print() {
|
||||||
|
print("any");
|
||||||
|
}
|
||||||
|
|
||||||
// --- NOTNL any character but newline
|
// --- NOTNL any character but newline
|
||||||
type _NotNl struct {
|
type _NotNl struct {
|
||||||
common
|
common;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (notnl *_NotNl) kind() int { return _NOTNL }
|
func (notnl *_NotNl) kind() int {
|
||||||
func (notnl *_NotNl) print() { print("notnl") }
|
return _NOTNL;
|
||||||
|
}
|
||||||
|
func (notnl *_NotNl) print() {
|
||||||
|
print("notnl");
|
||||||
|
}
|
||||||
|
|
||||||
// --- BRA parenthesized expression
|
// --- BRA parenthesized expression
|
||||||
type _Bra struct {
|
type _Bra struct {
|
||||||
|
|
@ -224,8 +262,12 @@ type _Bra struct {
|
||||||
n int; // subexpression number
|
n int; // subexpression number
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bra *_Bra) kind() int { return _BRA }
|
func (bra *_Bra) kind() int {
|
||||||
func (bra *_Bra) print() { print("bra", bra.n); }
|
return _BRA;
|
||||||
|
}
|
||||||
|
func (bra *_Bra) print() {
|
||||||
|
print("bra", bra.n);
|
||||||
|
}
|
||||||
|
|
||||||
// --- EBRA end of parenthesized expression
|
// --- EBRA end of parenthesized expression
|
||||||
type _Ebra struct {
|
type _Ebra struct {
|
||||||
|
|
@ -233,8 +275,12 @@ type _Ebra struct {
|
||||||
n int; // subexpression number
|
n int; // subexpression number
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ebra *_Ebra) kind() int { return _EBRA }
|
func (ebra *_Ebra) kind() int {
|
||||||
func (ebra *_Ebra) print() { print("ebra ", ebra.n); }
|
return _EBRA;
|
||||||
|
}
|
||||||
|
func (ebra *_Ebra) print() {
|
||||||
|
print("ebra ", ebra.n);
|
||||||
|
}
|
||||||
|
|
||||||
// --- ALT alternation
|
// --- ALT alternation
|
||||||
type _Alt struct {
|
type _Alt struct {
|
||||||
|
|
@ -242,16 +288,24 @@ type _Alt struct {
|
||||||
left instr; // other branch
|
left instr; // other branch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (alt *_Alt) kind() int { return _ALT }
|
func (alt *_Alt) kind() int {
|
||||||
func (alt *_Alt) print() { print("alt(", alt.left.index(), ")"); }
|
return _ALT;
|
||||||
|
}
|
||||||
|
func (alt *_Alt) print() {
|
||||||
|
print("alt(", alt.left.index(), ")");
|
||||||
|
}
|
||||||
|
|
||||||
// --- NOP no operation
|
// --- NOP no operation
|
||||||
type _Nop struct {
|
type _Nop struct {
|
||||||
common
|
common;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nop *_Nop) kind() int { return _NOP }
|
func (nop *_Nop) kind() int {
|
||||||
func (nop *_Nop) print() { print("nop") }
|
return _NOP;
|
||||||
|
}
|
||||||
|
func (nop *_Nop) print() {
|
||||||
|
print("nop");
|
||||||
|
}
|
||||||
|
|
||||||
// report error and exit compiling/executing goroutine
|
// report error and exit compiling/executing goroutine
|
||||||
func (re *Regexp) setError(err string) {
|
func (re *Regexp) setError(err string) {
|
||||||
|
|
@ -266,7 +320,7 @@ func (re *Regexp) add(i instr) instr {
|
||||||
if n >= cap(re.inst) {
|
if n >= cap(re.inst) {
|
||||||
ni := make([]instr, n, 2*n);
|
ni := make([]instr, n, 2*n);
|
||||||
for i, j := range re.inst {
|
for i, j := range re.inst {
|
||||||
ni[i] = j
|
ni[i] = j;
|
||||||
}
|
}
|
||||||
re.inst = ni;
|
re.inst = ni;
|
||||||
}
|
}
|
||||||
|
|
@ -290,7 +344,7 @@ func (p *parser) c() int {
|
||||||
|
|
||||||
func (p *parser) nextc() int {
|
func (p *parser) nextc() int {
|
||||||
if p.pos >= len(p.re.expr) {
|
if p.pos >= len(p.re.expr) {
|
||||||
p.ch = endOfFile
|
p.ch = endOfFile;
|
||||||
} else {
|
} else {
|
||||||
c, w := utf8.DecodeRuneInString(p.re.expr[p.pos : len(p.re.expr)]);
|
c, w := utf8.DecodeRuneInString(p.re.expr[p.pos : len(p.re.expr)]);
|
||||||
p.ch = c;
|
p.ch = c;
|
||||||
|
|
@ -312,20 +366,20 @@ func special(c int) bool {
|
||||||
s := `\.+*?()|[]^$`;
|
s := `\.+*?()|[]^$`;
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if c == int(s[i]) {
|
if c == int(s[i]) {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
func specialcclass(c int) bool {
|
func specialcclass(c int) bool {
|
||||||
s := `\-[]`;
|
s := `\-[]`;
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if c == int(s[i]) {
|
if c == int(s[i]) {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) charClass() instr {
|
func (p *parser) charClass() instr {
|
||||||
|
|
@ -383,7 +437,7 @@ func (p *parser) charClass() instr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return iNULL
|
return iNULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) term() (start, end instr) {
|
func (p *parser) term() (start, end instr) {
|
||||||
|
|
@ -438,9 +492,9 @@ func (p *parser) term() (start, end instr) {
|
||||||
ebra.n = nbra;
|
ebra.n = nbra;
|
||||||
if start == iNULL {
|
if start == iNULL {
|
||||||
if end == iNULL {
|
if end == iNULL {
|
||||||
p.re.setError(ErrInternal)
|
p.re.setError(ErrInternal);
|
||||||
}
|
}
|
||||||
start = ebra
|
start = ebra;
|
||||||
} else {
|
} else {
|
||||||
end.setNext(ebra);
|
end.setNext(ebra);
|
||||||
}
|
}
|
||||||
|
|
@ -463,7 +517,7 @@ func (p *parser) term() (start, end instr) {
|
||||||
p.nextc();
|
p.nextc();
|
||||||
start = newChar(c);
|
start = newChar(c);
|
||||||
p.re.add(start);
|
p.re.add(start);
|
||||||
return start, start
|
return start, start;
|
||||||
}
|
}
|
||||||
panic("unreachable");
|
panic("unreachable");
|
||||||
}
|
}
|
||||||
|
|
@ -471,7 +525,7 @@ func (p *parser) term() (start, end instr) {
|
||||||
func (p *parser) closure() (start, end instr) {
|
func (p *parser) closure() (start, end instr) {
|
||||||
start, end = p.term();
|
start, end = p.term();
|
||||||
if start == iNULL {
|
if start == iNULL {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
switch p.c() {
|
switch p.c() {
|
||||||
case '*':
|
case '*':
|
||||||
|
|
@ -501,13 +555,13 @@ func (p *parser) closure() (start, end instr) {
|
||||||
start = alt; // start is now alt
|
start = alt; // start is now alt
|
||||||
end = nop; // end is nop pointed to by both branches
|
end = nop; // end is nop pointed to by both branches
|
||||||
default:
|
default:
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
switch p.nextc() {
|
switch p.nextc() {
|
||||||
case '*', '+', '?':
|
case '*', '+', '?':
|
||||||
p.re.setError(ErrBadClosure);
|
p.re.setError(ErrBadClosure);
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) concatenation() (start, end instr) {
|
func (p *parser) concatenation() (start, end instr) {
|
||||||
|
|
@ -556,16 +610,16 @@ func (p *parser) regexp() (start, end instr) {
|
||||||
|
|
||||||
func unNop(i instr) instr {
|
func unNop(i instr) instr {
|
||||||
for i.kind() == _NOP {
|
for i.kind() == _NOP {
|
||||||
i = i.next()
|
i = i.next();
|
||||||
}
|
}
|
||||||
return i
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (re *Regexp) eliminateNops() {
|
func (re *Regexp) eliminateNops() {
|
||||||
for i := 0; i < len(re.inst); i++ {
|
for i := 0; i < len(re.inst); i++ {
|
||||||
inst := re.inst[i];
|
inst := re.inst[i];
|
||||||
if inst.kind() == _END {
|
if inst.kind() == _END {
|
||||||
continue
|
continue;
|
||||||
}
|
}
|
||||||
inst.setNext(unNop(inst.next()));
|
inst.setNext(unNop(inst.next()));
|
||||||
if inst.kind() == _ALT {
|
if inst.kind() == _ALT {
|
||||||
|
|
@ -581,7 +635,7 @@ func (re *Regexp) dump() {
|
||||||
print(inst.index(), ": ");
|
print(inst.index(), ": ");
|
||||||
inst.print();
|
inst.print();
|
||||||
if inst.kind() != _END {
|
if inst.kind() != _END {
|
||||||
print(" -> ", inst.next().index())
|
print(" -> ", inst.next().index());
|
||||||
}
|
}
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
|
@ -626,7 +680,7 @@ func CompileRegexp(str string) (regexp *Regexp, error string) {
|
||||||
ch := make(chan *Regexp);
|
ch := make(chan *Regexp);
|
||||||
go compiler(str, ch);
|
go compiler(str, ch);
|
||||||
re := <-ch;
|
re := <-ch;
|
||||||
return re, re.error
|
return re, re.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
type state struct {
|
type state struct {
|
||||||
|
|
@ -645,7 +699,7 @@ func addState(s []state, inst instr, match []int) []state {
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
if s[i].inst.index() == index && // same instruction
|
if s[i].inst.index() == index && // same instruction
|
||||||
s[i].match[0] < pos { // earlier match already going; lefmost wins
|
s[i].match[0] < pos { // earlier match already going; lefmost wins
|
||||||
return s
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if l == cap(s) {
|
if l == cap(s) {
|
||||||
|
|
@ -672,7 +726,7 @@ func (re *Regexp) doExecute(str string, bytes []byte, pos int) []int {
|
||||||
found := false;
|
found := false;
|
||||||
end := len(str);
|
end := len(str);
|
||||||
if bytes != nil {
|
if bytes != nil {
|
||||||
end = len(bytes)
|
end = len(bytes);
|
||||||
}
|
}
|
||||||
for pos <= end {
|
for pos <= end {
|
||||||
if !found {
|
if !found {
|
||||||
|
|
@ -704,27 +758,27 @@ func (re *Regexp) doExecute(str string, bytes []byte, pos int) []int {
|
||||||
switch s[in][i].inst.kind() {
|
switch s[in][i].inst.kind() {
|
||||||
case _BOT:
|
case _BOT:
|
||||||
if pos == 0 {
|
if pos == 0 {
|
||||||
s[in] = addState(s[in], st.inst.next(), st.match)
|
s[in] = addState(s[in], st.inst.next(), st.match);
|
||||||
}
|
}
|
||||||
case _EOT:
|
case _EOT:
|
||||||
if pos == end {
|
if pos == end {
|
||||||
s[in] = addState(s[in], st.inst.next(), st.match)
|
s[in] = addState(s[in], st.inst.next(), st.match);
|
||||||
}
|
}
|
||||||
case _CHAR:
|
case _CHAR:
|
||||||
if c == st.inst.(*_Char).char {
|
if c == st.inst.(*_Char).char {
|
||||||
s[out] = addState(s[out], st.inst.next(), st.match)
|
s[out] = addState(s[out], st.inst.next(), st.match);
|
||||||
}
|
}
|
||||||
case _CHARCLASS:
|
case _CHARCLASS:
|
||||||
if st.inst.(*_CharClass).matches(c) {
|
if st.inst.(*_CharClass).matches(c) {
|
||||||
s[out] = addState(s[out], st.inst.next(), st.match)
|
s[out] = addState(s[out], st.inst.next(), st.match);
|
||||||
}
|
}
|
||||||
case _ANY:
|
case _ANY:
|
||||||
if c != endOfFile {
|
if c != endOfFile {
|
||||||
s[out] = addState(s[out], st.inst.next(), st.match)
|
s[out] = addState(s[out], st.inst.next(), st.match);
|
||||||
}
|
}
|
||||||
case _NOTNL:
|
case _NOTNL:
|
||||||
if c != endOfFile && c != '\n' {
|
if c != endOfFile && c != '\n' {
|
||||||
s[out] = addState(s[out], st.inst.next(), st.match)
|
s[out] = addState(s[out], st.inst.next(), st.match);
|
||||||
}
|
}
|
||||||
case _BRA:
|
case _BRA:
|
||||||
n := st.inst.(*_Bra).n;
|
n := st.inst.(*_Bra).n;
|
||||||
|
|
@ -739,7 +793,7 @@ func (re *Regexp) doExecute(str string, bytes []byte, pos int) []int {
|
||||||
// give other branch a copy of this match vector
|
// give other branch a copy of this match vector
|
||||||
s1 := make([]int, 2*(re.nbra + 1));
|
s1 := make([]int, 2*(re.nbra + 1));
|
||||||
for i := 0; i < len(s1); i++ {
|
for i := 0; i < len(s1); i++ {
|
||||||
s1[i] = st.match[i]
|
s1[i] = st.match[i];
|
||||||
}
|
}
|
||||||
s[in] = addState(s[in], st.inst.next(), s1);
|
s[in] = addState(s[in], st.inst.next(), s1);
|
||||||
case _END:
|
case _END:
|
||||||
|
|
@ -770,7 +824,7 @@ func (re *Regexp) doExecute(str string, bytes []byte, pos int) []int {
|
||||||
// A negative value means the subexpression did not match any element of the string.
|
// A negative value means the subexpression did not match any element of the string.
|
||||||
// An empty array means "no match".
|
// An empty array means "no match".
|
||||||
func (re *Regexp) ExecuteString(s string) (a []int) {
|
func (re *Regexp) ExecuteString(s string) (a []int) {
|
||||||
return re.doExecute(s, nil, 0)
|
return re.doExecute(s, nil, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -782,21 +836,21 @@ func (re *Regexp) ExecuteString(s string) (a []int) {
|
||||||
// A negative value means the subexpression did not match any element of the slice.
|
// A negative value means the subexpression did not match any element of the slice.
|
||||||
// An empty array means "no match".
|
// An empty array means "no match".
|
||||||
func (re *Regexp) Execute(b []byte) (a []int) {
|
func (re *Regexp) Execute(b []byte) (a []int) {
|
||||||
return re.doExecute("", b, 0)
|
return re.doExecute("", b, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MatchString returns whether the Regexp matches the string s.
|
// MatchString returns whether the Regexp matches the string s.
|
||||||
// The return value is a boolean: true for match, false for no match.
|
// The return value is a boolean: true for match, false for no match.
|
||||||
func (re *Regexp) MatchString(s string) bool {
|
func (re *Regexp) MatchString(s string) bool {
|
||||||
return len(re.doExecute(s, nil, 0)) > 0
|
return len(re.doExecute(s, nil, 0)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Match returns whether the Regexp matches the byte slice b.
|
// Match returns whether the Regexp matches the byte slice b.
|
||||||
// The return value is a boolean: true for match, false for no match.
|
// The return value is a boolean: true for match, false for no match.
|
||||||
func (re *Regexp) Match(b []byte) bool {
|
func (re *Regexp) Match(b []byte) bool {
|
||||||
return len(re.doExecute("", b, 0)) > 0
|
return len(re.doExecute("", b, 0)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -808,15 +862,15 @@ func (re *Regexp) Match(b []byte) bool {
|
||||||
func (re *Regexp) MatchStrings(s string) (a []string) {
|
func (re *Regexp) MatchStrings(s string) (a []string) {
|
||||||
r := re.doExecute(s, nil, 0);
|
r := re.doExecute(s, nil, 0);
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil
|
return nil;
|
||||||
}
|
}
|
||||||
a = make([]string, len(r)/2);
|
a = make([]string, len(r)/2);
|
||||||
for i := 0; i < len(r); i += 2 {
|
for i := 0; i < len(r); i += 2 {
|
||||||
if r[i] != -1 { // -1 means no match for this subexpression
|
if r[i] != -1 { // -1 means no match for this subexpression
|
||||||
a[i/2] = s[r[i] : r[i+1]]
|
a[i/2] = s[r[i]:r[i+1]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MatchSlices matches the Regexp against the byte slice b.
|
// MatchSlices matches the Regexp against the byte slice b.
|
||||||
|
|
@ -827,15 +881,15 @@ func (re *Regexp) MatchStrings(s string) (a []string) {
|
||||||
func (re *Regexp) MatchSlices(b []byte) (a [][]byte) {
|
func (re *Regexp) MatchSlices(b []byte) (a [][]byte) {
|
||||||
r := re.doExecute("", b, 0);
|
r := re.doExecute("", b, 0);
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil
|
return nil;
|
||||||
}
|
}
|
||||||
a = make([][]byte, len(r)/2);
|
a = make([][]byte, len(r)/2);
|
||||||
for i := 0; i < len(r); i += 2 {
|
for i := 0; i < len(r); i += 2 {
|
||||||
if r[i] != -1 { // -1 means no match for this subexpression
|
if r[i] != -1 { // -1 means no match for this subexpression
|
||||||
a[i/2] = b[r[i] : r[i+1]]
|
a[i/2] = b[r[i]:r[i+1]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MatchString checks whether a textual regular expression
|
// MatchString checks whether a textual regular expression
|
||||||
|
|
@ -844,9 +898,9 @@ func (re *Regexp) MatchSlices(b []byte) (a [][]byte) {
|
||||||
func MatchString(pattern string, s string) (matched bool, error string) {
|
func MatchString(pattern string, s string) (matched bool, error string) {
|
||||||
re, err := CompileRegexp(pattern);
|
re, err := CompileRegexp(pattern);
|
||||||
if err != "" {
|
if err != "" {
|
||||||
return false, err
|
return false, err;
|
||||||
}
|
}
|
||||||
return re.MatchString(s), ""
|
return re.MatchString(s), "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match checks whether a textual regular expression
|
// Match checks whether a textual regular expression
|
||||||
|
|
@ -855,7 +909,7 @@ func MatchString(pattern string, s string) (matched bool, error string) {
|
||||||
func Match(pattern string, b []byte) (matched bool, error string) {
|
func Match(pattern string, b []byte) (matched bool, error string) {
|
||||||
re, err := CompileRegexp(pattern);
|
re, err := CompileRegexp(pattern);
|
||||||
if err != "" {
|
if err != "" {
|
||||||
return false, err
|
return false, err;
|
||||||
}
|
}
|
||||||
return re.Match(b), ""
|
return re.Match(b), "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ type stringError struct {
|
||||||
re string;
|
re string;
|
||||||
err string;
|
err string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bad_re = []stringError{
|
var bad_re = []stringError{
|
||||||
stringError{`*`, ErrBareClosure},
|
stringError{`*`, ErrBareClosure},
|
||||||
stringError{`(abc`, ErrUnmatchedLpar},
|
stringError{`(abc`, ErrUnmatchedLpar},
|
||||||
|
|
@ -48,7 +49,7 @@ var bad_re = []stringError{
|
||||||
stringError{`\x`, ErrBadBackslash},
|
stringError{`\x`, ErrBadBackslash},
|
||||||
}
|
}
|
||||||
|
|
||||||
type vec []int;
|
type vec []int
|
||||||
|
|
||||||
type tester struct {
|
type tester struct {
|
||||||
re string;
|
re string;
|
||||||
|
|
@ -90,7 +91,7 @@ func compileTest(t *T, expr string, error string) *Regexp {
|
||||||
if err != error {
|
if err != error {
|
||||||
t.Error("compiling `", expr, "`; unexpected error: ", err);
|
t.Error("compiling `", expr, "`; unexpected error: ", err);
|
||||||
}
|
}
|
||||||
return re
|
return re;
|
||||||
}
|
}
|
||||||
|
|
||||||
func printVec(t *T, m []int) {
|
func printVec(t *T, m []int) {
|
||||||
|
|
@ -99,7 +100,7 @@ func printVec(t *T, m []int) {
|
||||||
t.Log("\t<no match>");
|
t.Log("\t<no match>");
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < l; i = i+2 {
|
for i := 0; i < l; i = i+2 {
|
||||||
t.Log("\t", m[i], ",", m[i+1])
|
t.Log("\t", m[i], ",", m[i+1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +111,7 @@ func printStrings(t *T, m []string) {
|
||||||
t.Log("\t<no match>");
|
t.Log("\t<no match>");
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < l; i = i+2 {
|
for i := 0; i < l; i = i+2 {
|
||||||
t.Logf("\t%q", m[i])
|
t.Logf("\t%q", m[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +122,7 @@ func printBytes(t *T, b [][]byte) {
|
||||||
t.Log("\t<no match>");
|
t.Log("\t<no match>");
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < l; i = i+2 {
|
for i := 0; i < l; i = i+2 {
|
||||||
t.Logf("\t%q", b[i])
|
t.Logf("\t%q", b[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -129,46 +130,46 @@ func printBytes(t *T, b [][]byte) {
|
||||||
func equal(m1, m2 []int) bool {
|
func equal(m1, m2 []int) bool {
|
||||||
l := len(m1);
|
l := len(m1);
|
||||||
if l != len(m2) {
|
if l != len(m2) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
if m1[i] != m2[i] {
|
if m1[i] != m2[i] {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
func equalStrings(m1, m2 []string) bool {
|
func equalStrings(m1, m2 []string) bool {
|
||||||
l := len(m1);
|
l := len(m1);
|
||||||
if l != len(m2) {
|
if l != len(m2) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
if m1[i] != m2[i] {
|
if m1[i] != m2[i] {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
func equalBytes(m1 [][]byte, m2 []string) bool {
|
func equalBytes(m1 [][]byte, m2 []string) bool {
|
||||||
l := len(m1);
|
l := len(m1);
|
||||||
if l != len(m2) {
|
if l != len(m2) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
if string(m1[i]) != m2[i] {
|
if string(m1[i]) != m2[i] {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeTest(t *T, expr string, str string, match []int) {
|
func executeTest(t *T, expr string, str string, match []int) {
|
||||||
re := compileTest(t, expr, "");
|
re := compileTest(t, expr, "");
|
||||||
if re == nil {
|
if re == nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
m := re.ExecuteString(str);
|
m := re.ExecuteString(str);
|
||||||
if !equal(m, match) {
|
if !equal(m, match) {
|
||||||
|
|
@ -195,21 +196,21 @@ func TestGoodCompile(t *T) {
|
||||||
|
|
||||||
func TestBadCompile(t *T) {
|
func TestBadCompile(t *T) {
|
||||||
for i := 0; i < len(bad_re); i++ {
|
for i := 0; i < len(bad_re); i++ {
|
||||||
compileTest(t, bad_re[i].re, bad_re[i].err)
|
compileTest(t, bad_re[i].re, bad_re[i].err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecute(t *T) {
|
func TestExecute(t *T) {
|
||||||
for i := 0; i < len(matches); i++ {
|
for i := 0; i < len(matches); i++ {
|
||||||
test := &matches[i];
|
test := &matches[i];
|
||||||
executeTest(t, test.re, test.text, test.match)
|
executeTest(t, test.re, test.text, test.match);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchTest(t *T, expr string, str string, match []int) {
|
func matchTest(t *T, expr string, str string, match []int) {
|
||||||
re := compileTest(t, expr, "");
|
re := compileTest(t, expr, "");
|
||||||
if re == nil {
|
if re == nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
m := re.MatchString(str);
|
m := re.MatchString(str);
|
||||||
if m != (len(match) > 0) {
|
if m != (len(match) > 0) {
|
||||||
|
|
@ -225,18 +226,18 @@ func matchTest(t *T, expr string, str string, match []int) {
|
||||||
func TestMatch(t *T) {
|
func TestMatch(t *T) {
|
||||||
for i := 0; i < len(matches); i++ {
|
for i := 0; i < len(matches); i++ {
|
||||||
test := &matches[i];
|
test := &matches[i];
|
||||||
matchTest(t, test.re, test.text, test.match)
|
matchTest(t, test.re, test.text, test.match);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchStringsTest(t *T, expr string, str string, match []int) {
|
func matchStringsTest(t *T, expr string, str string, match []int) {
|
||||||
re := compileTest(t, expr, "");
|
re := compileTest(t, expr, "");
|
||||||
if re == nil {
|
if re == nil {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
strs := make([]string, len(match)/2);
|
strs := make([]string, len(match)/2);
|
||||||
for i := 0; i < len(match); i++ {
|
for i := 0; i < len(match); i++ {
|
||||||
strs[i/2] = str[match[i] : match[i+1]]
|
strs[i/2] = str[match[i]:match[i+1]];
|
||||||
}
|
}
|
||||||
m := re.MatchStrings(str);
|
m := re.MatchStrings(str);
|
||||||
if !equalStrings(m, strs) {
|
if !equalStrings(m, strs) {
|
||||||
|
|
@ -258,14 +259,14 @@ func matchStringsTest(t *T, expr string, str string, match []int) {
|
||||||
func TestMatchStrings(t *T) {
|
func TestMatchStrings(t *T) {
|
||||||
for i := 0; i < len(matches); i++ {
|
for i := 0; i < len(matches); i++ {
|
||||||
test := &matches[i];
|
test := &matches[i];
|
||||||
matchTest(t, test.re, test.text, test.match)
|
matchTest(t, test.re, test.text, test.match);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchFunctionTest(t *T, expr string, str string, match []int) {
|
func matchFunctionTest(t *T, expr string, str string, match []int) {
|
||||||
m, err := MatchString(expr, str);
|
m, err := MatchString(expr, str);
|
||||||
if err == "" {
|
if err == "" {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if m != (len(match) > 0) {
|
if m != (len(match) > 0) {
|
||||||
t.Error("function Match failure on `", expr, "` matching `", str, "`:", m, "should be", len(match) > 0);
|
t.Error("function Match failure on `", expr, "` matching `", str, "`:", m, "should be", len(match) > 0);
|
||||||
|
|
@ -275,6 +276,6 @@ func matchFunctionTest(t *T, expr string, str string, match []int) {
|
||||||
func TestMatchFunction(t *T) {
|
func TestMatchFunction(t *T) {
|
||||||
for i := 0; i < len(matches); i++ {
|
for i := 0; i < len(matches); i++ {
|
||||||
test := &matches[i];
|
test := &matches[i];
|
||||||
matchFunctionTest(t, test.re, test.text, test.match)
|
matchFunctionTest(t, test.re, test.text, test.match);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,24 +29,24 @@ var utctests = []TimeTest {
|
||||||
TimeTest{1e18, Time{31688740476, 10, 23, 1, 46, 40, Friday, 0, "UTC"}},
|
TimeTest{1e18, Time{31688740476, 10, 23, 1, 46, 40, Friday, 0, "UTC"}},
|
||||||
TimeTest{-1e18, Time{-31688736537, 3, 10, 22, 13, 20, Tuesday, 0, "UTC"}},
|
TimeTest{-1e18, Time{-31688736537, 3, 10, 22, 13, 20, Tuesday, 0, "UTC"}},
|
||||||
TimeTest{0x7fffffffffffffff, Time{292277026596, 12, 4, 15, 30, 7, Sunday, 0, "UTC"}},
|
TimeTest{0x7fffffffffffffff, Time{292277026596, 12, 4, 15, 30, 7, Sunday, 0, "UTC"}},
|
||||||
TimeTest{-0x8000000000000000, Time{-292277022657, 1, 27, 8, 29, 52, Sunday, 0, "UTC"}}
|
TimeTest{-0x8000000000000000, Time{-292277022657, 1, 27, 8, 29, 52, Sunday, 0, "UTC"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
var localtests = []TimeTest{
|
var localtests = []TimeTest{
|
||||||
TimeTest{0, Time{1969, 12, 31, 16, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
|
TimeTest{0, Time{1969, 12, 31, 16, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
|
||||||
TimeTest{1221681866, Time{2008, 9, 17, 13, 4, 26, Wednesday, -7*60*60, "PDT"}}
|
TimeTest{1221681866, Time{2008, 9, 17, 13, 4, 26, Wednesday, -7 * 60 * 60, "PDT"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
func same(t, u *Time) bool {
|
func same(t, u *Time) bool {
|
||||||
return t.Year == u.Year
|
return t.Year == u.Year &&
|
||||||
&& t.Month == u.Month
|
t.Month == u.Month &&
|
||||||
&& t.Day == u.Day
|
t.Day == u.Day &&
|
||||||
&& t.Hour == u.Hour
|
t.Hour == u.Hour &&
|
||||||
&& t.Minute == u.Minute
|
t.Minute == u.Minute &&
|
||||||
&& t.Second == u.Second
|
t.Second == u.Second &&
|
||||||
&& t.Weekday == u.Weekday
|
t.Weekday == u.Weekday &&
|
||||||
&& t.ZoneOffset == u.ZoneOffset
|
t.ZoneOffset == u.ZoneOffset &&
|
||||||
&& t.Zone == u.Zone
|
t.Zone == u.Zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSecondsToUTC(t *testing.T) {
|
func TestSecondsToUTC(t *testing.T) {
|
||||||
|
|
@ -82,4 +82,3 @@ func TestSecondsToLocalTime(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,7 @@ var inTest = []T {
|
||||||
}
|
}
|
||||||
|
|
||||||
var outTest = []T{ // not really worth being thorough
|
var outTest = []T{ // not really worth being thorough
|
||||||
T{0x20, "Telugu"}
|
T{0x20, "Telugu"}}
|
||||||
}
|
|
||||||
|
|
||||||
var inCategoryTest = []T{
|
var inCategoryTest = []T{
|
||||||
T{0x0081, "Cc"},
|
T{0x0081, "Cc"},
|
||||||
|
|
@ -172,16 +171,16 @@ var inPropTest = []T {
|
||||||
func TestScripts(t *testing.T) {
|
func TestScripts(t *testing.T) {
|
||||||
notTested := make(map[string]bool);
|
notTested := make(map[string]bool);
|
||||||
for k := range Scripts {
|
for k := range Scripts {
|
||||||
notTested[k] = true
|
notTested[k] = true;
|
||||||
}
|
}
|
||||||
for _, test := range inTest {
|
for _, test := range inTest {
|
||||||
if _, ok := Scripts[test.script]; !ok {
|
if _, ok := Scripts[test.script]; !ok {
|
||||||
t.Fatal(test.script, "not a known script")
|
t.Fatal(test.script, "not a known script");
|
||||||
}
|
}
|
||||||
if !Is(Scripts[test.script], test.rune) {
|
if !Is(Scripts[test.script], test.rune) {
|
||||||
t.Errorf("IsScript(%#x, %s) = false, want true\n", test.rune, test.script);
|
t.Errorf("IsScript(%#x, %s) = false, want true\n", test.rune, test.script);
|
||||||
}
|
}
|
||||||
notTested[test.script] = false, false
|
notTested[test.script] = false, false;
|
||||||
}
|
}
|
||||||
for _, test := range outTest {
|
for _, test := range outTest {
|
||||||
if Is(Scripts[test.script], test.rune) {
|
if Is(Scripts[test.script], test.rune) {
|
||||||
|
|
@ -189,44 +188,44 @@ func TestScripts(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for k := range notTested {
|
for k := range notTested {
|
||||||
t.Error("not tested:", k)
|
t.Error("not tested:", k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCategories(t *testing.T) {
|
func TestCategories(t *testing.T) {
|
||||||
notTested := make(map[string]bool);
|
notTested := make(map[string]bool);
|
||||||
for k := range Categories {
|
for k := range Categories {
|
||||||
notTested[k] = true
|
notTested[k] = true;
|
||||||
}
|
}
|
||||||
for _, test := range inCategoryTest {
|
for _, test := range inCategoryTest {
|
||||||
if _, ok := Categories[test.script]; !ok {
|
if _, ok := Categories[test.script]; !ok {
|
||||||
t.Fatal(test.script, "not a known category")
|
t.Fatal(test.script, "not a known category");
|
||||||
}
|
}
|
||||||
if !Is(Categories[test.script], test.rune) {
|
if !Is(Categories[test.script], test.rune) {
|
||||||
t.Errorf("IsCategory(%#x, %s) = false, want true\n", test.rune, test.script);
|
t.Errorf("IsCategory(%#x, %s) = false, want true\n", test.rune, test.script);
|
||||||
}
|
}
|
||||||
notTested[test.script] = false, false
|
notTested[test.script] = false, false;
|
||||||
}
|
}
|
||||||
for k := range notTested {
|
for k := range notTested {
|
||||||
t.Error("not tested:", k)
|
t.Error("not tested:", k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProperties(t *testing.T) {
|
func TestProperties(t *testing.T) {
|
||||||
notTested := make(map[string]bool);
|
notTested := make(map[string]bool);
|
||||||
for k := range Properties {
|
for k := range Properties {
|
||||||
notTested[k] = true
|
notTested[k] = true;
|
||||||
}
|
}
|
||||||
for _, test := range inPropTest {
|
for _, test := range inPropTest {
|
||||||
if _, ok := Properties[test.script]; !ok {
|
if _, ok := Properties[test.script]; !ok {
|
||||||
t.Fatal(test.script, "not a known prop")
|
t.Fatal(test.script, "not a known prop");
|
||||||
}
|
}
|
||||||
if !Is(Properties[test.script], test.rune) {
|
if !Is(Properties[test.script], test.rune) {
|
||||||
t.Errorf("IsCategory(%#x, %s) = false, want true\n", test.rune, test.script);
|
t.Errorf("IsCategory(%#x, %s) = false, want true\n", test.rune, test.script);
|
||||||
}
|
}
|
||||||
notTested[test.script] = false, false
|
notTested[test.script] = false, false;
|
||||||
}
|
}
|
||||||
for k := range notTested {
|
for k := range notTested {
|
||||||
t.Error("not tested:", k)
|
t.Error("not tested:", k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,70 +43,70 @@ func decodeRuneInternal(p []byte) (rune, size int, short bool) {
|
||||||
|
|
||||||
// 1-byte, 7-bit sequence?
|
// 1-byte, 7-bit sequence?
|
||||||
if c0 < _Tx {
|
if c0 < _Tx {
|
||||||
return int(c0), 1, false
|
return int(c0), 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unexpected continuation byte?
|
// unexpected continuation byte?
|
||||||
if c0 < _T2 {
|
if c0 < _T2 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need first continuation byte
|
// need first continuation byte
|
||||||
if n < 2 {
|
if n < 2 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true;
|
||||||
}
|
}
|
||||||
c1 := p[1];
|
c1 := p[1];
|
||||||
if c1 < _Tx || _T2 <= c1 {
|
if c1 < _Tx || _T2 <= c1 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2-byte, 11-bit sequence?
|
// 2-byte, 11-bit sequence?
|
||||||
if c0 < _T3 {
|
if c0 < _T3 {
|
||||||
rune = int(c0&_Mask2)<<6 | int(c1&_Maskx);
|
rune = int(c0&_Mask2)<<6 | int(c1&_Maskx);
|
||||||
if rune <= _Rune1Max {
|
if rune <= _Rune1Max {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
return rune, 2, false
|
return rune, 2, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need second continuation byte
|
// need second continuation byte
|
||||||
if n < 3 {
|
if n < 3 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true;
|
||||||
}
|
}
|
||||||
c2 := p[2];
|
c2 := p[2];
|
||||||
if c2 < _Tx || _T2 <= c2 {
|
if c2 < _Tx || _T2 <= c2 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3-byte, 16-bit sequence?
|
// 3-byte, 16-bit sequence?
|
||||||
if c0 < _T4 {
|
if c0 < _T4 {
|
||||||
rune = int(c0&_Mask3)<<12 | int(c1&_Maskx)<<6 | int(c2&_Maskx);
|
rune = int(c0&_Mask3)<<12 | int(c1&_Maskx)<<6 | int(c2&_Maskx);
|
||||||
if rune <= _Rune2Max {
|
if rune <= _Rune2Max {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
return rune, 3, false
|
return rune, 3, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need third continuation byte
|
// need third continuation byte
|
||||||
if n < 4 {
|
if n < 4 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true;
|
||||||
}
|
}
|
||||||
c3 := p[3];
|
c3 := p[3];
|
||||||
if c3 < _Tx || _T2 <= c3 {
|
if c3 < _Tx || _T2 <= c3 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4-byte, 21-bit sequence?
|
// 4-byte, 21-bit sequence?
|
||||||
if c0 < _T5 {
|
if c0 < _T5 {
|
||||||
rune = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx);
|
rune = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx);
|
||||||
if rune <= _Rune3Max {
|
if rune <= _Rune3Max {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
return rune, 4, false
|
return rune, 4, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// error
|
// error
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
|
func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
|
||||||
|
|
@ -118,83 +118,83 @@ func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
|
||||||
|
|
||||||
// 1-byte, 7-bit sequence?
|
// 1-byte, 7-bit sequence?
|
||||||
if c0 < _Tx {
|
if c0 < _Tx {
|
||||||
return int(c0), 1, false
|
return int(c0), 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unexpected continuation byte?
|
// unexpected continuation byte?
|
||||||
if c0 < _T2 {
|
if c0 < _T2 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need first continuation byte
|
// need first continuation byte
|
||||||
if n < 2 {
|
if n < 2 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true;
|
||||||
}
|
}
|
||||||
c1 := s[1];
|
c1 := s[1];
|
||||||
if c1 < _Tx || _T2 <= c1 {
|
if c1 < _Tx || _T2 <= c1 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2-byte, 11-bit sequence?
|
// 2-byte, 11-bit sequence?
|
||||||
if c0 < _T3 {
|
if c0 < _T3 {
|
||||||
rune = int(c0&_Mask2)<<6 | int(c1&_Maskx);
|
rune = int(c0&_Mask2)<<6 | int(c1&_Maskx);
|
||||||
if rune <= _Rune1Max {
|
if rune <= _Rune1Max {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
return rune, 2, false
|
return rune, 2, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need second continuation byte
|
// need second continuation byte
|
||||||
if n < 3 {
|
if n < 3 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true;
|
||||||
}
|
}
|
||||||
c2 := s[2];
|
c2 := s[2];
|
||||||
if c2 < _Tx || _T2 <= c2 {
|
if c2 < _Tx || _T2 <= c2 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3-byte, 16-bit sequence?
|
// 3-byte, 16-bit sequence?
|
||||||
if c0 < _T4 {
|
if c0 < _T4 {
|
||||||
rune = int(c0&_Mask3)<<12 | int(c1&_Maskx)<<6 | int(c2&_Maskx);
|
rune = int(c0&_Mask3)<<12 | int(c1&_Maskx)<<6 | int(c2&_Maskx);
|
||||||
if rune <= _Rune2Max {
|
if rune <= _Rune2Max {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
return rune, 3, false
|
return rune, 3, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need third continuation byte
|
// need third continuation byte
|
||||||
if n < 4 {
|
if n < 4 {
|
||||||
return RuneError, 1, true
|
return RuneError, 1, true;
|
||||||
}
|
}
|
||||||
c3 := s[3];
|
c3 := s[3];
|
||||||
if c3 < _Tx || _T2 <= c3 {
|
if c3 < _Tx || _T2 <= c3 {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4-byte, 21-bit sequence?
|
// 4-byte, 21-bit sequence?
|
||||||
if c0 < _T5 {
|
if c0 < _T5 {
|
||||||
rune = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx);
|
rune = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx);
|
||||||
if rune <= _Rune3Max {
|
if rune <= _Rune3Max {
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
return rune, 4, false
|
return rune, 4, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// error
|
// error
|
||||||
return RuneError, 1, false
|
return RuneError, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
|
// FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
|
||||||
// An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
|
// An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
|
||||||
func FullRune(p []byte) bool {
|
func FullRune(p []byte) bool {
|
||||||
_, _, short := decodeRuneInternal(p);
|
_, _, short := decodeRuneInternal(p);
|
||||||
return !short
|
return !short;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullRuneInString is like FullRune but its input is a string.
|
// FullRuneInString is like FullRune but its input is a string.
|
||||||
func FullRuneInString(s string) bool {
|
func FullRuneInString(s string) bool {
|
||||||
_, _, short := decodeRuneInStringInternal(s);
|
_, _, short := decodeRuneInStringInternal(s);
|
||||||
return !short
|
return !short;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes.
|
// DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes.
|
||||||
|
|
@ -239,7 +239,7 @@ func EncodeRune(rune int, p []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if rune > unicode.MaxRune {
|
if rune > unicode.MaxRune {
|
||||||
rune = RuneError
|
rune = RuneError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if rune <= _Rune3Max {
|
if rune <= _Rune3Max {
|
||||||
|
|
@ -292,5 +292,5 @@ func RuneCountInString(s string) int {
|
||||||
// an encoded rune. Second and subsequent bytes always have the top
|
// an encoded rune. Second and subsequent bytes always have the top
|
||||||
// two bits set to 10.
|
// two bits set to 10.
|
||||||
func RuneStart(b byte) bool {
|
func RuneStart(b byte) bool {
|
||||||
return b & 0xC0 != 0x80
|
return b&0xC0 != 0x80;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import (
|
||||||
|
|
||||||
// A SyntaxError represents a syntax error in the XML input stream.
|
// A SyntaxError represents a syntax error in the XML input stream.
|
||||||
type SyntaxError string
|
type SyntaxError string
|
||||||
|
|
||||||
func (e SyntaxError) String() string {
|
func (e SyntaxError) String() string {
|
||||||
return "XML syntax error: " + string(e);
|
return "XML syntax error: " + string(e);
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +105,7 @@ func (d Directive) Copy() Directive {
|
||||||
}
|
}
|
||||||
|
|
||||||
type readByter interface {
|
type readByter interface {
|
||||||
ReadByte() (b byte, err os.Error)
|
ReadByte() (b byte, err os.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Parser represents an XML parser reading a particular input stream.
|
// A Parser represents an XML parser reading a particular input stream.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue