| 520 | } |
| 521 | |
| 522 | func findallVariables(raw string) variableSet { |
| 523 | matchStartPosition := 0 |
| 524 | remainedString := raw |
| 525 | varSet := make(variableSet) |
| 526 | |
| 527 | for matchStartPosition < len(raw) { |
| 528 | // locate $ char position |
| 529 | startPosition := strings.Index(remainedString, "$") |
| 530 | if startPosition == -1 { // no $ found |
| 531 | return varSet |
| 532 | } |
| 533 | |
| 534 | // found $, check if variable or function |
| 535 | matchStartPosition += startPosition |
| 536 | remainedString = remainedString[startPosition:] |
| 537 | |
| 538 | // Notice: notation priority |
| 539 | // $$ > $var |
| 540 | |
| 541 | // search $$, use $$ to escape $ notation |
| 542 | if strings.HasPrefix(remainedString, "$$") { // found $$ |
| 543 | matchStartPosition += 2 |
| 544 | remainedString = remainedString[2:] |
| 545 | continue |
| 546 | } |
| 547 | |
| 548 | // search variable like ${var} or $var |
| 549 | varMatched := regexCompileVariable.FindStringSubmatch(remainedString) |
| 550 | if len(varMatched) == 3 { |
| 551 | var varName string |
| 552 | if varMatched[1] != "" { |
| 553 | varName = varMatched[1] // match ${var} |
| 554 | } else { |
| 555 | varName = varMatched[2] // match $var |
| 556 | } |
| 557 | varSet[varName] = struct{}{} |
| 558 | |
| 559 | matchStartPosition += len(varMatched[0]) |
| 560 | remainedString = raw[matchStartPosition:] |
| 561 | continue |
| 562 | } |
| 563 | |
| 564 | break |
| 565 | } |
| 566 | |
| 567 | return varSet |
| 568 | } |