|
Packit |
63bb0d |
package ini
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
import (
|
|
Packit |
63bb0d |
"bytes"
|
|
Packit |
63bb0d |
"fmt"
|
|
Packit |
63bb0d |
"strconv"
|
|
Packit |
63bb0d |
)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
const (
|
|
Packit |
63bb0d |
none = numberFormat(iota)
|
|
Packit |
63bb0d |
binary
|
|
Packit |
63bb0d |
octal
|
|
Packit |
63bb0d |
decimal
|
|
Packit |
63bb0d |
hex
|
|
Packit |
63bb0d |
exponent
|
|
Packit |
63bb0d |
)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type numberFormat int
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// numberHelper is used to dictate what format a number is in
|
|
Packit |
63bb0d |
// and what to do for negative values. Since -1e-4 is a valid
|
|
Packit |
63bb0d |
// number, we cannot just simply check for duplicate negatives.
|
|
Packit |
63bb0d |
type numberHelper struct {
|
|
Packit |
63bb0d |
numberFormat numberFormat
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
negative bool
|
|
Packit |
63bb0d |
negativeExponent bool
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (b numberHelper) Exists() bool {
|
|
Packit |
63bb0d |
return b.numberFormat != none
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (b numberHelper) IsNegative() bool {
|
|
Packit |
63bb0d |
return b.negative || b.negativeExponent
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (b *numberHelper) Determine(c rune) error {
|
|
Packit |
63bb0d |
if b.Exists() {
|
|
Packit |
63bb0d |
return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c)))
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
switch c {
|
|
Packit |
63bb0d |
case 'b':
|
|
Packit |
63bb0d |
b.numberFormat = binary
|
|
Packit |
63bb0d |
case 'o':
|
|
Packit |
63bb0d |
b.numberFormat = octal
|
|
Packit |
63bb0d |
case 'x':
|
|
Packit |
63bb0d |
b.numberFormat = hex
|
|
Packit |
63bb0d |
case 'e', 'E':
|
|
Packit |
63bb0d |
b.numberFormat = exponent
|
|
Packit |
63bb0d |
case '-':
|
|
Packit |
63bb0d |
if b.numberFormat != exponent {
|
|
Packit |
63bb0d |
b.negative = true
|
|
Packit |
63bb0d |
} else {
|
|
Packit |
63bb0d |
b.negativeExponent = true
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
case '.':
|
|
Packit |
63bb0d |
b.numberFormat = decimal
|
|
Packit |
63bb0d |
default:
|
|
Packit |
63bb0d |
return NewParseError(fmt.Sprintf("invalid number character: %v", string(c)))
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (b numberHelper) CorrectByte(c rune) bool {
|
|
Packit |
63bb0d |
switch {
|
|
Packit |
63bb0d |
case b.numberFormat == binary:
|
|
Packit |
63bb0d |
if !isBinaryByte(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
case b.numberFormat == octal:
|
|
Packit |
63bb0d |
if !isOctalByte(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
case b.numberFormat == hex:
|
|
Packit |
63bb0d |
if !isHexByte(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
case b.numberFormat == decimal:
|
|
Packit |
63bb0d |
if !isDigit(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
case b.numberFormat == exponent:
|
|
Packit |
63bb0d |
if !isDigit(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
case b.negativeExponent:
|
|
Packit |
63bb0d |
if !isDigit(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
case b.negative:
|
|
Packit |
63bb0d |
if !isDigit(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
default:
|
|
Packit |
63bb0d |
if !isDigit(c) {
|
|
Packit |
63bb0d |
return false
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return true
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (b numberHelper) Base() int {
|
|
Packit |
63bb0d |
switch b.numberFormat {
|
|
Packit |
63bb0d |
case binary:
|
|
Packit |
63bb0d |
return 2
|
|
Packit |
63bb0d |
case octal:
|
|
Packit |
63bb0d |
return 8
|
|
Packit |
63bb0d |
case hex:
|
|
Packit |
63bb0d |
return 16
|
|
Packit |
63bb0d |
default:
|
|
Packit |
63bb0d |
return 10
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (b numberHelper) String() string {
|
|
Packit |
63bb0d |
buf := bytes.Buffer{}
|
|
Packit |
63bb0d |
i := 0
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
switch b.numberFormat {
|
|
Packit |
63bb0d |
case binary:
|
|
Packit |
63bb0d |
i++
|
|
Packit |
63bb0d |
buf.WriteString(strconv.Itoa(i) + ": binary format\n")
|
|
Packit |
63bb0d |
case octal:
|
|
Packit |
63bb0d |
i++
|
|
Packit |
63bb0d |
buf.WriteString(strconv.Itoa(i) + ": octal format\n")
|
|
Packit |
63bb0d |
case hex:
|
|
Packit |
63bb0d |
i++
|
|
Packit |
63bb0d |
buf.WriteString(strconv.Itoa(i) + ": hex format\n")
|
|
Packit |
63bb0d |
case exponent:
|
|
Packit |
63bb0d |
i++
|
|
Packit |
63bb0d |
buf.WriteString(strconv.Itoa(i) + ": exponent format\n")
|
|
Packit |
63bb0d |
default:
|
|
Packit |
63bb0d |
i++
|
|
Packit |
63bb0d |
buf.WriteString(strconv.Itoa(i) + ": integer format\n")
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
if b.negative {
|
|
Packit |
63bb0d |
i++
|
|
Packit |
63bb0d |
buf.WriteString(strconv.Itoa(i) + ": negative format\n")
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
if b.negativeExponent {
|
|
Packit |
63bb0d |
i++
|
|
Packit |
63bb0d |
buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n")
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return buf.String()
|
|
Packit |
63bb0d |
}
|