github.com/gotranspile/cxgo@v0.3.7/runtime/stdio/format.go (about) 1 package stdio 2 3 import "strings" 4 5 type formatWord struct { 6 Str string 7 Verb bool 8 } 9 10 func parseFormat(format string) []formatWord { 11 var ( 12 words []formatWord 13 placeholder = false 14 cur []rune 15 ) 16 reset := func() { 17 cur = cur[:0] 18 placeholder = false 19 } 20 pushWord := func(verb bool) { 21 if len(cur) != 0 { 22 words = append(words, formatWord{Str: string(cur), Verb: verb}) 23 } 24 reset() 25 } 26 for _, b := range format { 27 if b == '%' { 28 if placeholder { 29 if len(cur) == 1 { // %% 30 cur = append(cur, '%') 31 pushWord(true) // fake verb 32 continue 33 } 34 // end the current placeholder, start a new one 35 pushWord(true) 36 } 37 // start a new placeholder 38 pushWord(false) 39 placeholder = true 40 cur = append(cur, '%') 41 continue 42 } 43 if !placeholder { 44 // continue the string 45 cur = append(cur, b) 46 continue 47 } 48 // in placeholder 49 switch b { 50 default: 51 if strings.IndexRune("1234567890#+-*. l", b) >= 0 { 52 // consider a part of the placeholder 53 cur = append(cur, b) 54 continue 55 } 56 // other rune: stop the placeholder 57 pushWord(true) 58 cur = append(cur, b) 59 continue 60 case 'i': // signed, allows octal and hex 61 case 'd': // signed, only decimal 62 case 'u': // unsigned, only decimal 63 case 'o': // octal 64 case 'x': // hex 65 case 'f', 'e', 'g', 'F', 'E', 'G': // float 66 case 'c': // char 67 case 'p': // ptr 68 case 's': // string 69 case 'S': // wstring 70 } 71 cur = append(cur, b) 72 pushWord(true) 73 } 74 pushWord(placeholder) 75 return words 76 }