1// line 1 "format_fsm.rl" 2// This file is generated from format_fsm.rl. DO NOT EDIT. 3 4// line 5 "format_fsm.rl" 5 6package stdlib 7 8import ( 9 "bytes" 10 "fmt" 11 "unicode/utf8" 12 13 "github.com/zclconf/go-cty/cty" 14 "github.com/zclconf/go-cty/cty/function" 15) 16 17// line 21 "format_fsm.go" 18var _formatfsm_actions []byte = []byte{ 19 0, 1, 0, 1, 1, 1, 2, 1, 4, 20 1, 5, 1, 6, 1, 7, 1, 8, 21 1, 9, 1, 10, 1, 11, 1, 14, 22 1, 16, 1, 17, 1, 18, 2, 3, 23 4, 2, 12, 10, 2, 12, 16, 2, 24 12, 18, 2, 13, 14, 2, 15, 10, 25 2, 15, 18, 26} 27 28var _formatfsm_key_offsets []byte = []byte{ 29 0, 0, 14, 27, 34, 36, 39, 43, 30 51, 31} 32 33var _formatfsm_trans_keys []byte = []byte{ 34 32, 35, 37, 43, 45, 46, 48, 91, 35 49, 57, 65, 90, 97, 122, 32, 35, 36 43, 45, 46, 48, 91, 49, 57, 65, 37 90, 97, 122, 91, 48, 57, 65, 90, 38 97, 122, 49, 57, 93, 48, 57, 65, 39 90, 97, 122, 46, 91, 48, 57, 65, 40 90, 97, 122, 37, 41} 42 43var _formatfsm_single_lengths []byte = []byte{ 44 0, 8, 7, 1, 0, 1, 0, 2, 45 1, 46} 47 48var _formatfsm_range_lengths []byte = []byte{ 49 0, 3, 3, 3, 1, 1, 2, 3, 50 0, 51} 52 53var _formatfsm_index_offsets []byte = []byte{ 54 0, 0, 12, 23, 28, 30, 33, 36, 55 42, 56} 57 58var _formatfsm_indicies []byte = []byte{ 59 1, 2, 3, 4, 5, 6, 7, 10, 60 8, 9, 9, 0, 1, 2, 4, 5, 61 6, 7, 10, 8, 9, 9, 0, 13, 62 11, 12, 12, 0, 14, 0, 15, 14, 63 0, 9, 9, 0, 16, 19, 17, 18, 64 18, 0, 20, 3, 65} 66 67var _formatfsm_trans_targs []byte = []byte{ 68 0, 2, 2, 8, 2, 2, 3, 2, 69 7, 8, 4, 3, 8, 4, 5, 6, 70 3, 7, 8, 4, 1, 71} 72 73var _formatfsm_trans_actions []byte = []byte{ 74 7, 17, 9, 3, 15, 13, 25, 11, 75 43, 29, 19, 27, 49, 46, 21, 0, 76 37, 23, 40, 34, 1, 77} 78 79var _formatfsm_eof_actions []byte = []byte{ 80 0, 31, 31, 31, 31, 31, 31, 31, 81 5, 82} 83 84const formatfsm_start int = 8 85const formatfsm_first_final int = 8 86const formatfsm_error int = 0 87 88const formatfsm_en_main int = 8 89 90// line 20 "format_fsm.rl" 91 92func formatFSM(format string, a []cty.Value) (string, error) { 93 var buf bytes.Buffer 94 data := format 95 nextArg := 1 // arg numbers are 1-based 96 var verb formatVerb 97 highestArgIdx := 0 // zero means "none", since arg numbers are 1-based 98 99 // line 159 "format_fsm.rl" 100 101 // Ragel state 102 p := 0 // "Pointer" into data 103 pe := len(data) // End-of-data "pointer" 104 cs := 0 // current state (will be initialized by ragel-generated code) 105 ts := 0 106 te := 0 107 eof := pe 108 109 // Keep Go compiler happy even if generated code doesn't use these 110 _ = ts 111 _ = te 112 _ = eof 113 114 // line 123 "format_fsm.go" 115 { 116 cs = formatfsm_start 117 } 118 119 // line 128 "format_fsm.go" 120 { 121 var _klen int 122 var _trans int 123 var _acts int 124 var _nacts uint 125 var _keys int 126 if p == pe { 127 goto _test_eof 128 } 129 if cs == 0 { 130 goto _out 131 } 132 _resume: 133 _keys = int(_formatfsm_key_offsets[cs]) 134 _trans = int(_formatfsm_index_offsets[cs]) 135 136 _klen = int(_formatfsm_single_lengths[cs]) 137 if _klen > 0 { 138 _lower := int(_keys) 139 var _mid int 140 _upper := int(_keys + _klen - 1) 141 for { 142 if _upper < _lower { 143 break 144 } 145 146 _mid = _lower + ((_upper - _lower) >> 1) 147 switch { 148 case data[p] < _formatfsm_trans_keys[_mid]: 149 _upper = _mid - 1 150 case data[p] > _formatfsm_trans_keys[_mid]: 151 _lower = _mid + 1 152 default: 153 _trans += int(_mid - int(_keys)) 154 goto _match 155 } 156 } 157 _keys += _klen 158 _trans += _klen 159 } 160 161 _klen = int(_formatfsm_range_lengths[cs]) 162 if _klen > 0 { 163 _lower := int(_keys) 164 var _mid int 165 _upper := int(_keys + (_klen << 1) - 2) 166 for { 167 if _upper < _lower { 168 break 169 } 170 171 _mid = _lower + (((_upper - _lower) >> 1) & ^1) 172 switch { 173 case data[p] < _formatfsm_trans_keys[_mid]: 174 _upper = _mid - 2 175 case data[p] > _formatfsm_trans_keys[_mid+1]: 176 _lower = _mid + 2 177 default: 178 _trans += int((_mid - int(_keys)) >> 1) 179 goto _match 180 } 181 } 182 _trans += _klen 183 } 184 185 _match: 186 _trans = int(_formatfsm_indicies[_trans]) 187 cs = int(_formatfsm_trans_targs[_trans]) 188 189 if _formatfsm_trans_actions[_trans] == 0 { 190 goto _again 191 } 192 193 _acts = int(_formatfsm_trans_actions[_trans]) 194 _nacts = uint(_formatfsm_actions[_acts]) 195 _acts++ 196 for ; _nacts > 0; _nacts-- { 197 _acts++ 198 switch _formatfsm_actions[_acts-1] { 199 case 0: 200 // line 31 "format_fsm.rl" 201 202 verb = formatVerb{ 203 ArgNum: nextArg, 204 Prec: -1, 205 Width: -1, 206 } 207 ts = p 208 209 case 1: 210 // line 40 "format_fsm.rl" 211 212 buf.WriteByte(data[p]) 213 214 case 4: 215 // line 51 "format_fsm.rl" 216 217 // We'll try to slurp a whole UTF-8 sequence here, to give the user 218 // better feedback. 219 r, _ := utf8.DecodeRuneInString(data[p:]) 220 return buf.String(), fmt.Errorf("unrecognized format character %q at offset %d", r, p) 221 222 case 5: 223 // line 58 "format_fsm.rl" 224 225 verb.Sharp = true 226 227 case 6: 228 // line 61 "format_fsm.rl" 229 230 verb.Zero = true 231 232 case 7: 233 // line 64 "format_fsm.rl" 234 235 verb.Minus = true 236 237 case 8: 238 // line 67 "format_fsm.rl" 239 240 verb.Plus = true 241 242 case 9: 243 // line 70 "format_fsm.rl" 244 245 verb.Space = true 246 247 case 10: 248 // line 74 "format_fsm.rl" 249 250 verb.ArgNum = 0 251 252 case 11: 253 // line 77 "format_fsm.rl" 254 255 verb.ArgNum = (10 * verb.ArgNum) + (int(data[p]) - '0') 256 257 case 12: 258 // line 81 "format_fsm.rl" 259 260 verb.HasWidth = true 261 262 case 13: 263 // line 84 "format_fsm.rl" 264 265 verb.Width = 0 266 267 case 14: 268 // line 87 "format_fsm.rl" 269 270 verb.Width = (10 * verb.Width) + (int(data[p]) - '0') 271 272 case 15: 273 // line 91 "format_fsm.rl" 274 275 verb.HasPrec = true 276 277 case 16: 278 // line 94 "format_fsm.rl" 279 280 verb.Prec = 0 281 282 case 17: 283 // line 97 "format_fsm.rl" 284 285 verb.Prec = (10 * verb.Prec) + (int(data[p]) - '0') 286 287 case 18: 288 // line 101 "format_fsm.rl" 289 290 verb.Mode = rune(data[p]) 291 te = p + 1 292 verb.Raw = data[ts:te] 293 verb.Offset = ts 294 295 if verb.ArgNum > highestArgIdx { 296 highestArgIdx = verb.ArgNum 297 } 298 299 err := formatAppend(&verb, &buf, a) 300 if err != nil { 301 return buf.String(), err 302 } 303 nextArg = verb.ArgNum + 1 304 305 // line 330 "format_fsm.go" 306 } 307 } 308 309 _again: 310 if cs == 0 { 311 goto _out 312 } 313 p++ 314 if p != pe { 315 goto _resume 316 } 317 _test_eof: 318 { 319 } 320 if p == eof { 321 __acts := _formatfsm_eof_actions[cs] 322 __nacts := uint(_formatfsm_actions[__acts]) 323 __acts++ 324 for ; __nacts > 0; __nacts-- { 325 __acts++ 326 switch _formatfsm_actions[__acts-1] { 327 case 2: 328 // line 44 "format_fsm.rl" 329 330 case 3: 331 // line 47 "format_fsm.rl" 332 333 return buf.String(), fmt.Errorf("invalid format string starting at offset %d", p) 334 335 case 4: 336 // line 51 "format_fsm.rl" 337 338 // We'll try to slurp a whole UTF-8 sequence here, to give the user 339 // better feedback. 340 r, _ := utf8.DecodeRuneInString(data[p:]) 341 return buf.String(), fmt.Errorf("unrecognized format character %q at offset %d", r, p) 342 343 // line 369 "format_fsm.go" 344 } 345 } 346 } 347 348 _out: 349 { 350 } 351 } 352 353 // line 177 "format_fsm.rl" 354 355 // If we fall out here without being in a final state then we've 356 // encountered something that the scanner can't match, which should 357 // be impossible (the scanner matches all bytes _somehow_) but we'll 358 // flag it anyway rather than just losing data from the end. 359 if cs < formatfsm_first_final { 360 return buf.String(), fmt.Errorf("extraneous characters beginning at offset %d", p) 361 } 362 363 if highestArgIdx < len(a) { 364 // Extraneous args are an error, to more easily detect mistakes 365 firstBad := highestArgIdx + 1 366 if highestArgIdx == 0 { 367 // Custom error message for this case 368 return buf.String(), function.NewArgErrorf(firstBad, "too many arguments; no verbs in format string") 369 } 370 return buf.String(), function.NewArgErrorf(firstBad, "too many arguments; only %d used by format string", highestArgIdx) 371 } 372 373 return buf.String(), nil 374} 375