123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- package ini
- import (
- "fmt"
- )
- // getStringValue will return a quoted string and the amount
- // of bytes read
- //
- // an error will be returned if the string is not properly formatted
- func getStringValue(b []rune) (int, error) {
- if b[0] != '"' {
- return 0, NewParseError("strings must start with '\"'")
- }
- endQuote := false
- i := 1
- for ; i < len(b) && !endQuote; i++ {
- if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
- endQuote = true
- break
- } else if escaped {
- /*c, err := getEscapedByte(b[i])
- if err != nil {
- return 0, err
- }
- b[i-1] = c
- b = append(b[:i], b[i+1:]...)
- i--*/
- continue
- }
- }
- if !endQuote {
- return 0, NewParseError("missing '\"' in string value")
- }
- return i + 1, nil
- }
- // getBoolValue will return a boolean and the amount
- // of bytes read
- //
- // an error will be returned if the boolean is not of a correct
- // value
- func getBoolValue(b []rune) (int, error) {
- if len(b) < 4 {
- return 0, NewParseError("invalid boolean value")
- }
- n := 0
- for _, lv := range literalValues {
- if len(lv) > len(b) {
- continue
- }
- if isLitValue(lv, b) {
- n = len(lv)
- }
- }
- if n == 0 {
- return 0, NewParseError("invalid boolean value")
- }
- return n, nil
- }
- // getNumericalValue will return a numerical string, the amount
- // of bytes read, and the base of the number
- //
- // an error will be returned if the number is not of a correct
- // value
- func getNumericalValue(b []rune) (int, int, error) {
- if !isDigit(b[0]) {
- return 0, 0, NewParseError("invalid digit value")
- }
- i := 0
- helper := numberHelper{}
- loop:
- for negativeIndex := 0; i < len(b); i++ {
- negativeIndex++
- if !isDigit(b[i]) {
- switch b[i] {
- case '-':
- if helper.IsNegative() || negativeIndex != 1 {
- return 0, 0, NewParseError("parse error '-'")
- }
- n := getNegativeNumber(b[i:])
- i += (n - 1)
- helper.Determine(b[i])
- continue
- case '.':
- if err := helper.Determine(b[i]); err != nil {
- return 0, 0, err
- }
- case 'e', 'E':
- if err := helper.Determine(b[i]); err != nil {
- return 0, 0, err
- }
- negativeIndex = 0
- case 'b':
- if helper.numberFormat == hex {
- break
- }
- fallthrough
- case 'o', 'x':
- if i == 0 && b[i] != '0' {
- return 0, 0, NewParseError("incorrect base format, expected leading '0'")
- }
- if i != 1 {
- return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i))
- }
- if err := helper.Determine(b[i]); err != nil {
- return 0, 0, err
- }
- default:
- if isWhitespace(b[i]) {
- break loop
- }
- if isNewline(b[i:]) {
- break loop
- }
- if !(helper.numberFormat == hex && isHexByte(b[i])) {
- if i+2 < len(b) && !isNewline(b[i:i+2]) {
- return 0, 0, NewParseError("invalid numerical character")
- } else if !isNewline([]rune{b[i]}) {
- return 0, 0, NewParseError("invalid numerical character")
- }
- break loop
- }
- }
- }
- }
- return helper.Base(), i, nil
- }
- // isDigit will return whether or not something is an integer
- func isDigit(b rune) bool {
- return b >= '0' && b <= '9'
- }
- func hasExponent(v []rune) bool {
- return contains(v, 'e') || contains(v, 'E')
- }
- func isBinaryByte(b rune) bool {
- switch b {
- case '0', '1':
- return true
- default:
- return false
- }
- }
- func isOctalByte(b rune) bool {
- switch b {
- case '0', '1', '2', '3', '4', '5', '6', '7':
- return true
- default:
- return false
- }
- }
- func isHexByte(b rune) bool {
- if isDigit(b) {
- return true
- }
- return (b >= 'A' && b <= 'F') ||
- (b >= 'a' && b <= 'f')
- }
- func getValue(b []rune) (int, error) {
- i := 0
- for i < len(b) {
- if isNewline(b[i:]) {
- break
- }
- if isOp(b[i:]) {
- break
- }
- valid, n, err := isValid(b[i:])
- if err != nil {
- return 0, err
- }
- if !valid {
- break
- }
- i += n
- }
- return i, nil
- }
- // getNegativeNumber will return a negative number from a
- // byte slice. This will iterate through all characters until
- // a non-digit has been found.
- func getNegativeNumber(b []rune) int {
- if b[0] != '-' {
- return 0
- }
- i := 1
- for ; i < len(b); i++ {
- if !isDigit(b[i]) {
- return i
- }
- }
- return i
- }
- // isEscaped will return whether or not the character is an escaped
- // character.
- func isEscaped(value []rune, b rune) bool {
- if len(value) == 0 {
- return false
- }
- switch b {
- case '\'': // single quote
- case '"': // quote
- case 'n': // newline
- case 't': // tab
- case '\\': // backslash
- default:
- return false
- }
- return value[len(value)-1] == '\\'
- }
- func getEscapedByte(b rune) (rune, error) {
- switch b {
- case '\'': // single quote
- return '\'', nil
- case '"': // quote
- return '"', nil
- case 'n': // newline
- return '\n', nil
- case 't': // table
- return '\t', nil
- case '\\': // backslash
- return '\\', nil
- default:
- return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
- }
- }
- func removeEscapedCharacters(b []rune) []rune {
- for i := 0; i < len(b); i++ {
- if isEscaped(b[:i], b[i]) {
- c, err := getEscapedByte(b[i])
- if err != nil {
- return b
- }
- b[i-1] = c
- b = append(b[:i], b[i+1:]...)
- i--
- }
- }
- return b
- }
|