diff options
| author | Eyal Posener <[email protected]> | 2019-11-14 06:51:44 +0200 |
|---|---|---|
| committer | Eyal Posener <[email protected]> | 2019-11-18 01:05:47 +0200 |
| commit | 8724aaf18312e54750540a9578e00d61b1c545d8 (patch) | |
| tree | d3e736b4fb279975bbcc017ae1bad53e454c5773 /internal/tokener/tokener.go | |
| parent | 05b68ffc813dd10c420993cb1cf927b346c057b8 (diff) | |
V2
Diffstat (limited to 'internal/tokener/tokener.go')
| -rw-r--r-- | internal/tokener/tokener.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/internal/tokener/tokener.go b/internal/tokener/tokener.go new file mode 100644 index 0000000..0886341 --- /dev/null +++ b/internal/tokener/tokener.go @@ -0,0 +1,67 @@ +package tokener + +type Tokener struct { + quotes []byte + escaped bool + fixed string + space bool +} + +// Visit visit a byte and update the state of the quotes. +// It returns true if the byte was quotes or escape character. +func (t *Tokener) Visit(b byte) { + // Check space. + if b == ' ' { + if !t.escaped && !t.Quoted() { + t.space = true + } + } else { + t.space = false + } + + // Check escaping + if b == '\\' { + t.escaped = !t.escaped + } else { + defer func() { t.escaped = false }() + } + + // Check quotes. + if !t.escaped && (b == '"' || b == '\'') { + if t.Quoted() && t.quotes[len(t.quotes)-1] == b { + t.quotes = t.quotes[:len(t.quotes)-1] + } else { + t.quotes = append(t.quotes, b) + } + } + + // If not quoted, insert escape before inserting space. + if t.LastSpace() { + t.fixed += "\\" + } + t.fixed += string(b) +} + +func (t *Tokener) Escaped() bool { + return t.escaped +} + +func (t *Tokener) Quoted() bool { + return len(t.quotes) > 0 +} + +func (t *Tokener) Fixed() string { + return t.fixed +} + +func (t *Tokener) Closed() string { + fixed := t.fixed + for i := len(t.quotes) - 1; i >= 0; i-- { + fixed += string(t.quotes[i]) + } + return fixed +} + +func (t *Tokener) LastSpace() bool { + return t.space +} |
