pipe is wip but && operator kinda works

This commit is contained in:
minjaesong
2022-05-13 11:18:14 +09:00
parent 761f9b6264
commit 359ef6d235

View File

@@ -235,8 +235,6 @@ shell.parse = function(input) {
tokens.push(stringBuffer); tokens.push(stringBuffer);
} }
println(tokens)
return tokens; return tokens;
} }
shell.resolvePathInput = function(input) { shell.resolvePathInput = function(input) {
@@ -385,107 +383,147 @@ shell.coreutils.chdir = shell.coreutils.cd;
Object.freeze(shell.coreutils); Object.freeze(shell.coreutils);
shell.execute = function(line) { shell.execute = function(line) {
if (0 == line.size) return; if (0 == line.size) return;
var tokens = shell.parse(line); let parsedTokens = shell.parse(line); // echo, "hai", |, less
var cmd = tokens[0]; let statements = [] // [[echo, "hai"], [less]]
if (cmd === undefined || cmd === '') return 0; let operators = [] // [|]
// handle Ctrl-C let opRegex = /[|>&<]/
if (con.hitterminate()) return 1; let stmtBuf = []
parsedTokens.forEach((tok, i) => {
if (shell.coreutils[cmd.toLowerCase()] !== undefined) { if (tok.match(opRegex)) {
var retval = shell.coreutils[cmd.toLowerCase()](tokens); operators.push(tok)
return retval|0; // return value of undefined will cast into 0 statements.push(stmtBuf.slice())
} stmtBuf = []
else {
// search through PATH for execution
var fileExists = false;
var searchDir = (cmd.startsWith("/")) ? [""] : ["/"+shell_pwd.join("/")].concat(_TVDOS.getPath());
var pathExt = []; // it seems Nashorn does not like 'let' too much? this line gets ignored sometimes
// fill pathExt using %PATHEXT% but also capitalise them
if (cmd.split(".")[1] === undefined)
_TVDOS.variables.PATHEXT.split(';').forEach(function(it) { pathExt.push(it); pathExt.push(it.toUpperCase()); });
else
pathExt.push(""); // final empty extension
searchLoop:
for (var i = 0; i < searchDir.length; i++) {
for (var j = 0; j < pathExt.length; j++) {
var search = searchDir[i]; if (!search.endsWith('\\')) search += '\\';
var path = trimStartRevSlash(search + cmd + pathExt[j]);
if (DEBUG_PRINT) {
serial.println("[command.js > shell.execute] file search path: "+path);
}
if (0 == filesystem.open(CURRENT_DRIVE, path, "R")) {
fileExists = true;
break searchLoop;
}
}
}
if (!fileExists) {
printerrln('Bad command or filename: "'+cmd+'"');
return 127;
} }
else { else {
var programCode = filesystem.readAll(CURRENT_DRIVE); stmtBuf.push(tok)
var extension = undefined; }
// get proper extension })
var dotSepTokens = cmd.split('.'); if (stmtBuf[0] !== undefined) {
if (dotSepTokens.length > 1) extension = dotSepTokens[dotSepTokens.length - 1].toUpperCase(); statements.push(stmtBuf.slice())
}
if ("BAT" == extension) { let retValue = undefined // return value of the previous statement
// parse and run as batch file for (let c = 0; c < statements.length; c++) {
var lines = programCode.split('\n').filter(function(it) { return it.length > 0; }); let op = operators[c]
lines.forEach(function(line) {
shell.execute(line); // TODO : if operator is not undefined, swap built-in print functions with ones that 'prints' on pipes instead of stdout
});
let tokens = statements[c]
let cmd = tokens[0];
if (cmd === undefined || cmd === '') {
retValue = 0;
continue
}
// handle Ctrl-C
if (con.hitterminate()) {
retValue = 1;
continue
}
if (shell.coreutils[cmd.toLowerCase()] !== undefined) {
var retval = shell.coreutils[cmd.toLowerCase()](tokens);
retValue = retval|0; // return value of undefined will cast into 0
continue
}
else {
// search through PATH for execution
var fileExists = false;
var searchDir = (cmd.startsWith("/")) ? [""] : ["/"+shell_pwd.join("/")].concat(_TVDOS.getPath());
var pathExt = []; // it seems Nashorn does not like 'let' too much? this line gets ignored sometimes
// fill pathExt using %PATHEXT% but also capitalise them
if (cmd.split(".")[1] === undefined)
_TVDOS.variables.PATHEXT.split(';').forEach(function(it) { pathExt.push(it); pathExt.push(it.toUpperCase()); });
else
pathExt.push(""); // final empty extension
searchLoop:
for (var i = 0; i < searchDir.length; i++) {
for (var j = 0; j < pathExt.length; j++) {
var search = searchDir[i]; if (!search.endsWith('\\')) search += '\\';
var path = trimStartRevSlash(search + cmd + pathExt[j]);
if (DEBUG_PRINT) {
serial.println("[command.js > shell.execute] file search path: "+path);
}
if (0 == filesystem.open(CURRENT_DRIVE, path, "R")) {
fileExists = true;
break searchLoop;
}
}
}
if (!fileExists) {
printerrln('Bad command or filename: "'+cmd+'"');
retValue = 127;
continue
} }
else { else {
let gotError = false; var programCode = filesystem.readAll(CURRENT_DRIVE);
var extension = undefined;
// get proper extension
var dotSepTokens = cmd.split('.');
if (dotSepTokens.length > 1) extension = dotSepTokens[dotSepTokens.length - 1].toUpperCase();
try { if ("BAT" == extension) {
errorlevel = 0; // reset the number // parse and run as batch file
var lines = programCode.split('\n').filter(function(it) { return it.length > 0 }); // this return is not shell's return!
if (_G.shellProgramTitles === undefined) _G.shellProgramTitles = []; lines.forEach(function(line) {
_G.shellProgramTitles.push(cmd.toUpperCase()) shell.execute(line);
sendLcdMsg(_G.shellProgramTitles[_G.shellProgramTitles.length - 1]); });
//serial.println(_G.shellProgramTitles);
errorlevel = execApp(programCode, tokens); // return value of undefined will cast into 0
} }
catch (e) { else {
gotError = true; let gotError = false;
serial.printerr(`[command.js] program quit with ${e}:\n${e.stack || '(stack trace unavailable)'}`); try {
errorlevel = 0; // reset the number
if (`${e}`.startsWith("InterruptedException")) if (_G.shellProgramTitles === undefined) _G.shellProgramTitles = [];
errorlevel = SIGTERM.name; _G.shellProgramTitles.push(cmd.toUpperCase())
else if (e instanceof IllegalAccessException || `${e}`.startsWith("net.torvald.tsvm.ErrorIllegalAccess")) sendLcdMsg(_G.shellProgramTitles[_G.shellProgramTitles.length - 1]);
errorlevel = SIGSEGV.name; //serial.println(_G.shellProgramTitles);
// exception catched means something went wrong, so if errorlevel is found to be zero, force set to 1. errorlevel = execApp(programCode, tokens); // return value of undefined will cast into 0
if (errorlevel === 0 || errorlevel == undefined) }
errorlevel = 1; catch (e) {
} gotError = true;
finally {
// sometimes no-error program may return nothing as the errorlevel; force set to 0 then.
if (!gotError && (errorlevel == undefined || (typeof errorlevel.trim == "function" && errorlevel.trim().length == 0) || isNaN(errorlevel)))
errorlevel = 0;
serial.printerr(`errorlevel: ${errorlevel}`); serial.printerr(`[command.js] program quit with ${e}:\n${e.stack || '(stack trace unavailable)'}`);
_G.shellProgramTitles.pop(); if (`${e}`.startsWith("InterruptedException"))
sendLcdMsg(_G.shellProgramTitles[_G.shellProgramTitles.length - 1]); errorlevel = SIGTERM.name;
//serial.println(_G.shellProgramTitles); else if (e instanceof IllegalAccessException || `${e}`.startsWith("net.torvald.tsvm.ErrorIllegalAccess"))
errorlevel = SIGSEGV.name;
return errorlevel; // exception catched means something went wrong, so if errorlevel is found to be zero, force set to 1.
if (errorlevel === 0 || errorlevel == undefined)
errorlevel = 1;
}
finally {
// sometimes no-error program may return nothing as the errorlevel; force set to 0 then.
if (!gotError && (errorlevel == undefined || (typeof errorlevel.trim == "function" && errorlevel.trim().length == 0) || isNaN(errorlevel)))
errorlevel = 0;
serial.printerr(`errorlevel: ${errorlevel}`);
_G.shellProgramTitles.pop();
sendLcdMsg(_G.shellProgramTitles[_G.shellProgramTitles.length - 1]);
//serial.println(_G.shellProgramTitles);
retValue = errorlevel;
continue
}
} }
} }
} }
return retValue
} }
}; };
shell.pipes = {}; // syntax: _G.shell.pipes[name] = contents; all pipes are named pipes just like in Windows shell.pipes = {}; // syntax: _G.shell.pipes[name] = contents; all pipes are named pipes just like in Windows