Source file
src/fmt/scan.go
1
2
3
4
5 package fmt
6
7 import (
8 "errors"
9 "io"
10 "math"
11 "os"
12 "reflect"
13 "strconv"
14 "sync"
15 "unicode/utf8"
16 )
17
18
19
20
21 type ScanState interface {
22
23
24
25
26 ReadRune() (r rune, size int, err error)
27
28 UnreadRune() error
29
30
31
32 SkipSpace()
33
34
35
36
37
38
39
40
41 Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
42
43
44 Width() (wid int, ok bool)
45
46
47
48 Read(buf []byte) (n int, err error)
49 }
50
51
52
53
54
55 type Scanner interface {
56 Scan(state ScanState, verb rune) error
57 }
58
59
60
61
62
63 func Scan(a ...any) (n int, err error) {
64 return Fscan(os.Stdin, a...)
65 }
66
67
68
69 func Scanln(a ...any) (n int, err error) {
70 return Fscanln(os.Stdin, a...)
71 }
72
73
74
75
76
77
78
79
80 func Scanf(format string, a ...any) (n int, err error) {
81 return Fscanf(os.Stdin, format, a...)
82 }
83
84 type stringReader string
85
86 func (r *stringReader) Read(b []byte) (n int, err error) {
87 n = copy(b, *r)
88 *r = (*r)[n:]
89 if n == 0 {
90 err = io.EOF
91 }
92 return
93 }
94
95
96
97
98
99 func Sscan(str string, a ...any) (n int, err error) {
100 return Fscan((*stringReader)(&str), a...)
101 }
102
103
104
105 func Sscanln(str string, a ...any) (n int, err error) {
106 return Fscanln((*stringReader)(&str), a...)
107 }
108
109
110
111
112
113 func Sscanf(str string, format string, a ...any) (n int, err error) {
114 return Fscanf((*stringReader)(&str), format, a...)
115 }
116
117
118
119
120
121 func Fscan(r io.Reader, a ...any) (n int, err error) {
122 s, old := newScanState(r, true, false)
123 n, err = s.doScan(a)
124 s.free(old)
125 return
126 }
127
128
129
130 func Fscanln(r io.Reader, a ...any) (n int, err error) {
131 s, old := newScanState(r, false, true)
132 n, err = s.doScan(a)
133 s.free(old)
134 return
135 }
136
137
138
139
140
141 func Fscanf(r io.Reader, format string, a ...any) (n int, err error) {
142 s, old := newScanState(r, false, false)
143 n, err = s.doScanf(format, a)
144 s.free(old)
145 return
146 }
147
148
149
150 type scanError struct {
151 err error
152 }
153
154 const eof = -1
155
156
157 type ss struct {
158 rs io.RuneScanner
159 buf buffer
160 count int
161 atEOF bool
162 ssave
163 }
164
165
166
167 type ssave struct {
168 validSave bool
169 nlIsEnd bool
170 nlIsSpace bool
171 argLimit int
172 limit int
173 maxWid int
174 }
175
176
177
178
179 func (s *ss) Read(buf []byte) (n int, err error) {
180 return 0, errors.New("ScanState's Read should not be called. Use ReadRune")
181 }
182
183 func (s *ss) ReadRune() (r rune, size int, err error) {
184 if s.atEOF || s.count >= s.argLimit {
185 err = io.EOF
186 return
187 }
188
189 r, size, err = s.rs.ReadRune()
190 if err == nil {
191 s.count++
192 if s.nlIsEnd && r == '\n' {
193 s.atEOF = true
194 }
195 } else if err == io.EOF {
196 s.atEOF = true
197 }
198 return
199 }
200
201 func (s *ss) Width() (wid int, ok bool) {
202 if s.maxWid == hugeWid {
203 return 0, false
204 }
205 return s.maxWid, true
206 }
207
208
209
210 func (s *ss) getRune() (r rune) {
211 r, _, err := s.ReadRune()
212 if err != nil {
213 if err == io.EOF {
214 return eof
215 }
216 s.error(err)
217 }
218 return
219 }
220
221
222
223
224 func (s *ss) mustReadRune() (r rune) {
225 r = s.getRune()
226 if r == eof {
227 s.error(io.ErrUnexpectedEOF)
228 }
229 return
230 }
231
232 func (s *ss) UnreadRune() error {
233 s.rs.UnreadRune()
234 s.atEOF = false
235 s.count--
236 return nil
237 }
238
239 func (s *ss) error(err error) {
240 panic(scanError{err})
241 }
242
243 func (s *ss) errorString(err string) {
244 panic(scanError{errors.New(err)})
245 }
246
247 func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
248 defer func() {
249 if e := recover(); e != nil {
250 if se, ok := e.(scanError); ok {
251 err = se.err
252 } else {
253 panic(e)
254 }
255 }
256 }()
257 if f == nil {
258 f = notSpace
259 }
260 s.buf = s.buf[:0]
261 tok = s.token(skipSpace, f)
262 return
263 }
264
265
266
267 var space = [][2]uint16{
268 {0x0009, 0x000d},
269 {0x0020, 0x0020},
270 {0x0085, 0x0085},
271 {0x00a0, 0x00a0},
272 {0x1680, 0x1680},
273 {0x2000, 0x200a},
274 {0x2028, 0x2029},
275 {0x202f, 0x202f},
276 {0x205f, 0x205f},
277 {0x3000, 0x3000},
278 }
279
280 func isSpace(r rune) bool {
281 if r >= 1<<16 {
282 return false
283 }
284 rx := uint16(r)
285 for _, rng := range space {
286 if rx < rng[0] {
287 return false
288 }
289 if rx <= rng[1] {
290 return true
291 }
292 }
293 return false
294 }
295
296
297 func notSpace(r rune) bool {
298 return !isSpace(r)
299 }
300
301
302
303
304 type readRune struct {
305 reader io.Reader
306 buf [utf8.UTFMax]byte
307 pending int
308 pendBuf [utf8.UTFMax]byte
309 peekRune rune
310 }
311
312
313
314 func (r *readRune) readByte() (b byte, err error) {
315 if r.pending > 0 {
316 b = r.pendBuf[0]
317 copy(r.pendBuf[0:], r.pendBuf[1:])
318 r.pending--
319 return
320 }
321 n, err := io.ReadFull(r.reader, r.pendBuf[:1])
322 if n != 1 {
323 return 0, err
324 }
325 return r.pendBuf[0], err
326 }
327
328
329
330 func (r *readRune) ReadRune() (rr rune, size int, err error) {
331 if r.peekRune >= 0 {
332 rr = r.peekRune
333 r.peekRune = ^r.peekRune
334 size = utf8.RuneLen(rr)
335 return
336 }
337 r.buf[0], err = r.readByte()
338 if err != nil {
339 return
340 }
341 if r.buf[0] < utf8.RuneSelf {
342 rr = rune(r.buf[0])
343 size = 1
344
345 r.peekRune = ^rr
346 return
347 }
348 var n int
349 for n = 1; !utf8.FullRune(r.buf[:n]); n++ {
350 r.buf[n], err = r.readByte()
351 if err != nil {
352 if err == io.EOF {
353 err = nil
354 break
355 }
356 return
357 }
358 }
359 rr, size = utf8.DecodeRune(r.buf[:n])
360 if size < n {
361 copy(r.pendBuf[r.pending:], r.buf[size:n])
362 r.pending += n - size
363 }
364
365 r.peekRune = ^rr
366 return
367 }
368
369 func (r *readRune) UnreadRune() error {
370 if r.peekRune >= 0 {
371 return errors.New("fmt: scanning called UnreadRune with no rune available")
372 }
373
374 r.peekRune = ^r.peekRune
375 return nil
376 }
377
378 var ssFree = sync.Pool{
379 New: func() any { return new(ss) },
380 }
381
382
383 func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) {
384 s = ssFree.Get().(*ss)
385 if rs, ok := r.(io.RuneScanner); ok {
386 s.rs = rs
387 } else {
388 s.rs = &readRune{reader: r, peekRune: -1}
389 }
390 s.nlIsSpace = nlIsSpace
391 s.nlIsEnd = nlIsEnd
392 s.atEOF = false
393 s.limit = hugeWid
394 s.argLimit = hugeWid
395 s.maxWid = hugeWid
396 s.validSave = true
397 s.count = 0
398 return
399 }
400
401
402 func (s *ss) free(old ssave) {
403
404 if old.validSave {
405 s.ssave = old
406 return
407 }
408
409 if cap(s.buf) > 1024 {
410 return
411 }
412 s.buf = s.buf[:0]
413 s.rs = nil
414 ssFree.Put(s)
415 }
416
417
418
419
420 func (s *ss) SkipSpace() {
421 for {
422 r := s.getRune()
423 if r == eof {
424 return
425 }
426 if r == '\r' && s.peek("\n") {
427 continue
428 }
429 if r == '\n' {
430 if s.nlIsSpace {
431 continue
432 }
433 s.errorString("unexpected newline")
434 return
435 }
436 if !isSpace(r) {
437 s.UnreadRune()
438 break
439 }
440 }
441 }
442
443
444
445
446 func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
447 if skipSpace {
448 s.SkipSpace()
449 }
450
451 for {
452 r := s.getRune()
453 if r == eof {
454 break
455 }
456 if !f(r) {
457 s.UnreadRune()
458 break
459 }
460 s.buf.writeRune(r)
461 }
462 return s.buf
463 }
464
465 var errComplex = errors.New("syntax error scanning complex number")
466 var errBool = errors.New("syntax error scanning boolean")
467
468 func indexRune(s string, r rune) int {
469 for i, c := range s {
470 if c == r {
471 return i
472 }
473 }
474 return -1
475 }
476
477
478
479 func (s *ss) consume(ok string, accept bool) bool {
480 r := s.getRune()
481 if r == eof {
482 return false
483 }
484 if indexRune(ok, r) >= 0 {
485 if accept {
486 s.buf.writeRune(r)
487 }
488 return true
489 }
490 if r != eof && accept {
491 s.UnreadRune()
492 }
493 return false
494 }
495
496
497 func (s *ss) peek(ok string) bool {
498 r := s.getRune()
499 if r != eof {
500 s.UnreadRune()
501 }
502 return indexRune(ok, r) >= 0
503 }
504
505 func (s *ss) notEOF() {
506
507 if r := s.getRune(); r == eof {
508 panic(io.EOF)
509 }
510 s.UnreadRune()
511 }
512
513
514
515 func (s *ss) accept(ok string) bool {
516 return s.consume(ok, true)
517 }
518
519
520 func (s *ss) okVerb(verb rune, okVerbs, typ string) bool {
521 for _, v := range okVerbs {
522 if v == verb {
523 return true
524 }
525 }
526 s.errorString("bad verb '%" + string(verb) + "' for " + typ)
527 return false
528 }
529
530
531 func (s *ss) scanBool(verb rune) bool {
532 s.SkipSpace()
533 s.notEOF()
534 if !s.okVerb(verb, "tv", "boolean") {
535 return false
536 }
537
538 switch s.getRune() {
539 case '0':
540 return false
541 case '1':
542 return true
543 case 't', 'T':
544 if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) {
545 s.error(errBool)
546 }
547 return true
548 case 'f', 'F':
549 if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) {
550 s.error(errBool)
551 }
552 return false
553 }
554 return false
555 }
556
557
558 const (
559 binaryDigits = "01"
560 octalDigits = "01234567"
561 decimalDigits = "0123456789"
562 hexadecimalDigits = "0123456789aAbBcCdDeEfF"
563 sign = "+-"
564 period = "."
565 exponent = "eEpP"
566 )
567
568
569 func (s *ss) getBase(verb rune) (base int, digits string) {
570 s.okVerb(verb, "bdoUxXv", "integer")
571 base = 10
572 digits = decimalDigits
573 switch verb {
574 case 'b':
575 base = 2
576 digits = binaryDigits
577 case 'o':
578 base = 8
579 digits = octalDigits
580 case 'x', 'X', 'U':
581 base = 16
582 digits = hexadecimalDigits
583 }
584 return
585 }
586
587
588 func (s *ss) scanNumber(digits string, haveDigits bool) string {
589 if !haveDigits {
590 s.notEOF()
591 if !s.accept(digits) {
592 s.errorString("expected integer")
593 }
594 }
595 for s.accept(digits) {
596 }
597 return string(s.buf)
598 }
599
600
601 func (s *ss) scanRune(bitSize int) int64 {
602 s.notEOF()
603 r := s.getRune()
604 n := uint(bitSize)
605 x := (int64(r) << (64 - n)) >> (64 - n)
606 if x != int64(r) {
607 s.errorString("overflow on character value " + string(r))
608 }
609 return int64(r)
610 }
611
612
613
614
615 func (s *ss) scanBasePrefix() (base int, digits string, zeroFound bool) {
616 if !s.peek("0") {
617 return 0, decimalDigits + "_", false
618 }
619 s.accept("0")
620
621 switch {
622 case s.peek("bB"):
623 s.consume("bB", true)
624 return 0, binaryDigits + "_", true
625 case s.peek("oO"):
626 s.consume("oO", true)
627 return 0, octalDigits + "_", true
628 case s.peek("xX"):
629 s.consume("xX", true)
630 return 0, hexadecimalDigits + "_", true
631 default:
632 return 0, octalDigits + "_", true
633 }
634 }
635
636
637
638 func (s *ss) scanInt(verb rune, bitSize int) int64 {
639 if verb == 'c' {
640 return s.scanRune(bitSize)
641 }
642 s.SkipSpace()
643 s.notEOF()
644 base, digits := s.getBase(verb)
645 haveDigits := false
646 if verb == 'U' {
647 if !s.consume("U", false) || !s.consume("+", false) {
648 s.errorString("bad unicode format ")
649 }
650 } else {
651 s.accept(sign)
652 if verb == 'v' {
653 base, digits, haveDigits = s.scanBasePrefix()
654 }
655 }
656 tok := s.scanNumber(digits, haveDigits)
657 i, err := strconv.ParseInt(tok, base, 64)
658 if err != nil {
659 s.error(err)
660 }
661 n := uint(bitSize)
662 x := (i << (64 - n)) >> (64 - n)
663 if x != i {
664 s.errorString("integer overflow on token " + tok)
665 }
666 return i
667 }
668
669
670
671 func (s *ss) scanUint(verb rune, bitSize int) uint64 {
672 if verb == 'c' {
673 return uint64(s.scanRune(bitSize))
674 }
675 s.SkipSpace()
676 s.notEOF()
677 base, digits := s.getBase(verb)
678 haveDigits := false
679 if verb == 'U' {
680 if !s.consume("U", false) || !s.consume("+", false) {
681 s.errorString("bad unicode format ")
682 }
683 } else if verb == 'v' {
684 base, digits, haveDigits = s.scanBasePrefix()
685 }
686 tok := s.scanNumber(digits, haveDigits)
687 i, err := strconv.ParseUint(tok, base, 64)
688 if err != nil {
689 s.error(err)
690 }
691 n := uint(bitSize)
692 x := (i << (64 - n)) >> (64 - n)
693 if x != i {
694 s.errorString("unsigned integer overflow on token " + tok)
695 }
696 return i
697 }
698
699
700
701
702 func (s *ss) floatToken() string {
703 s.buf = s.buf[:0]
704
705 if s.accept("nN") && s.accept("aA") && s.accept("nN") {
706 return string(s.buf)
707 }
708
709 s.accept(sign)
710
711 if s.accept("iI") && s.accept("nN") && s.accept("fF") {
712 return string(s.buf)
713 }
714 digits := decimalDigits + "_"
715 exp := exponent
716 if s.accept("0") && s.accept("xX") {
717 digits = hexadecimalDigits + "_"
718 exp = "pP"
719 }
720
721 for s.accept(digits) {
722 }
723
724 if s.accept(period) {
725
726 for s.accept(digits) {
727 }
728 }
729
730 if s.accept(exp) {
731
732 s.accept(sign)
733
734 for s.accept(decimalDigits + "_") {
735 }
736 }
737 return string(s.buf)
738 }
739
740
741
742
743 func (s *ss) complexTokens() (real, imag string) {
744
745 parens := s.accept("(")
746 real = s.floatToken()
747 s.buf = s.buf[:0]
748
749 if !s.accept("+-") {
750 s.error(errComplex)
751 }
752
753 imagSign := string(s.buf)
754 imag = s.floatToken()
755 if !s.accept("i") {
756 s.error(errComplex)
757 }
758 if parens && !s.accept(")") {
759 s.error(errComplex)
760 }
761 return real, imagSign + imag
762 }
763
764 func hasX(s string) bool {
765 for i := 0; i < len(s); i++ {
766 if s[i] == 'x' || s[i] == 'X' {
767 return true
768 }
769 }
770 return false
771 }
772
773
774 func (s *ss) convertFloat(str string, n int) float64 {
775
776
777
778 if p := indexRune(str, 'p'); p >= 0 && !hasX(str) {
779
780
781 f, err := strconv.ParseFloat(str[:p], n)
782 if err != nil {
783
784 if e, ok := err.(*strconv.NumError); ok {
785 e.Num = str
786 }
787 s.error(err)
788 }
789 m, err := strconv.Atoi(str[p+1:])
790 if err != nil {
791
792 if e, ok := err.(*strconv.NumError); ok {
793 e.Num = str
794 }
795 s.error(err)
796 }
797 return math.Ldexp(f, m)
798 }
799 f, err := strconv.ParseFloat(str, n)
800 if err != nil {
801 s.error(err)
802 }
803 return f
804 }
805
806
807
808
809
810 func (s *ss) scanComplex(verb rune, n int) complex128 {
811 if !s.okVerb(verb, floatVerbs, "complex") {
812 return 0
813 }
814 s.SkipSpace()
815 s.notEOF()
816 sreal, simag := s.complexTokens()
817 real := s.convertFloat(sreal, n/2)
818 imag := s.convertFloat(simag, n/2)
819 return complex(real, imag)
820 }
821
822
823
824 func (s *ss) convertString(verb rune) (str string) {
825 if !s.okVerb(verb, "svqxX", "string") {
826 return ""
827 }
828 s.SkipSpace()
829 s.notEOF()
830 switch verb {
831 case 'q':
832 str = s.quotedString()
833 case 'x', 'X':
834 str = s.hexString()
835 default:
836 str = string(s.token(true, notSpace))
837 }
838 return
839 }
840
841
842 func (s *ss) quotedString() string {
843 s.notEOF()
844 quote := s.getRune()
845 switch quote {
846 case '`':
847
848 for {
849 r := s.mustReadRune()
850 if r == quote {
851 break
852 }
853 s.buf.writeRune(r)
854 }
855 return string(s.buf)
856 case '"':
857
858 s.buf.writeByte('"')
859 for {
860 r := s.mustReadRune()
861 s.buf.writeRune(r)
862 if r == '\\' {
863
864
865
866 s.buf.writeRune(s.mustReadRune())
867 } else if r == '"' {
868 break
869 }
870 }
871 result, err := strconv.Unquote(string(s.buf))
872 if err != nil {
873 s.error(err)
874 }
875 return result
876 default:
877 s.errorString("expected quoted string")
878 }
879 return ""
880 }
881
882
883 func hexDigit(d rune) (int, bool) {
884 digit := int(d)
885 switch digit {
886 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
887 return digit - '0', true
888 case 'a', 'b', 'c', 'd', 'e', 'f':
889 return 10 + digit - 'a', true
890 case 'A', 'B', 'C', 'D', 'E', 'F':
891 return 10 + digit - 'A', true
892 }
893 return -1, false
894 }
895
896
897
898
899 func (s *ss) hexByte() (b byte, ok bool) {
900 rune1 := s.getRune()
901 if rune1 == eof {
902 return
903 }
904 value1, ok := hexDigit(rune1)
905 if !ok {
906 s.UnreadRune()
907 return
908 }
909 value2, ok := hexDigit(s.mustReadRune())
910 if !ok {
911 s.errorString("illegal hex digit")
912 return
913 }
914 return byte(value1<<4 | value2), true
915 }
916
917
918 func (s *ss) hexString() string {
919 s.notEOF()
920 for {
921 b, ok := s.hexByte()
922 if !ok {
923 break
924 }
925 s.buf.writeByte(b)
926 }
927 if len(s.buf) == 0 {
928 s.errorString("no hex data for %x string")
929 return ""
930 }
931 return string(s.buf)
932 }
933
934 const (
935 floatVerbs = "beEfFgGv"
936
937 hugeWid = 1 << 30
938
939 intBits = 32 << (^uint(0) >> 63)
940 uintptrBits = 32 << (^uintptr(0) >> 63)
941 )
942
943
944 func (s *ss) scanPercent() {
945 s.SkipSpace()
946 s.notEOF()
947 if !s.accept("%") {
948 s.errorString("missing literal %")
949 }
950 }
951
952
953 func (s *ss) scanOne(verb rune, arg any) {
954 s.buf = s.buf[:0]
955 var err error
956
957 if v, ok := arg.(Scanner); ok {
958 err = v.Scan(s, verb)
959 if err != nil {
960 if err == io.EOF {
961 err = io.ErrUnexpectedEOF
962 }
963 s.error(err)
964 }
965 return
966 }
967
968 switch v := arg.(type) {
969 case *bool:
970 *v = s.scanBool(verb)
971 case *complex64:
972 *v = complex64(s.scanComplex(verb, 64))
973 case *complex128:
974 *v = s.scanComplex(verb, 128)
975 case *int:
976 *v = int(s.scanInt(verb, intBits))
977 case *int8:
978 *v = int8(s.scanInt(verb, 8))
979 case *int16:
980 *v = int16(s.scanInt(verb, 16))
981 case *int32:
982 *v = int32(s.scanInt(verb, 32))
983 case *int64:
984 *v = s.scanInt(verb, 64)
985 case *uint:
986 *v = uint(s.scanUint(verb, intBits))
987 case *uint8:
988 *v = uint8(s.scanUint(verb, 8))
989 case *uint16:
990 *v = uint16(s.scanUint(verb, 16))
991 case *uint32:
992 *v = uint32(s.scanUint(verb, 32))
993 case *uint64:
994 *v = s.scanUint(verb, 64)
995 case *uintptr:
996 *v = uintptr(s.scanUint(verb, uintptrBits))
997
998
999 case *float32:
1000 if s.okVerb(verb, floatVerbs, "float32") {
1001 s.SkipSpace()
1002 s.notEOF()
1003 *v = float32(s.convertFloat(s.floatToken(), 32))
1004 }
1005 case *float64:
1006 if s.okVerb(verb, floatVerbs, "float64") {
1007 s.SkipSpace()
1008 s.notEOF()
1009 *v = s.convertFloat(s.floatToken(), 64)
1010 }
1011 case *string:
1012 *v = s.convertString(verb)
1013 case *[]byte:
1014
1015
1016 *v = []byte(s.convertString(verb))
1017 default:
1018 val := reflect.ValueOf(v)
1019 ptr := val
1020 if ptr.Kind() != reflect.Pointer {
1021 s.errorString("type not a pointer: " + val.Type().String())
1022 return
1023 }
1024 switch v := ptr.Elem(); v.Kind() {
1025 case reflect.Bool:
1026 v.SetBool(s.scanBool(verb))
1027 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1028 v.SetInt(s.scanInt(verb, v.Type().Bits()))
1029 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1030 v.SetUint(s.scanUint(verb, v.Type().Bits()))
1031 case reflect.String:
1032 v.SetString(s.convertString(verb))
1033 case reflect.Slice:
1034
1035 typ := v.Type()
1036 if typ.Elem().Kind() != reflect.Uint8 {
1037 s.errorString("can't scan type: " + val.Type().String())
1038 }
1039 str := s.convertString(verb)
1040 v.Set(reflect.MakeSlice(typ, len(str), len(str)))
1041 for i := 0; i < len(str); i++ {
1042 v.Index(i).SetUint(uint64(str[i]))
1043 }
1044 case reflect.Float32, reflect.Float64:
1045 s.SkipSpace()
1046 s.notEOF()
1047 v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits()))
1048 case reflect.Complex64, reflect.Complex128:
1049 v.SetComplex(s.scanComplex(verb, v.Type().Bits()))
1050 default:
1051 s.errorString("can't scan type: " + val.Type().String())
1052 }
1053 }
1054 }
1055
1056
1057 func errorHandler(errp *error) {
1058 if e := recover(); e != nil {
1059 if se, ok := e.(scanError); ok {
1060 *errp = se.err
1061 } else if eof, ok := e.(error); ok && eof == io.EOF {
1062 *errp = eof
1063 } else {
1064 panic(e)
1065 }
1066 }
1067 }
1068
1069
1070 func (s *ss) doScan(a []any) (numProcessed int, err error) {
1071 defer errorHandler(&err)
1072 for _, arg := range a {
1073 s.scanOne('v', arg)
1074 numProcessed++
1075 }
1076
1077 if s.nlIsEnd {
1078 for {
1079 r := s.getRune()
1080 if r == '\n' || r == eof {
1081 break
1082 }
1083 if !isSpace(r) {
1084 s.errorString("expected newline")
1085 break
1086 }
1087 }
1088 }
1089 return
1090 }
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 func (s *ss) advance(format string) (i int) {
1101 for i < len(format) {
1102 fmtc, w := utf8.DecodeRuneInString(format[i:])
1103
1104
1105
1106
1107
1108
1109
1110 if isSpace(fmtc) {
1111 newlines := 0
1112 trailingSpace := false
1113 for isSpace(fmtc) && i < len(format) {
1114 if fmtc == '\n' {
1115 newlines++
1116 trailingSpace = false
1117 } else {
1118 trailingSpace = true
1119 }
1120 i += w
1121 fmtc, w = utf8.DecodeRuneInString(format[i:])
1122 }
1123 for j := 0; j < newlines; j++ {
1124 inputc := s.getRune()
1125 for isSpace(inputc) && inputc != '\n' {
1126 inputc = s.getRune()
1127 }
1128 if inputc != '\n' && inputc != eof {
1129 s.errorString("newline in format does not match input")
1130 }
1131 }
1132 if trailingSpace {
1133 inputc := s.getRune()
1134 if newlines == 0 {
1135
1136
1137 if !isSpace(inputc) && inputc != eof {
1138 s.errorString("expected space in input to match format")
1139 }
1140 if inputc == '\n' {
1141 s.errorString("newline in input does not match format")
1142 }
1143 }
1144 for isSpace(inputc) && inputc != '\n' {
1145 inputc = s.getRune()
1146 }
1147 if inputc != eof {
1148 s.UnreadRune()
1149 }
1150 }
1151 continue
1152 }
1153
1154
1155 if fmtc == '%' {
1156
1157 if i+w == len(format) {
1158 s.errorString("missing verb: % at end of format string")
1159 }
1160
1161 nextc, _ := utf8.DecodeRuneInString(format[i+w:])
1162 if nextc != '%' {
1163 return
1164 }
1165 i += w
1166 }
1167
1168
1169 inputc := s.mustReadRune()
1170 if fmtc != inputc {
1171 s.UnreadRune()
1172 return -1
1173 }
1174 i += w
1175 }
1176 return
1177 }
1178
1179
1180
1181 func (s *ss) doScanf(format string, a []any) (numProcessed int, err error) {
1182 defer errorHandler(&err)
1183 end := len(format) - 1
1184
1185 for i := 0; i <= end; {
1186 w := s.advance(format[i:])
1187 if w > 0 {
1188 i += w
1189 continue
1190 }
1191
1192 if format[i] != '%' {
1193
1194 if w < 0 {
1195 s.errorString("input does not match format")
1196 }
1197
1198 break
1199 }
1200 i++
1201
1202
1203 var widPresent bool
1204 s.maxWid, widPresent, i = parsenum(format, i, end)
1205 if !widPresent {
1206 s.maxWid = hugeWid
1207 }
1208
1209 c, w := utf8.DecodeRuneInString(format[i:])
1210 i += w
1211
1212 if c != 'c' {
1213 s.SkipSpace()
1214 }
1215 if c == '%' {
1216 s.scanPercent()
1217 continue
1218 }
1219 s.argLimit = s.limit
1220 if f := s.count + s.maxWid; f < s.argLimit {
1221 s.argLimit = f
1222 }
1223
1224 if numProcessed >= len(a) {
1225 s.errorString("too few operands for format '%" + format[i-w:] + "'")
1226 break
1227 }
1228 arg := a[numProcessed]
1229
1230 s.scanOne(c, arg)
1231 numProcessed++
1232 s.argLimit = s.limit
1233 }
1234 if numProcessed < len(a) {
1235 s.errorString("too many operands")
1236 }
1237 return
1238 }
1239
View as plain text