mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-11 18:23:54 +01:00
128 lines
3.8 KiB
TypeScript
128 lines
3.8 KiB
TypeScript
import { substituteAliases } from "../Alias";
|
|
// Helper function that checks if an argument (which is a string) is a valid number
|
|
function isNumber(str: string): boolean {
|
|
if (typeof str != "string") {
|
|
return false;
|
|
} // Only process strings
|
|
return !isNaN(parseFloat(str));
|
|
}
|
|
|
|
export function ParseCommands(commands: string): string[] {
|
|
// Sanitize input
|
|
commands = commands.trim();
|
|
// Replace all extra whitespace in command with a single space
|
|
commands = commands.replace(/\s\s+/g, " ");
|
|
|
|
const match = commands.match(/(?:'[^']*'|"[^"]*"|[^;"])*/g);
|
|
if (!match) return [];
|
|
// Split commands and execute sequentially
|
|
const allCommands = match
|
|
.map(substituteAliases)
|
|
.map((c) => c.match(/(?:'[^']*'|"[^"]*"|[^;"])*/g))
|
|
.flat();
|
|
|
|
const out: string[] = [];
|
|
for (const c of allCommands) {
|
|
if (c === null) continue;
|
|
if (c.match(/^\s*$/)) {
|
|
continue;
|
|
} // Don't run commands that only have whitespace
|
|
out.push(c.trim());
|
|
}
|
|
return out;
|
|
}
|
|
|
|
export function ParseCommand(command: string): (string | number)[] {
|
|
// This will be used to keep track of whether we're in a quote. This is for situations
|
|
// like the alias command:
|
|
// alias run="run NUKE.exe"
|
|
// We want the run="run NUKE.exe" to be parsed as a single command, so this flag
|
|
// will keep track of whether we have a quote in
|
|
let inQuote = ``;
|
|
|
|
// Returns an array with the command and its arguments in each index
|
|
// Properly handles quotation marks (e.g. `run foo.script "the sun"` will return [run, foo.script, the sun])
|
|
const args = [];
|
|
let start = 0,
|
|
i = 0;
|
|
let prevChar = ""; // Previous character
|
|
while (i < command.length) {
|
|
let escaped = false; // Check for escaped quotation marks
|
|
if (i >= 1) {
|
|
prevChar = command.charAt(i - 1);
|
|
if (prevChar === "\\") {
|
|
escaped = true;
|
|
}
|
|
}
|
|
|
|
const c = command.charAt(i);
|
|
if (c === '"') {
|
|
// Double quotes
|
|
if (!escaped && prevChar === " ") {
|
|
const endQuote = command.indexOf('"', i + 1);
|
|
if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === " ")) {
|
|
args.push(command.substr(i + 1, endQuote - i - 1));
|
|
if (endQuote === command.length - 1) {
|
|
start = i = endQuote + 1;
|
|
} else {
|
|
start = i = endQuote + 2; // Skip the space
|
|
}
|
|
continue;
|
|
}
|
|
} else {
|
|
if (inQuote === ``) {
|
|
inQuote = `"`;
|
|
} else if (inQuote === `"`) {
|
|
inQuote = ``;
|
|
}
|
|
}
|
|
} else if (c === "'") {
|
|
// Single quotes, same thing as above
|
|
if (!escaped && prevChar === " ") {
|
|
const endQuote = command.indexOf("'", i + 1);
|
|
if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === " ")) {
|
|
args.push(command.substr(i + 1, endQuote - i - 1));
|
|
if (endQuote === command.length - 1) {
|
|
start = i = endQuote + 1;
|
|
} else {
|
|
start = i = endQuote + 2; // Skip the space
|
|
}
|
|
continue;
|
|
}
|
|
} else {
|
|
if (inQuote === ``) {
|
|
inQuote = `'`;
|
|
} else if (inQuote === `'`) {
|
|
inQuote = ``;
|
|
}
|
|
}
|
|
} else if (c === " " && inQuote === ``) {
|
|
const arg = command.substr(start, i - start);
|
|
|
|
// If this is a number, convert it from a string to number
|
|
if (isNumber(arg)) {
|
|
args.push(parseFloat(arg));
|
|
} else {
|
|
args.push(arg);
|
|
}
|
|
|
|
start = i + 1;
|
|
}
|
|
++i;
|
|
}
|
|
|
|
// Add the last argument
|
|
if (start !== i) {
|
|
const arg = command.substr(start, i - start);
|
|
|
|
// If this is a number, convert it from string to number
|
|
if (isNumber(arg)) {
|
|
args.push(parseFloat(arg));
|
|
} else {
|
|
args.push(arg);
|
|
}
|
|
}
|
|
|
|
return args;
|
|
}
|