config/shconf/scan.go
func (s *Scanner) Scan() bool {
	var thisRune rune
	var n int
	var err error

	for s.line++; ; s.line++ {
		// Skip leading spaces.
		for thisRune, n, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
			if err != nil {
				s.err = err
				return false
			}

			if thisRune == '\n' {
				s.line++
				continue
			}
			if !unicode.IsSpace(thisRune) {
				break
			}
		}

		// Skip line comment and section.
		if thisRune == '#' || thisRune == '[' {
			if _, err = s.buf.ReadBytes('\n'); err != nil {
				s.err = err
				return false
			}
			continue
		}
		break
	}

	if thisRune == '=' {
		s.err = keyError(s.line)
		return false
	}

	var key, value, separator []rune

	// Get key

	for ; ; thisRune, n, err = s.buf.ReadRune() {
		if err != nil {
			if err != io.EOF {
				s.err = err
			} else {
				s.err = valueError(s.line)
			}
			return false
		}

		// The separator charater could the the equal sign or space.
		if thisRune == '=' || unicode.IsSpace(thisRune) {
			break
		}

		if n > 1 || !isValidChar(thisRune) {
			s.err = noASCIIKeyError(s.line)
			return false
		}
		key = append(key, thisRune)
	}

	// Skip spaces before and after of the separator character.

	if unicode.IsSpace(thisRune) {
		separator = append(separator, thisRune)

		for thisRune, _, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
			if err != nil {
				if err != io.EOF {
					s.err = err
				} else {
					s.err = valueError(s.line)
				}
				return false
			}

			if !unicode.IsSpace(thisRune) {
				break
			}
			separator = append(separator, thisRune)
		}
	}
	if thisRune == '=' {
		separator = append(separator, thisRune)

		if thisRune, _, err = s.buf.ReadRune(); err != nil {
			if err != io.EOF {
				s.err = err
			} else {
				s.err = valueError(s.line)
			}
			return false
		}
	}
	if unicode.IsSpace(thisRune) {
		separator = append(separator, thisRune)

		for thisRune, _, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
			if err != nil {
				if err != io.EOF {
					s.err = err
				} else {
					s.err = valueError(s.line)
				}
				return false
			}

			if !unicode.IsSpace(thisRune) {
				break
			}
			separator = append(separator, thisRune)
		}
	}

	// Get value

	var valueIsString, valueInDQuote bool
	var lastRune rune

	if thisRune == '"' { // The value is between double quotes
		valueIsString = true
		valueInDQuote = true
	} else if thisRune == '\'' { // between single quotes
		valueIsString = true
	} else {
		value = append(value, thisRune)
	}

	for thisRune, _, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
		if err != nil {
			if err != io.EOF {
				s.err = err
				return false
			}

			if valueIsString {
				s.err = openQuoteError(s.line)
				return false
			}
			s.err = err
			break
		}

		if valueIsString {
			if valueInDQuote {
				if thisRune == '"' && lastRune != '\\' {
					break
				}
			} else if thisRune == '\'' && lastRune != '\\' {
				break
			}
			lastRune = thisRune // To checking if it is a quote escaped.
			value = append(value, thisRune)

		} else {
			if unicode.IsSpace(thisRune) {
				break
			}
			value = append(value, thisRune)
		}
	}

	// Sanity check
	if thisRune != '\n' && thisRune != '\r' {
		doCheck := true
		last, _, err := s.buf.ReadLine()
		if err != nil {
			if err != io.EOF {
				s.err = err
				return false
			} else {
				doCheck = false
			}
		}

		if doCheck {
			for _, char := range last {
				if unicode.IsSpace(rune(char)) {
					continue
				} else if char == '#' {
					break
				} else {
					s.err = extraCharError(s.line)
					return false
				}
			}
		}
	}

	// Store key and value

	var bufKey, bufValue, bufSep bytes.Buffer
	var bytes []byte

	for _, r := range key {
		bytes = make([]byte, utf8.RuneLen(r))
		utf8.EncodeRune(bytes, r)
		bufKey.Write(bytes)
	}
	s.key = bufKey.Bytes()

	for _, r := range value {
		bytes = make([]byte, utf8.RuneLen(r))
		utf8.EncodeRune(bytes, r)
		bufValue.Write(bytes)
	}
	s.value = bufValue.Bytes()

	// Store separator character
	if s.separator == nil {
		for _, r := range separator {
			bytes = make([]byte, utf8.RuneLen(r))
			utf8.EncodeRune(bytes, r)
			bufSep.Write(bytes)
		}
		s.separator = bufSep.Bytes()
	}

	return true
}
func (s *Scanner) Scan() bool {
	var thisRune rune
	var n int
	var err error

	for s.line++; ; s.line++ {
		// Skip leading spaces.
		for thisRune, n, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
			if err != nil {
				s.err = err
				return false
			}

			if thisRune == '\n' {
				s.line++
				continue
			}
			if !unicode.IsSpace(thisRune) {
				break
			}
		}

		// Skip line comment and section.
		if thisRune == '#' || thisRune == '[' {
			if _, err = s.buf.ReadBytes('\n'); err != nil {
				s.err = err
				return false
			}
			continue
		}
		break
	}

	if thisRune == '=' {
		s.err = keyError(s.line)
		return false
	}

	var key, value, separator []rune

	// Get key

	for ; ; thisRune, n, err = s.buf.ReadRune() {
		if err != nil {
			if err != io.EOF {
				s.err = err
			} else {
				s.err = valueError(s.line)
			}
			return false
		}

		// The separator charater could the the equal sign or space.
		if thisRune == '=' || unicode.IsSpace(thisRune) {
			break
		}

		if n > 1 || !isValidChar(thisRune) {
			s.err = noASCIIKeyError(s.line)
			return false
		}
		key = append(key, thisRune)
	}

	// Skip spaces before and after of the separator character.

	if unicode.IsSpace(thisRune) {
		separator = append(separator, thisRune)

		for thisRune, _, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
			if err != nil {
				if err != io.EOF {
					s.err = err
				} else {
					s.err = valueError(s.line)
				}
				return false
			}

			if !unicode.IsSpace(thisRune) {
				break
			}
			separator = append(separator, thisRune)
		}
	}
	if thisRune == '=' {
		separator = append(separator, thisRune)

		if thisRune, _, err = s.buf.ReadRune(); err != nil {
			if err != io.EOF {
				s.err = err
			} else {
				s.err = valueError(s.line)
			}
			return false
		}
	}
	if unicode.IsSpace(thisRune) {
		separator = append(separator, thisRune)

		for thisRune, _, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
			if err != nil {
				if err != io.EOF {
					s.err = err
				} else {
					s.err = valueError(s.line)
				}
				return false
			}

			if !unicode.IsSpace(thisRune) {
				break
			}
			separator = append(separator, thisRune)
		}
	}

	// Get value

	var valueIsString, valueInDQuote bool
	var lastRune rune

	if thisRune == '"' { // The value is between double quotes
		valueIsString = true
		valueInDQuote = true
	} else if thisRune == '\'' { // between single quotes
		valueIsString = true
	} else {
		value = append(value, thisRune)
	}

	for thisRune, _, err = s.buf.ReadRune(); ; thisRune, _, err = s.buf.ReadRune() {
		if err != nil {
			if err != io.EOF {
				s.err = err
				return false
			}

			if valueIsString {
				s.err = openQuoteError(s.line)
				return false
			}
			s.err = err
			break
		}

		if valueIsString {
			if valueInDQuote {
				if thisRune == '"' && lastRune != '\\' {
					break
				}
			} else if thisRune == '\'' && lastRune != '\\' {
				break
			}
			lastRune = thisRune // To checking if it is a quote escaped.
			value = append(value, thisRune)

		} else {
			if unicode.IsSpace(thisRune) {
				break
			}
			value = append(value, thisRune)
		}
	}

	// Sanity check
	if thisRune != '\n' && thisRune != '\r' {
		doCheck := true
		last, _, err := s.buf.ReadLine()
		if err != nil {
			if err != io.EOF {
				s.err = err
				return false
			} else {
				doCheck = false
			}
		}

		if doCheck {
			for _, char := range last {
				if unicode.IsSpace(rune(char)) {
					continue
				} else if char == '#' {
					break
				} else {
					s.err = extraCharError(s.line)
					return false
				}
			}
		}
	}

	// Store key and value

	var bufKey, bufValue, bufSep bytes.Buffer
	var bytes []byte

	for _, r := range key {
		bytes = make([]byte, utf8.RuneLen(r))
		utf8.EncodeRune(bytes, r)
		bufKey.Write(bytes)
	}
	s.key = bufKey.Bytes()

	for _, r := range value {
		bytes = make([]byte, utf8.RuneLen(r))
		utf8.EncodeRune(bytes, r)
		bufValue.Write(bytes)
	}
	s.value = bufValue.Bytes()

	// Store separator character
	if s.separator == nil {
		for _, r := range separator {
			bytes = make([]byte, utf8.RuneLen(r))
			utf8.EncodeRune(bytes, r)
			bufSep.Write(bytes)
		}
		s.separator = bufSep.Bytes()
	}

	return true
}
func ( s * Scanner ) Scan ( ) bool { var thisRune rune var n int var err error for s . line ++ ; ; s . line ++ { // Skip leading spaces. for thisRune , n , err = s . buf . ReadRune ( ) ; ; thisRune , _ , err = s . buf . ReadRune ( ) { if err != nil { s . err = err return false } if thisRune == '\n' { s . line ++ continue } if ! unicode . IsSpace ( thisRune ) { break } } // Skip line comment and section. if thisRune == '#' || thisRune == '[' { if _ , err = s . buf . ReadBytes ( '\n' ) ; err != nil { s . err = err return false } continue } break } if thisRune == '=' { s . err = keyError ( s . line ) return false } var key , value , separator [ ] rune // Get key for ; ; thisRune , n , err = s . buf . ReadRune ( ) { if err != nil { if err != io . EOF { s . err = err } else { s . err = valueError ( s . line ) } return false } // The separator charater could the the equal sign or space. if thisRune == '=' || unicode . IsSpace ( thisRune ) { break } if n > 1 || ! isValidChar ( thisRune ) { s . err = noASCIIKeyError ( s . line ) return false } key = append ( key , thisRune ) } // Skip spaces before and after of the separator character. if unicode . IsSpace ( thisRune ) { separator = append ( separator , thisRune ) for thisRune , _ , err = s . buf . ReadRune ( ) ; ; thisRune , _ , err = s . buf . ReadRune ( ) { if err != nil { if err != io . EOF { s . err = err } else { s . err = valueError ( s . line ) } return false } if ! unicode . IsSpace ( thisRune ) { break } separator = append ( separator , thisRune ) } } if thisRune == '=' { separator = append ( separator , thisRune ) if thisRune , _ , err = s . buf . ReadRune ( ) ; err != nil { if err != io . EOF { s . err = err } else { s . err = valueError ( s . line ) } return false } } if unicode . IsSpace ( thisRune ) { separator = append ( separator , thisRune ) for thisRune , _ , err = s . buf . ReadRune ( ) ; ; thisRune , _ , err = s . buf . ReadRune ( ) { if err != nil { if err != io . EOF { s . err = err } else { s . err = valueError ( s . line ) } return false } if ! unicode . IsSpace ( thisRune ) { break } separator = append ( separator , thisRune ) } } // Get value var valueIsString , valueInDQuote bool var lastRune rune if thisRune == '"' { // The value is between double quotes valueIsString = true valueInDQuote = true } else if thisRune == '\'' { // between single quotes valueIsString = true } else { value = append ( value , thisRune ) } for thisRune , _ , err = s . buf . ReadRune ( ) ; ; thisRune , _ , err = s . buf . ReadRune ( ) { if err != nil { if err != io . EOF { s . err = err return false } if valueIsString { s . err = openQuoteError ( s . line ) return false } s . err = err break } if valueIsString { if valueInDQuote { if thisRune == '"' && lastRune != '\\' { break } } else if thisRune == '\'' && lastRune != '\\' { break } lastRune = thisRune // To checking if it is a quote escaped. value = append ( value , thisRune ) } else { if unicode . IsSpace ( thisRune ) { break } value = append ( value , thisRune ) } } // Sanity check if thisRune != '\n' && thisRune != '\r' { doCheck := true last , _ , err := s . buf . ReadLine ( ) if err != nil { if err != io . EOF { s . err = err return false } else { doCheck = false } } if doCheck { for _ , char := range last { if unicode . IsSpace ( rune ( char ) ) { continue } else if char == '#' { break } else { s . err = extraCharError ( s . line ) return false } } } } // Store key and value var bufKey , bufValue , bufSep bytes . Buffer var bytes [ ] byte for _ , r := range key { bytes = make ( [ ] byte , utf8 . RuneLen ( r ) ) utf8 . EncodeRune ( bytes , r ) bufKey . Write ( bytes ) } s . key = bufKey . Bytes ( ) for _ , r := range value { bytes = make ( [ ] byte , utf8 . RuneLen ( r ) ) utf8 . EncodeRune ( bytes , r ) bufValue . Write ( bytes ) } s . value = bufValue . Bytes ( ) // Store separator character if s . separator == nil { for _ , r := range separator { bytes = make ( [ ] byte , utf8 . RuneLen ( r ) ) utf8 . EncodeRune ( bytes , r ) bufSep . Write ( bytes ) } s . separator = bufSep . Bytes ( ) } return true }
// Scan advances the Scanner to the next tokens, which will then be available
// through the Bytes or Text method. It returns false when the scan stops, either
// by reaching the end of the input or an error. After Scan returns false, the Err
// method will return any error that occurred during scanning, except that if it
// was io.EOF, Err will return nil.
Scan advances the Scanner to the next tokens which will then be available through the Bytes or Text method . It returns false when the scan stops either by reaching the end of the input or an error . After Scan returns false the Err method will return any error that occurred during scanning except that if it was io . EOF Err will return nil .