Source File
scan.go
Belonging Package
fmt
package fmt
import (
)
func ( string, ...interface{}) ( int, error) {
return Fscan((*stringReader)(&), ...)
}
func ( string, ...interface{}) ( int, error) {
return Fscanln((*stringReader)(&), ...)
}
type ssave struct {
validSave bool // is or was a part of an actual ss.
nlIsEnd bool // whether newline terminates scan
nlIsSpace bool // whether newline counts as white space
argLimit int // max value of ss.count for this arg; argLimit <= limit
limit int // max value of ss.count.
maxWid int // width of this arg.
}
func ( *ss) ( []byte) ( int, error) {
return 0, errors.New("ScanState's Read should not be called. Use ReadRune")
}
func ( *ss) () ( rune, int, error) {
if .atEOF || .count >= .argLimit {
= io.EOF
return
}
, , = .rs.ReadRune()
if == nil {
.count++
if .nlIsEnd && == '\n' {
.atEOF = true
}
} else if == io.EOF {
.atEOF = true
}
return
}
func ( *ss) () ( int, bool) {
if .maxWid == hugeWid {
return 0, false
}
return .maxWid, true
}
func ( *ss) () ( rune) {
= .getRune()
if == eof {
.error(io.ErrUnexpectedEOF)
}
return
}
func ( *ss) () error {
.rs.UnreadRune()
.atEOF = false
.count--
return nil
}
func ( *ss) ( error) {
panic(scanError{})
}
func ( *ss) ( string) {
panic(scanError{errors.New()})
}
func ( *ss) ( bool, func(rune) bool) ( []byte, error) {
defer func() {
if := recover(); != nil {
if , := .(scanError); {
= .err
} else {
panic()
}
}
}()
if == nil {
= notSpace
}
.buf = .buf[:0]
= .token(, )
return
}
var space = [][2]uint16{
{0x0009, 0x000d},
{0x0020, 0x0020},
{0x0085, 0x0085},
{0x00a0, 0x00a0},
{0x1680, 0x1680},
{0x2000, 0x200a},
{0x2028, 0x2029},
{0x202f, 0x202f},
{0x205f, 0x205f},
{0x3000, 0x3000},
}
func ( rune) bool {
if >= 1<<16 {
return false
}
:= uint16()
for , := range space {
if < [0] {
return false
}
if <= [1] {
return true
}
}
return false
}
func ( *ss) () {
for {
:= .getRune()
if == eof {
return
}
if == '\r' && .peek("\n") {
continue
}
if == '\n' {
if .nlIsSpace {
continue
}
.errorString("unexpected newline")
return
}
if !isSpace() {
.UnreadRune()
break
}
}
}
for {
:= .getRune()
if == eof {
break
}
if !() {
.UnreadRune()
break
}
.buf.writeRune()
}
return .buf
}
var complexError = errors.New("syntax error scanning complex number")
var boolError = errors.New("syntax error scanning boolean")
func ( string, rune) int {
for , := range {
if == {
return
}
}
return -1
}
switch .getRune() {
case '0':
return false
case '1':
return true
case 't', 'T':
if .accept("rR") && (!.accept("uU") || !.accept("eE")) {
.error(boolError)
}
return true
case 'f', 'F':
if .accept("aA") && (!.accept("lL") || !.accept("sS") || !.accept("eE")) {
.error(boolError)
}
return false
}
return false
}
const (
binaryDigits = "01"
octalDigits = "01234567"
decimalDigits = "0123456789"
hexadecimalDigits = "0123456789aAbBcCdDeEfF"
sign = "+-"
period = "."
exponent = "eEpP"
)
func ( *ss) ( rune) ( int, string) {
.okVerb(, "bdoUxXv", "integer") // sets s.err
= 10
= decimalDigits
switch {
case 'b':
= 2
= binaryDigits
case 'o':
= 8
= octalDigits
case 'x', 'X', 'U':
= 16
= hexadecimalDigits
}
return
}
switch {
case .peek("bB"):
.consume("bB", true)
return 0, binaryDigits + "_", true
case .peek("oO"):
.consume("oO", true)
return 0, octalDigits + "_", true
case .peek("xX"):
.consume("xX", true)
return 0, hexadecimalDigits + "_", true
default:
return 0, octalDigits + "_", true
}
}
func ( *ss) ( rune, int) int64 {
if == 'c' {
return .scanRune()
}
.SkipSpace()
.notEOF()
, := .getBase()
:= false
if == 'U' {
if !.consume("U", false) || !.consume("+", false) {
.errorString("bad unicode format ")
}
} else {
.accept(sign) // If there's a sign, it will be left in the token buffer.
if == 'v' {
, , = .scanBasePrefix()
}
}
:= .scanNumber(, )
, := strconv.ParseInt(, , 64)
if != nil {
.error()
}
:= uint()
:= ( << (64 - )) >> (64 - )
if != {
.errorString("integer overflow on token " + )
}
return
}
func ( *ss) ( rune, int) uint64 {
if == 'c' {
return uint64(.scanRune())
}
.SkipSpace()
.notEOF()
, := .getBase()
:= false
if == 'U' {
if !.consume("U", false) || !.consume("+", false) {
.errorString("bad unicode format ")
}
} else if == 'v' {
, , = .scanBasePrefix()
}
:= .scanNumber(, )
, := strconv.ParseUint(, , 64)
if != nil {
.error()
}
:= uint()
:= ( << (64 - )) >> (64 - )
if != {
.errorString("unsigned integer overflow on token " + )
}
return
}
if .accept("iI") && .accept("nN") && .accept("fF") {
return string(.buf)
}
:= decimalDigits + "_"
:= exponent
if .accept("0") && .accept("xX") {
= hexadecimalDigits + "_"
= "pP"
for .accept() {
for .accept() {
}
for .accept(decimalDigits + "_") {
}
}
return string(.buf)
}
:= .accept("(")
= .floatToken()
if !.accept("+-") {
.error(complexError)
:= string(.buf)
= .floatToken()
if !.accept("i") {
.error(complexError)
}
if && !.accept(")") {
.error(complexError)
}
return , +
}
func ( string) bool {
for := 0; < len(); ++ {
if [] == 'x' || [] == 'X' {
return true
}
}
return false
}
, := strconv.ParseFloat([:], )
func ( *ss) ( rune, int) complex128 {
if !.okVerb(, floatVerbs, "complex") {
return 0
}
.SkipSpace()
.notEOF()
, := .complexTokens()
:= .convertFloat(, /2)
:= .convertFloat(, /2)
return complex(, )
}
for {
:= .mustReadRune()
if == {
break
}
.buf.writeRune()
}
return string(.buf)
.buf.writeByte('"')
for {
:= .mustReadRune()
.buf.writeRune()
.buf.writeRune(.mustReadRune())
} else if == '"' {
break
}
}
, := strconv.Unquote(string(.buf))
if != nil {
.error()
}
return
default:
.errorString("expected quoted string")
}
return ""
}
func ( *ss) () ( byte, bool) {
:= .getRune()
if == eof {
return
}
, := hexDigit()
if ! {
.UnreadRune()
return
}
, := hexDigit(.mustReadRune())
if ! {
.errorString("illegal hex digit")
return
}
return byte(<<4 | ), true
}
func ( *ss) () string {
.notEOF()
for {
, := .hexByte()
if ! {
break
}
.buf.writeByte()
}
if len(.buf) == 0 {
.errorString("no hex data for %x string")
return ""
}
return string(.buf)
}
const (
floatVerbs = "beEfFgGv"
hugeWid = 1 << 30
intBits = 32 << (^uint(0) >> 63)
uintptrBits = 32 << (^uintptr(0) >> 63)
)
func ( *ss) () {
.SkipSpace()
.notEOF()
if !.accept("%") {
.errorString("missing literal %")
}
}
if , := .(Scanner); {
= .Scan(, )
if != nil {
if == io.EOF {
= io.ErrUnexpectedEOF
}
.error()
}
return
}
switch v := .(type) {
case *bool:
* = .scanBool()
case *complex64:
* = complex64(.scanComplex(, 64))
case *complex128:
* = .scanComplex(, 128)
case *int:
* = int(.scanInt(, intBits))
case *int8:
* = int8(.scanInt(, 8))
case *int16:
* = int16(.scanInt(, 16))
case *int32:
* = int32(.scanInt(, 32))
case *int64:
* = .scanInt(, 64)
case *uint:
* = uint(.scanUint(, intBits))
case *uint8:
* = uint8(.scanUint(, 8))
case *uint16:
* = uint16(.scanUint(, 16))
case *uint32:
* = uint32(.scanUint(, 32))
case *uint64:
* = .scanUint(, 64)
case *uintptr:
case *float32:
if .okVerb(, floatVerbs, "float32") {
.SkipSpace()
.notEOF()
* = float32(.convertFloat(.floatToken(), 32))
}
case *float64:
if .okVerb(, floatVerbs, "float64") {
.SkipSpace()
.notEOF()
* = .convertFloat(.floatToken(), 64)
}
case *string:
* = .convertString()
* = []byte(.convertString())
default:
:= reflect.ValueOf()
:=
if .Kind() != reflect.Ptr {
.errorString("type not a pointer: " + .Type().String())
return
}
switch := .Elem(); .Kind() {
case reflect.Bool:
.SetBool(.scanBool())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
.SetInt(.scanInt(, .Type().Bits()))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
.SetUint(.scanUint(, .Type().Bits()))
case reflect.String:
.SetString(.convertString())
:= .Type()
if .Elem().Kind() != reflect.Uint8 {
.errorString("can't scan type: " + .Type().String())
}
:= .convertString()
.Set(reflect.MakeSlice(, len(), len()))
for := 0; < len(); ++ {
.Index().SetUint(uint64([]))
}
case reflect.Float32, reflect.Float64:
.SkipSpace()
.notEOF()
.SetFloat(.convertFloat(.floatToken(), .Type().Bits()))
case reflect.Complex64, reflect.Complex128:
.SetComplex(.scanComplex(, .Type().Bits()))
default:
.errorString("can't scan type: " + .Type().String())
}
}
}
func ( *ss) ( []interface{}) ( int, error) {
defer errorHandler(&)
for , := range {
.scanOne('v', )
++
if .nlIsEnd {
for {
:= .getRune()
if == '\n' || == eof {
break
}
if !isSpace() {
.errorString("expected newline")
break
}
}
}
return
}
if isSpace() {
:= 0
:= false
for isSpace() && < len() {
if == '\n' {
++
= false
} else {
= true
}
+=
, = utf8.DecodeRuneInString([:])
}
for := 0; < ; ++ {
:= .getRune()
for isSpace() && != '\n' {
= .getRune()
}
if != '\n' && != eof {
.errorString("newline in format does not match input")
}
}
if {
:= .getRune()
if !isSpace() && != eof {
.errorString("expected space in input to match format")
}
if == '\n' {
.errorString("newline in input does not match format")
}
}
for isSpace() && != '\n' {
= .getRune()
}
if != eof {
.UnreadRune()
}
}
continue
}
if + == len() {
.errorString("missing verb: % at end of format string")
, := utf8.DecodeRuneInString([+:]) // will not match % if string is empty
if != '%' {
return
}
+= // skip the first %
}
:= .mustReadRune()
if != {
.UnreadRune()
return -1
}
+=
}
return
}
func ( *ss) ( string, []interface{}) ( int, error) {
defer errorHandler(&)
for := 0; <= ; {
:= .advance([:])
if > 0 {
+=
continue
if < 0 {
.errorString("input does not match format")
break
}
++ // % is one byte
var bool
.maxWid, , = parsenum(, , )
if ! {
.maxWid = hugeWid
}
, := utf8.DecodeRuneInString([:])
+=
if != 'c' {
.SkipSpace()
}
if == '%' {
.scanPercent()
continue // Do not consume an argument.
}
.argLimit = .limit
if := .count + .maxWid; < .argLimit {
.argLimit =
}
if >= len() { // out of operands
.errorString("too few operands for format '%" + [-:] + "'")
break
}
:= []
.scanOne(, )
++
.argLimit = .limit
}
if < len() {
.errorString("too many operands")
}
return
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |