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 }