summaryrefslogtreecommitdiff
path: root/vendor/modernc.org/libc/scanf.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/modernc.org/libc/scanf.go')
-rw-r--r--vendor/modernc.org/libc/scanf.go198
1 files changed, 192 insertions, 6 deletions
diff --git a/vendor/modernc.org/libc/scanf.go b/vendor/modernc.org/libc/scanf.go
index ead0830e8..cc35da358 100644
--- a/vendor/modernc.org/libc/scanf.go
+++ b/vendor/modernc.org/libc/scanf.go
@@ -5,7 +5,8 @@
package libc // import "modernc.org/libc"
import (
- "strings"
+ "io"
+ "strconv"
"unsafe"
)
@@ -15,7 +16,7 @@ import (
// be either of the following: input failure, meaning that input characters
// were unavailable, or matching failure, meaning that the input was
// inappropriate.
-func scanf(r *strings.Reader, format, args uintptr) (nvalues int32) {
+func scanf(r io.ByteScanner, format, args uintptr) (nvalues int32) {
// var src []byte //TODO-
var ok bool
out:
@@ -75,7 +76,7 @@ out:
return -1 // stdio.EOF but not defined for windows
}
-func scanfConversion(r *strings.Reader, format uintptr, args *uintptr) (_ uintptr, nvalues int, match bool) {
+func scanfConversion(r io.ByteScanner, format uintptr, args *uintptr) (_ uintptr, nvalues int, match bool) {
format++ // '%'
// Each conversion specification in format begins with either the character '%'
@@ -157,7 +158,7 @@ flags:
break dec
}
- panic(todo("", err))
+ return 0, 0, false
}
if allowSign {
@@ -301,7 +302,38 @@ flags:
// Matches an optionally signed floating-point number; the next pointer must be
// a pointer to float.
format++
- panic(todo(""))
+ skipReaderWhiteSpace(r)
+ seq := fpLiteral(r)
+ if len(seq) == 0 {
+ return 0, 0, false
+ }
+
+ var neg bool
+ switch seq[0] {
+ case '+':
+ seq = seq[1:]
+ case '-':
+ neg = true
+ seq = seq[1:]
+ }
+ n, err := strconv.ParseFloat(string(seq), 64)
+ if err != nil {
+ panic(todo("", err))
+ }
+
+ arg := VaUintptr(args)
+ if neg {
+ n = -n
+ }
+ switch mod {
+ case modNone:
+ *(*float32)(unsafe.Pointer(arg)) = float32(n)
+ case modL:
+ *(*float64)(unsafe.Pointer(arg)) = n
+ default:
+ panic(todo("", mod, neg, n))
+ }
+ return format, 1, true
case 's':
// Matches a sequence of non-white-space characters; the next pointer must be
// a pointer to the initial element of a character array that is long enough to
@@ -414,7 +446,7 @@ flags:
return format, nvalues, match
}
-func skipReaderWhiteSpace(r *strings.Reader) error {
+func skipReaderWhiteSpace(r io.ByteScanner) error {
for {
c, err := r.ReadByte()
if err != nil {
@@ -441,3 +473,157 @@ func skipWhiteSpace(s uintptr) uintptr {
}
}
}
+
+// [-+]?([0-9]*[.])?[0-9]+([eE][-+]?\d+)?
+func fpLiteral(rd io.ByteScanner) (seq []byte) {
+ const endOfText = 0x110000
+ var pos, width, length int
+
+ defer func() {
+ if len(seq) > length {
+ rd.UnreadByte()
+ seq = seq[:len(seq)-1]
+ }
+ }()
+
+ var r rune
+ step := func(pos int) (rune, int) {
+ b, err := rd.ReadByte()
+ if err != nil {
+ return endOfText, 0
+ }
+
+ seq = append(seq, b)
+ return rune(b), 1
+ }
+ move := func() {
+ pos += width
+ if r != endOfText {
+ r, width = step(pos + width)
+ }
+ }
+ accept := func(x rune) bool {
+ if r == x {
+ move()
+ return true
+ }
+ return false
+ }
+ accept2 := func(x rune) bool {
+ if r <= x {
+ move()
+ return true
+ }
+ return false
+ }
+ r = endOfText
+ width = 0
+ r, width = step(pos)
+ if accept('.') {
+ goto l7
+ }
+ if accept('+') {
+ goto l30
+ }
+ if accept('-') {
+ goto l30
+ }
+ if r < '0' {
+ goto l4out
+ }
+ if accept2('9') {
+ goto l35
+ }
+l4out:
+ return seq
+l7:
+ if r < '0' {
+ goto l7out
+ }
+ if accept2('9') {
+ goto l10
+ }
+l7out:
+ return seq
+l10:
+ length = pos
+ if accept('E') {
+ goto l18
+ }
+ if accept('e') {
+ goto l18
+ }
+ if r < '0' {
+ goto l15out
+ }
+ if accept2('9') {
+ goto l10
+ }
+l15out:
+ return seq
+l18:
+ if accept('+') {
+ goto l23
+ }
+ if accept('-') {
+ goto l23
+ }
+ if r < '0' {
+ goto l20out
+ }
+ if accept2('9') {
+ goto l26
+ }
+l20out:
+ return seq
+l23:
+ if r < '0' {
+ goto l23out
+ }
+ if accept2('9') {
+ goto l26
+ }
+l23out:
+ return seq
+l26:
+ length = pos
+ if r < '0' {
+ goto l27out
+ }
+ if accept2('9') {
+ goto l26
+ }
+l27out:
+ return seq
+l30:
+ if accept('.') {
+ goto l7
+ }
+ if r < '0' {
+ goto l32out
+ }
+ if accept2('9') {
+ goto l35
+ }
+l32out:
+ return seq
+l35:
+ length = pos
+ if accept('.') {
+ goto l7
+ }
+ if accept('E') {
+ goto l18
+ }
+ if accept('e') {
+ goto l18
+ }
+ if r < '0' {
+ goto l42out
+ }
+ if accept2('9') {
+ goto l35
+ }
+l42out:
+ return seq
+}