src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

number_helper.go (2636B)


      1 package ini
      2 
      3 import (
      4 	"bytes"
      5 	"fmt"
      6 	"strconv"
      7 )
      8 
      9 const (
     10 	none = numberFormat(iota)
     11 	binary
     12 	octal
     13 	decimal
     14 	hex
     15 	exponent
     16 )
     17 
     18 type numberFormat int
     19 
     20 // numberHelper is used to dictate what format a number is in
     21 // and what to do for negative values. Since -1e-4 is a valid
     22 // number, we cannot just simply check for duplicate negatives.
     23 type numberHelper struct {
     24 	numberFormat numberFormat
     25 
     26 	negative         bool
     27 	negativeExponent bool
     28 }
     29 
     30 func (b numberHelper) Exists() bool {
     31 	return b.numberFormat != none
     32 }
     33 
     34 func (b numberHelper) IsNegative() bool {
     35 	return b.negative || b.negativeExponent
     36 }
     37 
     38 func (b *numberHelper) Determine(c rune) error {
     39 	if b.Exists() {
     40 		return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c)))
     41 	}
     42 
     43 	switch c {
     44 	case 'b':
     45 		b.numberFormat = binary
     46 	case 'o':
     47 		b.numberFormat = octal
     48 	case 'x':
     49 		b.numberFormat = hex
     50 	case 'e', 'E':
     51 		b.numberFormat = exponent
     52 	case '-':
     53 		if b.numberFormat != exponent {
     54 			b.negative = true
     55 		} else {
     56 			b.negativeExponent = true
     57 		}
     58 	case '.':
     59 		b.numberFormat = decimal
     60 	default:
     61 		return NewParseError(fmt.Sprintf("invalid number character: %v", string(c)))
     62 	}
     63 
     64 	return nil
     65 }
     66 
     67 func (b numberHelper) CorrectByte(c rune) bool {
     68 	switch {
     69 	case b.numberFormat == binary:
     70 		if !isBinaryByte(c) {
     71 			return false
     72 		}
     73 	case b.numberFormat == octal:
     74 		if !isOctalByte(c) {
     75 			return false
     76 		}
     77 	case b.numberFormat == hex:
     78 		if !isHexByte(c) {
     79 			return false
     80 		}
     81 	case b.numberFormat == decimal:
     82 		if !isDigit(c) {
     83 			return false
     84 		}
     85 	case b.numberFormat == exponent:
     86 		if !isDigit(c) {
     87 			return false
     88 		}
     89 	case b.negativeExponent:
     90 		if !isDigit(c) {
     91 			return false
     92 		}
     93 	case b.negative:
     94 		if !isDigit(c) {
     95 			return false
     96 		}
     97 	default:
     98 		if !isDigit(c) {
     99 			return false
    100 		}
    101 	}
    102 
    103 	return true
    104 }
    105 
    106 func (b numberHelper) Base() int {
    107 	switch b.numberFormat {
    108 	case binary:
    109 		return 2
    110 	case octal:
    111 		return 8
    112 	case hex:
    113 		return 16
    114 	default:
    115 		return 10
    116 	}
    117 }
    118 
    119 func (b numberHelper) String() string {
    120 	buf := bytes.Buffer{}
    121 	i := 0
    122 
    123 	switch b.numberFormat {
    124 	case binary:
    125 		i++
    126 		buf.WriteString(strconv.Itoa(i) + ": binary format\n")
    127 	case octal:
    128 		i++
    129 		buf.WriteString(strconv.Itoa(i) + ": octal format\n")
    130 	case hex:
    131 		i++
    132 		buf.WriteString(strconv.Itoa(i) + ": hex format\n")
    133 	case exponent:
    134 		i++
    135 		buf.WriteString(strconv.Itoa(i) + ": exponent format\n")
    136 	default:
    137 		i++
    138 		buf.WriteString(strconv.Itoa(i) + ": integer format\n")
    139 	}
    140 
    141 	if b.negative {
    142 		i++
    143 		buf.WriteString(strconv.Itoa(i) + ": negative format\n")
    144 	}
    145 
    146 	if b.negativeExponent {
    147 		i++
    148 		buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n")
    149 	}
    150 
    151 	return buf.String()
    152 }