forked from openclaw/openclaw
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharg-split.ts
More file actions
63 lines (61 loc) · 1.62 KB
/
Copy patharg-split.ts
File metadata and controls
63 lines (61 loc) · 1.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
type ArgSplitEscapeMode = "none" | "backslash" | "backslash-quote-only";
type ArgSplitQuoteChar = '"' | "'";
type ArgSplitQuoteStart = "anywhere" | "item-start";
export function splitArgsPreservingQuotes(
value: string,
options?: {
escapeMode?: ArgSplitEscapeMode;
quoteChars?: readonly ArgSplitQuoteChar[];
quoteStart?: ArgSplitQuoteStart;
},
): string[] {
const args: string[] = [];
let current = "";
let quoteChar: ArgSplitQuoteChar | null = null;
const escapeMode = options?.escapeMode ?? "none";
const quoteChars = new Set<ArgSplitQuoteChar>(options?.quoteChars ?? ['"']);
const quoteStart = options?.quoteStart ?? "anywhere";
for (let i = 0; i < value.length; i++) {
const char = value[i];
if (escapeMode === "backslash" && char === "\\") {
if (i + 1 < value.length) {
current += value[i + 1];
i++;
}
continue;
}
if (
escapeMode === "backslash-quote-only" &&
char === "\\" &&
i + 1 < value.length &&
value[i + 1] === '"'
) {
current += '"';
i++;
continue;
}
if (quoteChars.has(char as ArgSplitQuoteChar)) {
if (quoteChar === char) {
quoteChar = null;
continue;
}
const canOpenQuote = quoteStart === "anywhere" || current.length === 0;
if (!quoteChar && canOpenQuote) {
quoteChar = char as ArgSplitQuoteChar;
continue;
}
}
if (!quoteChar && /\s/.test(char)) {
if (current) {
args.push(current);
current = "";
}
continue;
}
current += char;
}
if (current) {
args.push(current);
}
return args;
}