splitVariableString is a derivative of splitPackageOverrideString in release create. it is required because the builtin go strings.SplitN can't handle more than one delimeter character. otherwise it works the same, but caps the number of splits at 'n'
(s string, n int)
| 351 | // otherwise it works the same, but caps the number of splits at 'n' |
| 352 | |
| 353 | func splitVariableString(s string, n int) []string { |
| 354 | // pass 1: collect spans; golang strings.FieldsFunc says it's much more efficient this way |
| 355 | type span struct { |
| 356 | start int |
| 357 | end int |
| 358 | } |
| 359 | spans := make([]span, 0, n) |
| 360 | |
| 361 | // Find the field start and end indices. |
| 362 | start := 0 // we always start the first span at the beginning of the string |
| 363 | escaped := false |
| 364 | |
| 365 | for idx, ch := range s { |
| 366 | if ch == '\\' && !escaped { |
| 367 | escaped = true |
| 368 | continue |
| 369 | } |
| 370 | |
| 371 | if (ch == ':' || ch == '=') && (!escaped) { |
| 372 | if start >= 0 { // we found a delimiter and we are already in a span; end the span and start a new one |
| 373 | if len(spans) == n-1 { // we're about to append the last span, break so the 'last field' code consumes the rest of the string |
| 374 | break |
| 375 | } else { |
| 376 | spans = append(spans, span{start, idx}) |
| 377 | start = idx + 1 |
| 378 | } |
| 379 | } else { // we found a delimiter and we are not in a span; start a new span |
| 380 | if start < 0 { |
| 381 | start = idx |
| 382 | } |
| 383 | } |
| 384 | } else { |
| 385 | escaped = false |
| 386 | } |
| 387 | } |
| 388 | |
| 389 | // Last field might end at EOF. |
| 390 | if start >= 0 { |
| 391 | spans = append(spans, span{start, len(s)}) |
| 392 | } |
| 393 | |
| 394 | // pass 2: create strings from recorded field indices. |
| 395 | a := make([]string, len(spans)) |
| 396 | for i, span := range spans { |
| 397 | a[i] = s[span.start:span.end] |
| 398 | } |
| 399 | |
| 400 | // the parts |
| 401 | for i, part := range a { |
| 402 | a[i] = unescape(part) |
| 403 | } |
| 404 | |
| 405 | return a |
| 406 | } |
| 407 | |
| 408 | func unescape(s string) string { |
| 409 | result := make([]rune, 0, len(s)) |
no test coverage detected