gonum.org/v1/gonum@v0.14.0/graph/formats/dot/internal/util/litconv.go (about)

     1  // Code generated by gocc; DO NOT EDIT.
     2  
     3  // This file is dual licensed under CC0 and The Gonum License.
     4  //
     5  // Copyright ©2017 The Gonum Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  //
     9  // Copyright ©2017 Robin Eklind.
    10  // This file is made available under a Creative Commons CC0 1.0
    11  // Universal Public Domain Dedication.
    12  
    13  package util
    14  
    15  import (
    16  	"fmt"
    17  	"strconv"
    18  	"unicode"
    19  	"unicode/utf8"
    20  )
    21  
    22  // Interface.
    23  
    24  // RuneValue will convert the literal value of a scanned token to a rune.
    25  func RuneValue(lit []byte) rune {
    26  	if lit[1] == '\\' {
    27  		return escapeCharVal(lit)
    28  	}
    29  	r, size := utf8.DecodeRune(lit[1:])
    30  	if size != len(lit)-2 {
    31  		panic(fmt.Sprintf("Error decoding rune. Lit: %s, rune: %d, size%d\n", lit, r, size))
    32  	}
    33  	return r
    34  }
    35  
    36  // UintValue will attempt to parse a byte-slice as a signed base-10 64-bit integer.
    37  func IntValue(lit []byte) (int64, error) {
    38  	return strconv.ParseInt(string(lit), 10, 64)
    39  }
    40  
    41  // UintValue will attempt to parse a byte-slice as an unsigned base-10 64-bit integer.
    42  func UintValue(lit []byte) (uint64, error) {
    43  	return strconv.ParseUint(string(lit), 10, 64)
    44  }
    45  
    46  // Helpers.
    47  func escapeCharVal(lit []byte) rune {
    48  	var i, base, max uint32
    49  	offset := 2
    50  	switch lit[offset] {
    51  	case 'a':
    52  		return '\a'
    53  	case 'b':
    54  		return '\b'
    55  	case 'f':
    56  		return '\f'
    57  	case 'n':
    58  		return '\n'
    59  	case 'r':
    60  		return '\r'
    61  	case 't':
    62  		return '\t'
    63  	case 'v':
    64  		return '\v'
    65  	case '\\':
    66  		return '\\'
    67  	case '\'':
    68  		return '\''
    69  	case '0', '1', '2', '3', '4', '5', '6', '7':
    70  		i, base, max = 3, 8, 255
    71  	case 'x':
    72  		i, base, max = 2, 16, 255
    73  		offset++
    74  	case 'u':
    75  		i, base, max = 4, 16, unicode.MaxRune
    76  		offset++
    77  	case 'U':
    78  		i, base, max = 8, 16, unicode.MaxRune
    79  		offset++
    80  	default:
    81  		panic(fmt.Sprintf("Error decoding character literal: %s\n", lit))
    82  	}
    83  
    84  	var x uint32
    85  	for ; i > 0 && offset < len(lit)-1; i-- {
    86  		ch, size := utf8.DecodeRune(lit[offset:])
    87  		offset += size
    88  		d := uint32(digitVal(ch))
    89  		if d >= base {
    90  			panic(fmt.Sprintf("charVal(%s): illegal character (%c) in escape sequence. size=%d, offset=%d", lit, ch, size, offset))
    91  		}
    92  		x = x*base + d
    93  	}
    94  	if x > max || 0xD800 <= x && x < 0xE000 {
    95  		panic(fmt.Sprintf("Error decoding escape char value. Lit:%s, offset:%d, escape sequence is invalid Unicode code point\n", lit, offset))
    96  	}
    97  
    98  	return rune(x)
    99  }
   100  
   101  func digitVal(ch rune) int {
   102  	switch {
   103  	case '0' <= ch && ch <= '9':
   104  		return int(ch) - '0'
   105  	case 'a' <= ch && ch <= 'f':
   106  		return int(ch) - 'a' + 10
   107  	case 'A' <= ch && ch <= 'F':
   108  		return int(ch) - 'A' + 10
   109  	}
   110  	return 16 // larger than any legal digit val
   111  }