scanDollarQuotedString scans for so called dollar-quoted strings, which start/end with either $$ or $tag$, where tag is some arbitrary string. e.g. $$a string$$ or $escaped$a string$escaped$.
(lval ScanSymType)
| 1024 | // scanDollarQuotedString scans for so called dollar-quoted strings, which start/end with either $$ or $tag$, where |
| 1025 | // tag is some arbitrary string. e.g. $$a string$$ or $escaped$a string$escaped$. |
| 1026 | func (s *Scanner) scanDollarQuotedString(lval ScanSymType) bool { |
| 1027 | s.lastAttemptedID = int32(lexbase.SCONST) |
| 1028 | buf := s.buffer() |
| 1029 | start := s.pos |
| 1030 | |
| 1031 | foundStartTag := false |
| 1032 | possibleEndTag := false |
| 1033 | startTagIndex := -1 |
| 1034 | var startTag string |
| 1035 | |
| 1036 | outer: |
| 1037 | for { |
| 1038 | ch := s.peek() |
| 1039 | switch ch { |
| 1040 | case '$': |
| 1041 | s.pos++ |
| 1042 | if foundStartTag { |
| 1043 | if possibleEndTag { |
| 1044 | if len(startTag) == startTagIndex { |
| 1045 | // Found end tag. |
| 1046 | buf = append(buf, s.in[start+len(startTag)+1:s.pos-len(startTag)-2]...) |
| 1047 | break outer |
| 1048 | } else { |
| 1049 | // Was not the end tag but the current $ might be the start of the end tag we are looking for, so |
| 1050 | // just reset the startTagIndex. |
| 1051 | startTagIndex = 0 |
| 1052 | } |
| 1053 | } else { |
| 1054 | possibleEndTag = true |
| 1055 | startTagIndex = 0 |
| 1056 | } |
| 1057 | } else { |
| 1058 | startTag = s.in[start : s.pos-1] |
| 1059 | foundStartTag = true |
| 1060 | } |
| 1061 | |
| 1062 | case eof: |
| 1063 | if foundStartTag { |
| 1064 | // A start tag was found, therefore we expect an end tag before the eof, otherwise it is an error. |
| 1065 | lval.SetID(lexbase.ERROR) |
| 1066 | lval.SetStr(errUnterminated) |
| 1067 | } else { |
| 1068 | // This is not a dollar-quoted string, reset the pos back to the start. |
| 1069 | s.pos = start |
| 1070 | } |
| 1071 | return false |
| 1072 | |
| 1073 | default: |
| 1074 | // If we haven't found a start tag yet, check whether the current characters is a valid for a tag. |
| 1075 | if !foundStartTag && !lexbase.IsIdentStart(ch) && !lexbase.IsDigit(ch) { |
| 1076 | return false |
| 1077 | } |
| 1078 | s.pos++ |
| 1079 | if possibleEndTag { |
| 1080 | // Check whether this could be the end tag. |
| 1081 | if startTagIndex >= len(startTag) || ch != int(startTag[startTagIndex]) { |
| 1082 | // This is not the end tag we are looking for. |
| 1083 | possibleEndTag = false |
no test coverage detected