MCPcopy Create free account
hub / github.com/Zoo-Code-Org/Zoo-Code / scanTopLevelQuotes

Function scanTopLevelQuotes

src/shared/parse-command.ts:201–395  ·  view source on GitHub ↗

* Single shared state-machine walk used by both `findUnterminatedQuote` and * `maskTopLevelQuotes`. Walks `command` left-to-right, identifies every * top-level quoted region (outside any other quote and outside `#` comments), * and returns the list of spans together with an unterminated-quote des

(command: string)

Source from the content-addressed store, hash-verified

199 * - `heredoc` <<WORD...WORD
200 */
201function scanTopLevelQuotes(command: string): ScanResult {
202 const spans: QuoteSpan[] = []
203 let i = 0
204
205 while (i < command.length) {
206 const char = command[i]
207
208 // Outside any quoted region: handle backslash, comments, and quote openers.
209 if (char === "\\") {
210 // Backslash escapes the next character; a quote after it is literal.
211 i += 2
212 continue
213 }
214
215 if (char === "#" && (i === 0 || /\s/.test(command[i - 1]))) {
216 // Comment: skip to end of line. Quotes inside are not shell quoting.
217 while (i < command.length && command[i] !== "\n" && command[i] !== "\r") {
218 i++
219 }
220 continue
221 }
222
223 // Herestring (<<<): single-line stdin redirect -- no body or terminator.
224 if (char === "<" && command[i + 1] === "<" && command[i + 2] === "<") {
225 i += 3
226 continue
227 }
228
229 // Heredoc opener: <<[-]? followed by an optional-quoted delimiter word.
230 if (char === "<" && command[i + 1] === "<") {
231 const start = i
232 i += 2 // skip <<
233 const stripTabs = command[i] === "-"
234 if (stripTabs) i++
235 // Skip horizontal whitespace between << and the delimiter word.
236 while (i < command.length && (command[i] === " " || command[i] === "\t")) {
237 i++
238 }
239 const { delimiter, endIndex } = parseHeredocDelimiter(command, i)
240 i = endIndex
241 // Advance past the remainder of the opener line.
242 while (i < command.length && command[i] !== "\n") i++
243 if (i < command.length) i++ // consume newline
244 if (delimiter.length > 0) {
245 let found = false
246 while (i < command.length) {
247 const lineStart = i
248 while (i < command.length && command[i] !== "\n" && command[i] !== "\r") {
249 i++
250 }
251 // Strip leading tabs only for <<- heredocs.
252 const rawLine = command.slice(lineStart, i)
253 const line = stripTabs ? rawLine.replace(/^\t*/, "") : rawLine
254 // Do NOT advance past the terminator's newline -- leave it as a
255 // separator for any command that follows the heredoc.
256 if (line === delimiter) {
257 found = true
258 break

Callers 3

findUnterminatedQuoteFunction · 0.85
maskTopLevelQuotesFunction · 0.85
parseCommandFunction · 0.85

Calls 3

parseHeredocDelimiterFunction · 0.85
unterminatedQuoteMessageFunction · 0.85
replaceMethod · 0.65

Tested by

no test coverage detected