diff --git a/clite/commands.js b/clite/commands.js index 9be8f30..5ddb0ed 100644 --- a/clite/commands.js +++ b/clite/commands.js @@ -1594,8 +1594,392 @@ Options: return main(args); }); -if (window.location.protocol == 'file:') clite.commands.load('test',function(args,env,io) { + var stdio = io.include('stdio'); + var clite = io.include('clite'); + + function help() { + stdio.printf(` +test - evalutate expression +Usage: test [OPTION] [EXPRESSION] + +Options: +-? Print this help information +`); + } + + // TODO: this + // -rwxrwxrwx + function checkReadable(fuid,fgid,perms) { + if (perms[7] == 'r') + return true; + if (perms[4] == 'r' && fgid == stdlib.getgid()) + return true; + if (perms[1] == 'r' && fuid == stdlib.getuid()) + return true; + return false; + } + function checkWritable(fuid,fgid,perms) { + if (perms[8] == 'w') + return true; + if (perms[5] == 'w' && fgid == stdlib.getgid()) + return true; + if (perms[2] == 'w' && fuid == stdlib.getuid()) + return true; + return false; + } + function checkExecutable(fuid,fgid,perms) { + if (perms[9] == 'x') + return true; + if (perms[6] == 'x' && fgid == stdlib.getgid()) + return true; + if (perms[3] == 'x' && fuid == stdlib.getuid()) + return true; + return false; + } + + function main(args) { + var negate = false; + if (args.length == 1) + return 1; + if (args.length == 2) { + if (args[1] == '-?') { + help(); + return 0; + } + if (args[1].length > 0) + return 0; + return 1; + } + + if (args.length > 5) + return 1; + + var uargs = args; + uargs.shift(); + + if (args[0] == '[' && uargs[uargs.length-1] == ']') + uargs.pop(); + + if (uargs[0] == '!') { + negate = true; + uargs.shift(); + } + + if (uargs.length > 2 && uargs[0] == '(' && uargs[uargs.length-1] == ')') { + uargs.shift(); + uargs.pop(); + if (uargs[0] == '!') { + negate = !negate; + uargs.shift(); + } + } + + if (uargs.length == 1) { + if (uargs[0].length > 0) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + } + + // -primary_operator primary_operand + if (uargs.length == 2) { + switch (uargs[0]) { + case '-b': // test for a block file (don't exist, always false) + if (negate) + return 0; + return 1; + break; + case '-c': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || st.type != stdio.types.FT_DEV) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-d': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || st.type != stdio.types.FT_DIR) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-e': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-f': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || st.type == stdio.types.FT_DIR || st.type == stdio.types.FT_DEV || st.type == stdio.types.FT_LINK) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-g': // test for set-groud-id (doesn't exist, always false) + if (negate) + return 0; + return 1; + break; + case '-h': + case '-L': + var p = clite.resolvePath(uargs[1]); + var st = stdio.lstat(p); + if (!st || st.type != stdio.types.FT_LINK) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-n': + if (uargs[1].length == 0) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-p': // test for FIFO/pipe (doesn't exist, always false) + if (negate) + return 0; + return 1; + break; + case '-r': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || !checkReadable(st.st_uid,st.st_gid,st.perms)) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-S': // test for socket (doesn't exist, always false) + if (negate) + return 0; + return 1; + break; + case '-s': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || st.st_size == 0) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-t': + if (uargs[1] == '0') { // stdin + if (!stdio.isatty(io.stdin)) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + } + if (uargs[1] == '1') { // stdout + if (!stdio.isatty(io.stdin)) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + } + if (uargs[1] == '2') { // stderr + if (!stdio.isatty(io.stdin)) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '-u': // test for set-user-id (doesn't exist, always false) + if (negate) + return 0; + return 1; + break; + case '-w': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || !checkWritable(st.st_uid,st.st_gid,st.perms)) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-x': + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || !checkExecutable(st.st_uid,st.st_gid,st.perms)) { + if (negate) + return 0; + return 1; + } + if (negate) + return 1; + return 0; + break; + case '-z': + if (uargs[1].length == 0) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + default: + return 2; + } + } + + // primary_operand -primary_operator primary_operand + // primary_operand primary_operator primary_operand + if (uargs.length == 3) { + switch (uargs[1]) { + case '=': + if (uargs[0] == uargs[2]) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '!=': + if (uargs[0] != uargs[2]) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '-eq': + if (parseInt(uargs[0]) == parseInt(uargs[2])) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '-ne': + if (parseInt(uargs[0]) != parseInt(uargs[2])) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '-gt': + if (parseInt(uargs[0]) > parseInt(uargs[2])) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '-ge': + if (parseInt(uargs[0]) >= parseInt(uargs[2])) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '-lt': + if (parseInt(uargs[0]) < parseInt(uargs[2])) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + case '-le': + if (parseInt(uargs[0]) <= parseInt(uargs[2])) { + if (negate) + return 1; + return 0; + } + if (negate) + return 0; + return 1; + break; + default: + return 2; + } + } + + return 1; + } + + + return main(args); +}); + +if (window.location.protocol == 'file:') +clite.commands.load('exp',function(args,env,io) { var stdio = io.include('stdio'); var stdlib = io.include('stdlib'); var time = io.include('time');